Time for Action: Post-Process Effects

Let's see a few post-processing effects in action:

  1. Open the ch10_01_post-process.html file in your browser, like so:

  1. The controls dropdown allows you to switch between different sample effects. Try them out to get a feel for the effects they have on the scene. We've already looked at grayscale, so let's examine the rest of the filters individually.
  2. The invert effect, similar to grayscale in that it only modifies the color output, inverts each color channel:
#version 300 es
precision mediump float;

uniform sampler2D uSampler;

in vec2 vTextureCoords;

out vec4 fragColor;

void main(void) {
vec4 frameColor = texture(uSampler, vTextureCoords);
fragColor = vec4(vec3(1.0) - frameColor.rgb, frameColor.a);
}

  1. The wavy effect manipulates the texture coordinates to make the scene swirl and sway. In this effect, we also provide the current time to allow the distortion to change as time progresses:
#version 300 es
precision mediump float;

const float speed = 15.0;
const float magnitude = 0.015;

uniform sampler2D uSampler;
uniform float uTime;

in vec2 vTextureCoords;

out vec4 fragColor;

void main(void) {
vec2 wavyCoord;
wavyCoord.s = vTextureCoords.s + sin(uTime + vTextureCoords.t *
speed) * magnitude;
wavyCoord.t = vTextureCoords.t + cos(uTime + vTextureCoords.s *
speed) * magnitude;
fragColor = texture(uSampler, wavyCoord);
}

  1. The blur effect samples several pixels around the current pixel and uses a weighted blend to produce a fragment output that is the average of its neighbors. This gives a blurry feel to the scene. A new uniform, uInverseTextureSize, provides values that are 1 over the width and height of the viewport. We use these values to accurately target individual pixels within the texture. For example, vTextureCoords.x + 2 * uInverseTextureSize.x will be exactly 2 pixels to the left of the original texture coordinate:
#version 300 es
precision mediump float;

uniform sampler2D uSampler;
uniform vec2 uInverseTextureSize;

in vec2 vTextureCoords;

out vec4 fragColor;

vec4 offsetLookup(float xOff, float yOff) {
return texture(
uSampler,
vec2(
vTextureCoords.x + xOff * uInverseTextureSize.x,
vTextureCoords.y + yOff * uInverseTextureSize.y
)
);
}

void main(void) {
vec4 frameColor = offsetLookup(-4.0, 0.0) * 0.05;
frameColor += offsetLookup(-3.0, 0.0) * 0.09;
frameColor += offsetLookup(-2.0, 0.0) * 0.12;
frameColor += offsetLookup(-1.0, 0.0) * 0.15;
frameColor += offsetLookup(0.0, 0.0) * 0.16;
frameColor += offsetLookup(1.0, 0.0) * 0.15;
frameColor += offsetLookup(2.0, 0.0) * 0.12;
frameColor += offsetLookup(3.0, 0.0) * 0.09;
frameColor += offsetLookup(4.0, 0.0) * 0.05;
fragColor = frameColor;
}

  1. Our final example is a film grain effect. This uses a noisy texture to create a grainy scene, which simulates the use of an old camera. This example is significant because it demonstrates the use of a second texture besides the framebuffer when rendering:
#version 300 es
precision mediump float;

const float grainIntensity = 0.1;
const float scrollSpeed = 4000.0;

uniform sampler2D uSampler;
uniform sampler2D uNoiseSampler;
uniform vec2 uInverseTextureSize;
uniform float uTime;

in vec2 vTextureCoords;

out vec4 fragColor;

void main(void) {
vec4 frameColor = texture(uSampler, vTextureCoords);
vec4 grain = texture(
uNoiseSampler,
vTextureCoords * 2.0 + uTime * scrollSpeed *
uInverseTextureSize
);
fragColor = frameColor - (grain * grainIntensity);
}

What just happened?

All of these effects are achieved by manipulating the rendered image before it is outputted to the screen. Since the amount of geometry processed for these effects is small, they are efficient, regardless of the scene's complexity. That being said, performance may be affected as the size of the canvas or the complexity of the post-process shader increases.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.30.162