Shaders
Shaders are small programs that we send to a GPU to perform computations. Shaders are extensively used in Smelter, in fact all built-in transformations rely on them.
General concepts
The Smelter utilizes two types of shaders: vertex shaders and fragment shaders.
Vertex shaders
Vertex shaders take data from a single vertex as input and manipulate it to create the desired output shape.
In vertex shaders, videos are represented as two triangles aligned in the following configuration:
The rectangle created by these triangles spans the entire clip space ([-1, 1] x [-1, 1]
). Each video input receives its own separate rectangle.
plane_id
in base_params
push_constant
represents number of currently rendered planes (textures). If there are no input textures, plane_id
is equal to -1
and a single rectangle is passed to the shader. It is only useful for shaders that generate something in the fragment shader.
Since Smelter doesn’t handle complex geometry, and layouts typically manage positioning, resizing, and cropping, we don’t expect the users to create complex vertex shaders very often.
The following vertex shader should cover most needs for transformations that process a single video in the fragment shader:
Fragment shaders
Fragment shaders focus on processing pixel data to apply visual effects. A single shader instance, responsible for calculating the color of a pixel, is started for every pixel of the output texture.
The output of a fragment shader must be a vector with four elements, each being a floating-point number (f32
) between 0.0 and 1.0. These four numbers represent the red, green, blue, and alpha (transparency) values of a pixel.
The children of the Smelter’s Shader
component are available as textures. You can sample them using the builtin textureSample
function. To customize texture sampling, use the sampler_
param.
For example see this simple fragment shader, which applies the negative effect:
Synthax
Since Smelter is implemented using wgpu, the shaders have to be written in WGSL (WebGPU Shading Language). Shaders also have to fulfill some custom requirements to be used by the Smelter. We will detail all necessary conditions in the following sections.
Header
Every user-provided shader should include the code below.
Custom parameters
You can define a custom WGSL struct and bind a value of this type:
You need to provide this struct when creating a node using the shader_params
field of the shader node struct.
Entry points
Vertex shader
A vertex shader entrypoint must match the following signature:
Where A
can be any user-defined struct suitable for a vertex shader output.
Fragment shader
A fragment shader entrypoint must match the following signature:
Where A
is the output type of the vertex shader.