Archive 17/01/2023.

Zoom Blur postprocess shader (GLSL)

jmiller

A zoom blur postprocess shader with user-defined strength and center.

Can produce nausea when animated. :smiley:
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>
1vanK

Nice!

Bananaft

Now feed Z-Buffer as Strength and camera velocity projection as vector, and you will get linear motion blur.

jmiller

Z-buffer use would be a definite improvement.
The screenshot app uses velocity as strength and computes center from direction.

Even more interesting, per-object motion blur - john-chapman-graphics.blogspot.c … -blur.html

Bananaft

[quote=“carnalis”]Z-buffer use would be a definite improvement.
The screenshot app uses velocity as strength and computes center from direction.

Even more interesting, per-object motion blur - john-chapman-graphics.blogspot.c … -blur.html[/quote]

Oh, there actually this project from a year ago: topic433.html

Also, in my opinion, there are very few games, that really need per object motion blur. For racing/flying game, for example, you can just mask out your vehicle and blur linearly the rest of the scene.

rasteron

Cool carnalis. Thanks for sharing!