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}]
