9
$\begingroup$

The function SurfaceAppearance provides a number of preset shaders for use in Graphics and Graphics3D, however it is undocumented in Mathematica 14.0. Apparently, these shaders are written in GLSL.

I frequently use OpenCLLink / CUDALink for specialized image effects, and the ability to write GLSL shaders would be incredibly useful.

$\endgroup$

1 Answer 1

13
$\begingroup$

As it turns out, it is entirely possible in 14.0 to write your own custom shaders as this video by Yuzhu Lu demonstrates.

In addition, a number of custom shaders are available to read in:

Mathematica\14.0\SystemFiles\FrontEnd\TextResources\CustomizedShaders.tr

Here is an example where I use a fragment shader to warp an image inside a manipulate:

customShader.frag

#version 330
uniform sampler2D theTexture;
uniform float time;
in vec2 v_texcoord;
out vec4 glFragColor;

void main()
{
    vec2 newcoord = vec2(
        v_texcoord.x + 0.05f*cos(time + 10 * v_texcoord.y),
        v_texcoord.y + 0.05f*sin(time + 10 * v_texcoord.x)
    );

    vec4 texColor = texture(theTexture, newcoord);
    glFragColor = texColor;
}

customShader.vert

#version 330
uniform mat4 mvp_matrix;
in vec4 a_position;
in vec2 a_texcoord;
out vec2 v_texcoord;

void main()
{
    gl_Position = mvp_matrix * a_position;
    v_texcoord = a_texcoord;
}
Remove["Global`*"];
fragmentShader = Import["customShader.frag", "Text"];
vertexShader = Import["customShader.vert", "Text"];
customGLSLShader = <|
   "Name" -> "CustomShader",
   "Attributes" -> <|"a_position" -> "ATTRIB_VERTEX",
     "a_texcoord" -> "ATTRIB_TEXTURECOORD"|>, "Parameters" ->
    <|"Matrix" -> {"mvp_matrix", "TRANSFORMMATRIX", "MATRIX4"}, 
     "Time" -> {"time", 0.0, "NUMBER"}|>,
   "ShaderPrograms" -> <|"GLFragmentProgram" -> fragmentShader,
     "GLVertexProgram" -> vertexShader|>
   |>;
FE`Evaluate[
  Evaluate[
   FEPrivate`AddSurfaceAppearanceDefinition[customGLSLShader]]];
(* Check that it was loaded *)
FE`Evaluate[FEPrivate`ListSurfaceAppearanceDefinitions["CustomShader"]]

tex = ExampleData[{"TestImage", "Mandrill"}];
Manipulate[
 Graphics[{Texture[tex], 
   SurfaceAppearance["CustomShader", "Time" -> t], 
   Rectangle[{0, 0}, {1, 1}]}]
 , {t, 0, 20}]

mandrill wobbly glsl shader effect

$\endgroup$
3
  • 1
    $\begingroup$ Face massage. :-) $\endgroup$ Commented Apr 28 at 13:17
  • $\begingroup$ Change the Graphics to Graphics3D and replace Rectangle[...] with Sphere[] for even more hilarious results. $\endgroup$
    – flinty
    Commented Apr 28 at 13:21
  • $\begingroup$ Unfortunately I do not have version14. $\endgroup$ Commented Apr 28 at 13:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.