-
-
Notifications
You must be signed in to change notification settings - Fork 237
Custom Passes
There are two options for creating custom passes. You can either rely on the general-purpose ShaderPass or extend Pass.
The ShaderPass expects an instance of ShaderMaterial as its first argument. The second argument specifies the name of the texture sampler uniform of the shader you provide. This name defaults to tDiffuse and the ShaderPass binds the read buffer to this uniform.
In order to render a simple ShaderMaterial, you have to pass your shader object (uniforms, defines, fragment and vertex shader code) to ShaderMaterial and then pass that material instance to ShaderPass and adjust the name of the input texture if necessary.
import { ShaderMaterial } from "three";
import { ShaderPass } from "postprocessing";
const myShaderMaterial = new ShaderMaterial({
defines: { ... },
uniforms: { ... }
vertexShader: `...`,
fragmentShader: `...`
});
const myShaderPass = new ShaderPass(myShaderMaterial, "myInputSampler");An example that uses the Kaleidoscope Shader from the three.js examples together with the ShaderPass can be found here.
More complex passes sometimes use more than one fullscreen Material or require additional programming. By extending the Pass class you can decide what happens with your pass during resizing, initialization and rendering.
The minimum requirement to create a custom pass is to override the render method. You may also need to set the needsSwap flag to false if your pass never renders to the outputBuffer. If you're creating a fullscreen effect, you'll need to assign a fullscreen Material by using the setFullscreenMaterial(Material) method. You may also create custom render targets in your pass. The EffectComposer destroys them automatically in case it's being destroyed itself.
As stated in the docs, the render method gains access to an inputBuffer as well as an outputBuffer. Reading from and writing to the same render target should be avoided. Therefore, two seperate yet identical buffers are used. The EffectComposer expects your pass to render its result to the outputBuffer. After your pass has finished rendering, the outputBuffer will be swapped with the inputBuffer so that the next queued pass can find the result in the inputBuffer. If your pass doesn't write to the outputBuffer, you need to set needsSwap to false. Otherwise, the image in the input buffer will be lost.
Note that Passes don't have to use the buffers that are provided in the render method. Writing self-contained render-to-texture passes is also a feasible option.
For reference, take a look at the existing passes.