11
$\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

16
$\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$
6
  • 1
    $\begingroup$ Face massage. :-) $\endgroup$ Commented Apr 28, 2024 at 13:17
  • $\begingroup$ Change the Graphics to Graphics3D and replace Rectangle[...] with Sphere[] for even more hilarious results. $\endgroup$ Commented Apr 28, 2024 at 13:21
  • $\begingroup$ Unfortunately I do not have version14. $\endgroup$ Commented Apr 28, 2024 at 13:25
  • $\begingroup$ Does this still work with version 14.2.0? I tried it on wolfram cloud but the output is just $Failed. $\endgroup$ Commented Feb 27 at 21:39
  • $\begingroup$ @azerbajdzan it's still working for me but then I'm not using cloud. $\endgroup$ Commented Mar 2 at 13:50

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.