A zoom blur postprocess shader with user-defined strength and center.
Can produce nausea when animated.
Center is normalized screen coordinates (-0.5 - 0.5)
Strength can be negative.
The cSamples constant in the shader code controls the amount of sampling.
#include "Uniforms.glsl"
#include "Samplers.glsl"
#include "Transform.glsl"
#include "ScreenPos.glsl"
#line 5
varying vec2 vScreenPos;
void VS() {
mat4 modelMatrix = iModelMatrix;
vec3 worldPos = GetWorldPos(modelMatrix);
gl_Position = GetClipPos(worldPos);
vScreenPos = GetScreenPosPreDiv(gl_Position);
}
#if defined(COMPILEPS)
uniform vec2 cZoomBlurCenter;
uniform float cZoomBlurStrength;
const float cSamples = 40.0;
float RandomOffset(vec3 scale, float seed) {
return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);
}
#endif
void PS() {
vec4 color = vec4(0.0);
float total = 0.0;
vec2 toCenter = cZoomBlurCenter - vScreenPos;
float offset = RandomOffset(vec3(12.9898, 78.233, 151.7182), 0.0);
for(float t = 0.0; t <= cSamples; t++) {
float percent = (t + offset) / cSamples;
float weight = 4.0 * (percent - percent * percent);
vec4 sample = texture2D(sDiffMap, vScreenPos + toCenter * percent * cZoomBlurStrength);
sample.rgb *= sample.a;
color += sample * weight;
total += weight;
}
gl_FragColor = color / total;
gl_FragColor.rgb /= gl_FragColor.a + 0.00001;
}
<renderpath>
<command type="quad" enabled="true" tag="ZoomBlur" vs="ZoomBlur" ps="ZoomBlur" output="viewport">
<texture unit="diffuse" name="viewport" />
<parameter name="ZoomBlurStrength" value="0.15" />
<parameter name="ZoomBlurCenter" value="0.5 0.5" />
</command>
</renderpath>