Core Concepts
Shader lifecycle
ShaderPad has the following render lifecycle:
- Construct a shader using
new ShaderPad() - Initialize custom uniforms or textures using
initializeUniform()andinitializeTexture() - Render with
play(),step(), ordraw() - Clean up with
destroy()
You can go over the details of each method in the Methods API reference. Below is a quick overview, including when you may want to use each method.
Constructor
const shader = new ShaderPad(fragmentShaderSrc, { canvas })
Rendering Methods
Quick Reference
- Use
play()for animation loops - Use
step()for manual time/frame advancement - Use
draw()when time, frame, and history should remain unchanged
play(onBeforeStep?)
play() starts the animation loop. u_time and u_frame uniforms are updated automatically, and history is kept up to date.
shader.play((time, frame) => {
shader.updateUniforms({ u_speed: Math.sin(time) })
})
Use it when:
- You want to animate the shader over time
- You don’t need manual control over timing
- You’re rendering a single shader or a straightforward rendering pipeline
step(options?)
step() advances exactly one frame, and renders without triggering the animation loop. u_time and u_frame uniforms are updated automatically, and history is kept up to date.
shader.step({ skipHistoryWrite: true })
Use it when:
- You want deterministic manual control over the animation frame
- Another loop owns timing
- You are building a chained or offscreen pipeline
draw(options?)
draw() renders without updating u_time, u_frame, or history.
shader.draw({ skipClear: true })
Use it when:
- The current uniforms already represent the exact state you want
- The output should not count as a new animation step
Pause, Reset, Destroy
pause()stops the animation loop started byplay()resetFrame()resets the clock and frame counterreset()resets the clock and frame counter, and also clears history buffersdestroy()releases WebGL resources and event listeners