-
-
Notifications
You must be signed in to change notification settings - Fork 213
Custom Effects
Effects are lightweight fullscreen passes. They can be combined using the EffectPass.
Just like passes, effects may perform initialization tasks, react to render size changes and execute supporting render operations if needed but they don't have access to an output buffer and are not supposed to render to screen by themselves.
Code Example
uniform vec3 weights;
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor) {
outputColor = vec4(inputColor.rgb * weights, inputColor.a);
}
import { Uniform, Vector3 } from "three";
import { Effect } from "postprocessing";
// Using rollup-plugin-string to import text files.
import fragment from "./shader.frag";
export class CustomEffect extends Effect {
constructor() {
super("CustomEffect", fragment, {
uniforms: new Map([
["weights", new Uniform(new Vector3())]
])
});
}
}
Every effect must provide a fragment shader that implements at least one of these two functions:
void mainImage(const in vec4 inputColor, const in vec2 uv, out vec4 outputColor);
void mainUv(inout vec2 uv);
If the effect relies on depth, it can choose to implement a slightly different mainImage
function:
void mainImage(const in vec4 inputColor, const in vec2 uv,
const in float depth, out vec4 outputColor);
Effects may also provide a vertex shader that implements the following function:
void mainSupport();
However, most effects do not need a vertex shader.
Some effects perform special operations inside the fragment shader or require additional resources. There are currently two EffectAttributes available: CONVOLUTION
and DEPTH
. Most effects do not need to specify any attributes.
Attributes can be concatenated using the bitwise OR operator
class MyEffect extends Effect {
constructor() {
super(name, fragmentShader, {
attributes: EffectAttribute.CONVOLUTION | EffectAttribute.DEPTH
});
}
}
Effects that fetch additional samples from the input buffer inside the fragment shader must specify the CONVOLUTION
attribute. To prevent bad results, it is not allowed to have more than one effect with this attribute per EffectPass
. Convolution effects are also incompatible with effects that implement the mainUv
function. The EffectPass
will warn you when it encounters incompatible effects.
The DEPTH
attribute must be specified by effects that require a depth texture. When the EffectPass
encounters an effect with this attribute, it will request a depth texture from the EffectComposer
. If your fragment shader implements the depth variant of the mainImage
function, depth will be read automatically and the value will be provided to your mainImage
function. In case you wish to sample depth at another coordinate, use the predefined float readDepth(const in vec2 uv)
function.
All shaders have access to the following uniforms:
uniform vec2 resolution;
uniform vec2 texelSize;
uniform float cameraNear;
uniform float cameraFar;
uniform float aspect;
uniform float time;
The fragment shader has access to the following additional uniforms:
uniform sampler2D inputBuffer;
uniform sampler2D depthBuffer;
Effects may define custom uniforms, varyings, functions and preprocessor macros as usual, but should not define global variables or constants.
If the camera of the associated EffectPass
is a PerspectiveCamera
, the macro
PERSPECTIVE_CAMERA
will be defined. Furthermore, the shader chunks
common
and packing
are included in the fragment shader.