java - Desenfoque de movimiento 2D y desenfoque gaussiano usando puramente GLSL
libgdx shader (1)
Deseo implementar desenfoque de movimiento o tal vez desenfoque gaussiano usando puramente GLSL.
He creado algunos sombreadores básicos y ya tengo algunas ideas en mente.
Mis sombreadores:
Vertex shader:
attribute vec4 a_color;
attribute vec2 a_position;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec4 v_color;
varying vec2 v_texCoord0;
void main() {
v_color = a_color;
v_texCoord0 = a_texCoord0;
gl_Position = u_projTrans * vec4(a_position, 0.0f, 1.0f);
}
Fragmento shader:
varying vec4 v_color;
varying vec2 v_texCoord0;
uniform vec2 screenSize;
uniform sampler2D u_texture;
uniform vec4 v_time;
const float RADIUS = 0.75;
const float SOFTNESS = 0.6;
void main() {
vec4 texColor = texture2D(u_texture, v_texCoord0);
vec4 timedColor = (v_color + v_time);
vec2 position = (gl_FragCoord.xy / screenSize.xy) - vec2(0.5);
float len = length(position);
float vignette = smoothstep(RADIUS, RADIUS-SOFTNESS, len);
texColor.rgb = mix(texColor.rgb, texColor.rgb * vignette, 0.5);
gl_FragColor = vec4(texColor.rgb * timedColor.rgb, texColor.a);
}
¿Es una buena idea crear desenfoque usando solo GLSL? y ¿alguien tiene alguna idea sobre cómo hacerlo?
También puedo responder mi propia pregunta ya que tengo algunas ideas en mente.
Voy a responder mi propia pregunta.
Eventualmente, cambié solo el fragmento shader:
varying vec4 vColor;
varying vec2 vTexCoord;
uniform vec2 screenSize;
uniform sampler2D u_texture;
uniform vec4 v_time;
const float RADIUS = 0.75;
const float SOFTNESS = 0.6;
const float blurSize = 1.0/1000.0;
void main() {
vec4 texColor = vec4(0.0); // texture2D(u_texture, vTexCoord)
texColor += texture2D(u_texture, vTexCoord - 4.0*blurSize) * 0.05;
texColor += texture2D(u_texture, vTexCoord - 3.0*blurSize) * 0.09;
texColor += texture2D(u_texture, vTexCoord - 2.0*blurSize) * 0.12;
texColor += texture2D(u_texture, vTexCoord - blurSize) * 0.15;
texColor += texture2D(u_texture, vTexCoord) * 0.16;
texColor += texture2D(u_texture, vTexCoord + blurSize) * 0.15;
texColor += texture2D(u_texture, vTexCoord + 2.0*blurSize) * 0.12;
texColor += texture2D(u_texture, vTexCoord + 3.0*blurSize) * 0.09;
texColor += texture2D(u_texture, vTexCoord + 4.0*blurSize) * 0.05;
vec4 timedColor = (vColor + v_time);
vec2 position = (gl_FragCoord.xy / screenSize.xy) - vec2(0.5);
float len = length(position);
float vignette = smoothstep(RADIUS, RADIUS-SOFTNESS, len);
texColor.rgb = mix(texColor.rgb, texColor.rgb * vignette, 0.5);
gl_FragColor = vec4(texColor.rgb * timedColor.rgb, texColor.a);
}
El efecto de desenfoque real está escrito aquí:
vec4 texColor = vec4(0.0); // texture2D(u_texture, vTexCoord)
texColor += texture2D(u_texture, vTexCoord - 4.0*blurSize) * 0.05;
texColor += texture2D(u_texture, vTexCoord - 3.0*blurSize) * 0.09;
texColor += texture2D(u_texture, vTexCoord - 2.0*blurSize) * 0.12;
texColor += texture2D(u_texture, vTexCoord - blurSize) * 0.15;
texColor += texture2D(u_texture, vTexCoord) * 0.16;
texColor += texture2D(u_texture, vTexCoord + blurSize) * 0.15;
texColor += texture2D(u_texture, vTexCoord + 2.0*blurSize) * 0.12;
texColor += texture2D(u_texture, vTexCoord + 3.0*blurSize) * 0.09;
texColor += texture2D(u_texture, vTexCoord + 4.0*blurSize) * 0.05;
El efecto crea una imagen borrosa gaussiana, puramente con GLSL. Siempre puede ajustar las variables a su gusto.