Last active
September 20, 2024 15:51
-
-
Save SIsilicon/17ccd24377f4b916a25b9c19fefe1eea to your computer and use it in GitHub Desktop.
Godot Painting Post procssing effect
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
shader_type canvas_item; | |
uniform sampler2D distort_texture; | |
uniform float fade : hint_range(0.0, 1.0) = 0.86; | |
uniform float desat : hint_range(0.0, 1.0) = 0.3; | |
uniform float scale = 0.009; | |
uniform float intensity = 0.041; | |
uniform int kuwahara_radius = 4; | |
varying vec2 world_position; | |
void vertex() { | |
world_position = VERTEX.xy; | |
} | |
vec4 kuwahara(sampler2D tex, vec2 uv, int radius) { | |
vec2 src_size = 1.0 / vec2(textureSize(tex, 0)); | |
float n = float((radius + 1) * (radius + 1)); | |
int i; | |
int j; | |
vec3 m0 = vec3(0.0); vec3 m1 = vec3(0.0); vec3 m2 = vec3(0.0); vec3 m3 = vec3(0.0); | |
vec3 s0 = vec3(0.0); vec3 s1 = vec3(0.0); vec3 s2 = vec3(0.0); vec3 s3 = vec3(0.0); | |
vec3 c; | |
for (j = -radius; j <= 0; ++j) { | |
for (i = -radius; i <= 0; ++i) { | |
c = texture(tex, uv + vec2(float(i),float(j)) * src_size).rgb; | |
m0 += c; | |
s0 += c * c; | |
} | |
} | |
for (j = -radius; j <= 0; ++j) { | |
for (i = 0; i <= radius; ++i) { | |
c = texture(tex, uv + vec2(float(i),float(j)) * src_size).rgb; | |
m1 += c; | |
s1 += c * c; | |
} | |
} | |
for (j = 0; j <= radius; ++j) { | |
for (i = 0; i <= radius; ++i) { | |
c = texture(tex, uv + vec2(float(i),float(j)) * src_size).rgb; | |
m2 += c; | |
s2 += c * c; | |
} | |
} | |
for (j = 0; j <= radius; ++j) { | |
for (i = -radius; i <= 0; ++i) { | |
c = texture(tex, uv + vec2(float(i),float(j)) * src_size).rgb; | |
m3 += c; | |
s3 += c * c; | |
} | |
} | |
vec4 fragColor = vec4(0.0); | |
float min_sigma2 = 1e+2; | |
m0 /= n; | |
s0 = abs(s0 / n - m0 * m0); | |
float sigma2 = s0.r + s0.g + s0.b; | |
if (sigma2 < min_sigma2) { | |
min_sigma2 = sigma2; | |
fragColor = vec4(m0, 1.0); | |
} | |
m1 /= n; | |
s1 = abs(s1 / n - m1 * m1); | |
sigma2 = s1.r + s1.g + s1.b; | |
if (sigma2 < min_sigma2) { | |
min_sigma2 = sigma2; | |
fragColor = vec4(m1, 1.0); | |
} | |
m2 /= n; | |
s2 = abs(s2 / n - m2 * m2); | |
sigma2 = s2.r + s2.g + s2.b; | |
if (sigma2 < min_sigma2) { | |
min_sigma2 = sigma2; | |
fragColor = vec4(m2, 1.0); | |
} | |
m3 /= n; | |
s3 = abs(s3 / n - m3 * m3); | |
sigma2 = s3.r + s3.g + s3.b; | |
if (sigma2 < min_sigma2) { | |
min_sigma2 = sigma2; | |
fragColor = vec4(m3, 1.0); | |
} | |
return fragColor; | |
} | |
vec3 blendNormal(vec3 normal){ | |
vec3 blending = abs(normal); | |
blending = normalize(max(blending, 0.00001)); | |
blending /= vec3(blending.x + blending.y + blending.z); | |
return blending; | |
} | |
vec3 triplanarMapping(sampler2D tex, vec3 normal, vec3 position) { | |
vec3 normalBlend = blendNormal(normal); | |
vec3 xColor = texture(tex, position.yz).rgb; | |
vec3 yColor = texture(tex, position.xz).rgb; | |
vec3 zColor = texture(tex, position.xy).rgb; | |
return (xColor * normalBlend.x + yColor * normalBlend.y + zColor * normalBlend.z); | |
} | |
void fragment() { | |
// float depth = texture(DEPTH_TEXTURE, SCREEN_UV).x; | |
// vec3 ndc = vec3(SCREEN_UV, depth) * 2.0 - 1.0; | |
// vec4 view = INV_PROJECTION_MATRIX * vec4(ndc, 1.0); | |
// view.xyz /= view.w; | |
// float linear_depth = -view.z; | |
// vec4 world = CAMERA_MATRIX * INV_PROJECTION_MATRIX * vec4(ndc, 1.0); | |
// vec3 world_position = world.xyz / world.w; | |
// vec3 world_normal = cross(normalize(dFdx(world_position)), normalize(dFdy(world_position))); | |
vec2 uv = SCREEN_UV; | |
vec2 distortion = texture(distort_texture, world_position * scale).rg/*triplanarMapping(distort_texture, world_normal, world_position * scale).rg*/ * 2.0 - 1.0; | |
uv += intensity * distortion; | |
vec3 paint = kuwahara(SCREEN_TEXTURE, uv, kuwahara_radius).rgb; | |
float desaturation = texture(distort_texture, -world_position * scale / 4.0).g * desat; | |
paint = mix(paint, vec3(paint.r + paint.g + paint.b) / 3.0, desaturation); | |
COLOR = vec4(mix(texture(SCREEN_TEXTURE, SCREEN_UV).rgb, paint, fade), 1.0); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment