Built In Shader Templates
To reduce boilerplate code, pySSV includes a selection of shader templates which generate any platform/compiler specific code needed for the shader. These templates should handle most needs for scientific visualisation, but if you want to write your own shader templates to add new functionality or simplify your workflow refer to Writing Shader Templates for details on writing shader templates.
Built In Shader Uniforms
All built in shader templates include the global_uniforms.glsl
library which defines a variety of useful shader
uniforms which are set automatically by pySSV. It also includes any automatically defined uniforms (such as textures
and render buffer textures).
-
float uTime
The current time since the shader was started in seconds.
-
int uFrame
The current frame number of the shader.
-
vec4 uResolution
The resolution of the render buffer this shader is rendering to.
-
vec2 uMouse
The current mouse position in pixel coordinates.
-
bool uMouseDown
Whether a mouse button is pressed.
-
mat4x4 uViewMat
The view matrix for the
SSVCanvas
’s main camera.
-
mat4x4 uProjMat
The projection matrix for the
SSVCanvas
’s main camera.
-
vec3 uViewDir
The view direction for the
SSVCanvas
’s main camera.
If SHADERTOY_COMPAT
is #define
before importing the global_uniforms.glsl
file (which is the case in the
Shadertoy template) then the following uniforms are also defined as aliases of the above uniforms.
-
iTime
= uTime
-
iFrame
= uFrame
-
iResolution
= uResolution
-
iMouse
= vec4(uMouse, uMouse*(uMouseDown?1.:-1.))
This doesn’t quite match the implementation of shadertoy, but it’s close enough for many shaders.
-
_DYNAMIC_UNIFORMS
This macro is defined automatically by pySSV and expands to include the declarations of all automatically declared uniforms, such as user-defined textures and render buffer textures.
Pixel Shader Template
#pragma SSV pixel
This template exposes a single entrypoint to a pixel shader.
Entrypoint Signature
-
vec4 entrypoint(vec2 fragPos)
- Parameters:
fragPos – the position of the pixel being processed by this shader invocation in pixel coordinates.
- Returns:
the pixel’s colour.
Template Arguments
- entrypoint
positional
type:
str
The name of the entrypoint function to pixel the shader.
- --z_value
default:
0.999
type:
float
The constant value to write into the depth buffer. 0 is close to the camera, 1 is far away.
Example
#pragma SSV pixel frag
// The entrypoint to the fragment shader
vec4 frag(vec2 fragPos)
{
vec2 uv = fragPos.xy / uResolution.xy;
return mix(uv.xyx, uv.yyx, sin(uTime)*0.5+0.5);
}
Vertex Shader Template
#pragma SSV vert
This template exposes a single entrypoint to a vertex shader.
Entrypoint Signature
-
VertexOutput mainVert()
- Returns:
a
VertexOutput
struct containing the transformed vertex data.
The shader is expected to take input from the following vertex attributes:
-
vec4 in_vert
-
vec4 in_color
Template Arguments
- entrypoint
positional
type:
str
The name of the entrypoint function to vertex the shader.
Example
#pragma SSV vert mainVert
VertexOutput mainVert()
{
VertexOutput o;
vec4 pos = vec4(in_vert, 1., 1.0);
pos = uViewMat * pos;
pos = uProjMat * pos;
o.position = pos;
o.color = vec4(in_color, 1.);
return o;
}
ShaderToy Template
#pragma SSV shadertoy
This template exposes a single entrypoint to a pixel shader. It’s designed to mimic the API of ShaderToy
Entrypoint Signature
-
void mainImage(vec4 fragColor, vec2 fragCoord)
- Parameters:
fragColor (out) – the pixel’s final colour.
fragPos – the position of the pixel being processed by this shader invocation in pixel coordinates.
Template Arguments
None
Example
#pragma SSV shadertoy
void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
// Normalized pixel coordinates (from 0 to 1)
vec2 uv = fragCoord/iResolution.yy;
// Colour changing over time
vec3 col = sin(uv.xyx + iTime * vec3(3, 4, 5)) * 0.5 + 0.5;
// Output to screen
fragColor = vec4(vec3(col), 1.);
}
Vertex/Pixel Shader Template
#pragma SSV vert_pixel
This template exposes an entrypoint to a vertex shader and an entrypoint to a pixel shader.
Entrypoint Signature
Vertex Stage
-
void mainVert()
- Returns:
a
VertexOutput
struct containing the transformed vertex data.
The shader is expected to take input from the following vertex attributes:
-
vec4 in_vert
-
vec4 in_color
The shader is expected to take write to the following vertex attributes:
-
vec3 color
-
vec4 gl_Position
Pixel Stage
-
vec4 mainPixel(vec3 position)
- Parameters:
position – the position written to gl_Position by the vertex shader.
- Returns:
the final colour of the fragment.
The shader is expected to take input from the following interpolated vertex attributes:
-
vec4 color
Template Arguments
- entrypoint_vert
positional
type:
str
The name of the entrypoint function to vertex the shader.
- entrypoint_pixel
positional
type:
str
The name of the entrypoint function to pixel the shader.
Example
#pragma SSV vert_pixel vert pixel
#ifdef SHADER_STAGE_VERTEX
// Additional vertex->fragment interpolators can be defined as follows
layout(location = 3) out vec2 uv;
void vert() {
uv = in_vert.xy;
gl_Position = vec4(in_vert.xyz, 1.);
gl_Position = uProjMat * uViewMat * gl_Position;
}
#endif // SHADER_STAGE_VERTEX
#ifdef SHADER_STAGE_FRAGMENT
// Make sure to also define any custom interpolators in the fragment stage
layout(location = 3) in vec2 uv;
vec4 pixel(vec3 pos) {
vec3 col = vec3(0.);
col.rg = uv;
col.b = pos.z;
return col;
}
#endif //SHADER_STAGE_FRAGMENT
Signed Distance Field Template
#pragma SSV sdf
This template exposes a single entrypoint to a pixel shader. It’s designed to mimic the API of ShaderToy
Entrypoint Signature
-
float map(vec3 pos)
- Parameters:
pos – the position to sample sample the signed distance field at.
- Returns:
the signed distance to the surface.
Template Arguments
- entrypoint
positional
type:
str
The name of the sdf function in the shader.
- --camera_mode
choices:
INTERACTIVE, AUTO
default:
AUTO
How the camera should behave.
INTERACTIVE
, uses the canvas’ camera.AUTO
, automatically rotates around the scene using the--camera_distance
and--rotate_speed
variables.
- --camera_distance
default:
10.0
type:
float
The distance of the camera from the centre of the distance field.
- --rotate_speed
default:
0.1
type:
float
The orbit speed of the camera around the SDF, in radians/second.
- --raymarch_steps
default:
128
type:
int
The number of raymarching steps to use when rendering, turn this up if the edges of surfaces look soft.
- --raymarch_distance
default:
32.0
type:
float
The maximum distance to raymarch.
- --light_dir
default:
normalize(vec3(0.5, 0.5, -0.9))
type:
vec3
The maximum distance to raymarch.
- --render_mode
choices:
SOLID, DEPTH, XRAY, ISOLINES
default:
SOLID
How the distance field should be rendered. Check the documentation for more information about each mode.
Example
#pragma SSV sdf sdf_main --camera_distance 2. --rotate_speed 1.5 --render_mode SOLID
// SDF taken from: https://iquilezles.org/articles/distfunctions/
float sdCappedTorus(vec3 p, vec2 sc, float ra, float rb) {
p.x = abs(p.x);
float k = (sc.y*p.x>sc.x*p.y) ? dot(p.xy,sc) : length(p.xy);
return sqrt( dot(p,p) + ra*ra - 2.0*ra*k ) - rb;
}
float sdf_main(vec3 p) {
float t = 2.*(sin(uTime)*0.5+0.5)+0.2;
return sdCappedTorus(p, vec2(sin(t), cos(t)), 0.5, 0.2);
}
Point Cloud Template
#pragma SSV point_cloud
This template exposes a single entrypoint to a vertex shader. It treats input vertices as points and uses a geometry shader to turn each vertex into a camera-facing sprite.
Entrypoint Signature
-
VertexOutput vert()
- Returns:
a VertexOutput struct containing the transformed vertex.
-
struct VertexOutput
-
vec4 position
-
float size
The size of the sprite representing the point.
-
vec4 color
-
vec4 position
The shader is expected to take input from the following vertex attributes:
-
vec4 in_vert
-
vec4 in_color
Template Arguments
None
Example
#pragma SSV point_cloud mainPoint
VertexOutput mainPoint()
{
VertexOutput o;
vec4 pos = vec4(in_vert, 1.0);
pos = uViewMat * pos;
pos = uProjMat * pos;
o.position = pos;
o.color = vec4(in_color, 1.);
o.size = 30.0/uResolution.x;
return o;
}
Render Test
#pragma SSV render_test
This template generates a simple pixel shader which displays a colour changing gradient. Useful as a shorthand to make a quick shader to test the rendering system.
Entrypoint Signature
None
Template Arguments
None
Example
#pragma SSV render_test
Geometry Shader Template
#pragma SSV geometry
This template exposes an entrypoint to a vertex shader and an entrypoint to a geometry shader. It treats input vertices as points which are processed by the user defined vertex shader and can then be turned into triangle primitives by the user defined geometry shader.
Entrypoint Signature
Vertex Stage
-
VertexOutput vert()
Where
VertexOutput
is substituted for the value of--vertex_output_struct
.
- returns:
a <VertexOutput> struct containing the transformed vertex.
If the --vertex_output_struct
argument isn’t set then the <VertexOutput>
struct is as follows:
-
struct DefaultVertexOutput
-
vec4 position
-
vec4 color
-
float size
The size of the sprite representing the point.
-
vec4 position
If the --custom_vertex_input
flag isn’t specified then the vertex shader is expected to take input from the
following vertex attributes:
-
vec4 in_vert
-
vec4 in_color
Geometry Stage
-
void geo(VertexOutput i)
- Parameters:
i – the struct containing the processed vertex data
The geometry function is expected to write to these output variables before each call to EmitVertex()
:
-
vec4 gl_Position
The transformed (clip space) position of the vertex to emit.
-
vec4 out_color
The final colour of the vertex to be emitted.
The geometry function is responsible for calling EmitVertex()
and EndPrimitive()
as needed and must not emit
more vertices in a single invocation than what is specified in --geo_max_vertices
(default=4
).
Template Arguments
- entrypoint_vert
positional
type:
str
The name of the entrypoint function to vertex the shader.
- entrypoint_geo
positional
type:
str
The name of the entrypoint function to geometry the shader.
- --vertex_output_struct
default:
DefaultVertexOutput
type:
float
The name of the struct containing data to be transferred from the vertex stage to the geometry stage.
- --geo_max_vertices
default:
4
type:
const int
The maximum number of vertices which can be output be the geometry stage per input vertex. Must be a constant.
- --custom_vertex_input
type:
flag
When this flag is passed, the default vertex input attributes are not created and must be declared by the user.
Example
#pragma SSV geometry mainPoint mainGeo
#ifdef SHADER_STAGE_VERTEX
DefaultVertexOutput mainPoint()
{
DefaultVertexOutput o;
// Transform the points using the camera matrices
vec4 pos = vec4(in_vert, 1.0);
pos = uViewMat * pos;
pos = uProjMat * pos;
o.position = pos;
o.color = vec4(in_color, 1.);
o.size = 10.0/uResolution.x;
return o;
}
#endif // SHADER_STAGE_VERTEX
#ifdef SHADER_STAGE_GEOMETRY
void mainGeo(DefaultVertexOutput i) {
// Generate a quad for each point
vec4 position = i.position;
float size = i.size;
out_color = i.color;
vec4 aspect_ratio = vec4(1., uResolution.x/uResolution.y, 1., 1.);
gl_Position = position + size * vec4(-1., -1., 0.0, 0.0) * aspect_ratio;
EmitVertex();
gl_Position = position + size * vec4(1., -1., 0.0, 0.0) * aspect_ratio;
EmitVertex();
gl_Position = position + size * vec4(-1., 1., 0.0, 0.0) * aspect_ratio;
EmitVertex();
gl_Position = position + size * vec4(1., 1., 0.0, 0.0) * aspect_ratio;
EmitVertex();
EndPrimitive();
}
#endif // SHADER_STAGE_GEOMETRY