generated from krampus/template-godot4
Sobel filter sampling for gunk normal maps
This commit is contained in:
parent
e5ce84bec1
commit
66b8c90070
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,3 +1,4 @@
|
||||
// -*- mode: glsl -*-
|
||||
/* Gunk shader adapted to a canvas item */
|
||||
shader_type canvas_item;
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
// -*- mode: glsl -*-
|
||||
// Common logic for gunk shaders
|
||||
|
||||
group_uniforms gunk_material;
|
||||
@ -36,6 +37,23 @@ uniform sampler2D overlay_albedo: hint_default_transparent, filter_nearest;
|
||||
uniform sampler2D overlay_emission: hint_default_transparent, filter_nearest;
|
||||
uniform float overlay_emission_scale = 1.0;
|
||||
|
||||
#if defined(USE_MASK)
|
||||
group_uniforms gunk_mask;
|
||||
uniform float edge_bleed = 0.25;
|
||||
uniform sampler2D gunk_mask;
|
||||
#endif
|
||||
|
||||
|
||||
float bump_sample(vec2 uv, vec3 uvt, float dx, float dy) {
|
||||
vec2 offset = vec2(dx / pixellation, dy / pixellation);
|
||||
float height = texture(gunk_noise, uvt + vec3(offset, 0.0)).r;
|
||||
#if defined(USE_MASK)
|
||||
float mask = texture(gunk_mask, uv + offset).r;
|
||||
height *= smoothstep(1.0, 0.0, mask);
|
||||
#endif
|
||||
return height;
|
||||
}
|
||||
|
||||
vec3 rim_glow(
|
||||
vec3 normal,
|
||||
vec3 view,
|
||||
@ -89,3 +107,82 @@ vec3 base_emission(vec2 uv, float value) {
|
||||
float base_specular() {
|
||||
return 0.5 * inversesqrt(specular_contribution);
|
||||
}
|
||||
|
||||
// Convolution methods
|
||||
|
||||
vec3 godot_convolution(vec2 uv, vec3 uvt) {
|
||||
// from https://github.com/godotengine/godot/blob/master/core/io/image.cpp#L3758
|
||||
float here = bump_sample(uv, uvt, 0.0, 0.0);
|
||||
float to_right = bump_sample(uv, uvt, 1.0, 0.0);
|
||||
float above = bump_sample(uv, uvt, 0.0, -1.0);
|
||||
vec3 up = vec3(0.0, 1.0, (here - above) * bump_strength);
|
||||
vec3 across = vec3(1.0, 0.0, (to_right - here) * bump_strength);
|
||||
return normalize(cross(across, up));
|
||||
}
|
||||
|
||||
vec3 minimal_convolution(vec2 uv, vec3 uvt) {
|
||||
float h_center = bump_sample(uv, uvt, 0.0, 0.0);
|
||||
float h_right = bump_sample(uv, uvt, 1.0, 0.0);
|
||||
float h_down = bump_sample(uv, uvt, 0.0, 1.0);
|
||||
float dX = (h_center - h_right);
|
||||
float dY = (h_center - h_down);
|
||||
float dZ = 1.0 / bump_strength;
|
||||
return normalize(vec3(dX, dY, dZ));
|
||||
}
|
||||
|
||||
vec3 cross_convolution(vec2 uv, vec3 uvt) {
|
||||
float h_right = bump_sample(uv, uvt, 1.0, 0.0);
|
||||
float h_down = bump_sample(uv, uvt, 0.0, 1.0);
|
||||
float h_left = bump_sample(uv, uvt, -1.0, 0.0);
|
||||
float h_up = bump_sample(uv, uvt, 0.0, -1.0);
|
||||
float dX = (h_left - h_right);
|
||||
float dY = (h_right - h_down);
|
||||
float dZ = 1.0 / bump_strength * 2.0;
|
||||
return normalize(vec3(dX, dY, dZ));
|
||||
}
|
||||
|
||||
vec3 sobel_convolution(vec2 uv, vec3 uvt) {
|
||||
float tl = bump_sample(uv, uvt, -1.0, -1.0);
|
||||
float l = bump_sample(uv, uvt, -1.0, 0.0);
|
||||
float bl = bump_sample(uv, uvt, -1.0, 1.0);
|
||||
float t = bump_sample(uv, uvt, 0.0, -1.0);
|
||||
float b = bump_sample(uv, uvt, 0.0, 1.0);
|
||||
float tr = bump_sample(uv, uvt, 1.0, -1.0);
|
||||
float r = bump_sample(uv, uvt, 1.0, 0.0);
|
||||
float br = bump_sample(uv, uvt, 1.0, 1.0);
|
||||
float dX = (tr + 2.0 * r + br) - (tl + 2.0 * l + bl);
|
||||
float dY = (bl + 2.0 * b + br) - (tl + 2.0 * t + tr);
|
||||
float dZ = 1.0 / bump_strength * 8.0;
|
||||
return normalize(vec3(dX, dY, dZ));
|
||||
}
|
||||
|
||||
vec3 scharr_convolution(vec2 uv, vec3 uvt) {
|
||||
float tl = bump_sample(uv, uvt, -1.0, -1.0);
|
||||
float l = bump_sample(uv, uvt, -1.0, 0.0);
|
||||
float bl = bump_sample(uv, uvt, -1.0, 1.0);
|
||||
float t = bump_sample(uv, uvt, 0.0, -1.0);
|
||||
float b = bump_sample(uv, uvt, 0.0, 1.0);
|
||||
float tr = bump_sample(uv, uvt, 1.0, -1.0);
|
||||
float r = bump_sample(uv, uvt, 1.0, 0.0);
|
||||
float br = bump_sample(uv, uvt, 1.0, 1.0);
|
||||
float dX = 3.0*tl + 10.0*l + 3.0*bl - 3.0*tr - 10.0*r - 3.0*br;
|
||||
float dY = 3.0*tl + 10.0*t + 3.0*tr - 3.0*bl - 10.0*b - 3.0*br;
|
||||
float dZ = 1.0 / bump_strength * 12.0;
|
||||
return normalize(vec3(dX, dY, dZ));
|
||||
}
|
||||
|
||||
vec3 sobel_5x5_convolution(vec2 uv, vec3 uvt) {
|
||||
// Expensive!!
|
||||
// TODO this can be decomposed into a few small matrix ops
|
||||
float s[25];
|
||||
for (int i = 0; i < 5; i++) {
|
||||
for (int j = 0; j < 5; j++) {
|
||||
s[i*5 + j] = bump_sample(uv, uvt, float(i - 2), float(j - 2));
|
||||
}
|
||||
}
|
||||
|
||||
float dX = 4.0 * (s[3] + s[23] - s[1] - s[21]) + 5.0 * (s[4] + s[24] - s[0] - s[20]) + 8.0 * (s[9] + s[19] - s[5] - s[15]) + 10.0 * (s[8] + s[14] + s[18] - s[6] - s[10] - s[16]) + 20.0 * (s[13] - s[11]);
|
||||
float dY = 4.0 * (s[19] + s[15] - s[9] - s[5]) + 5.0 * (s[24] + s[20] - s[4] - s[0]) + 8.0 * (s[23] + s[21] - s[3] - s[1]) + 10.0 * (s[18] + s[22] + s[16] - s[8] - s[2] - s[6]) + 20.0 * (s[17] - s[7]);
|
||||
float dZ = 1.0 / bump_strength * 240.0;
|
||||
return normalize(vec3(dX, dY, dZ));
|
||||
}
|
||||
|
@ -1,31 +1,16 @@
|
||||
// -*- mode: glsl -*-
|
||||
shader_type spatial;
|
||||
render_mode depth_prepass_alpha, unshaded;
|
||||
|
||||
#define USE_MASK
|
||||
#include "common.gdshaderinc"
|
||||
|
||||
group_uniforms gunk_mask;
|
||||
uniform float edge_bleed = 0.25;
|
||||
uniform sampler2D gunk_mask;
|
||||
|
||||
|
||||
float bump_sample(vec2 uv, vec3 uvt, float dx, float dy) {
|
||||
vec2 offset = vec2(dx / pixellation, dy / pixellation);
|
||||
float height = texture(gunk_noise, uvt + vec3(offset, 0.0)).r;
|
||||
float mask = texture(gunk_mask, uv + offset / uv_scale).r;
|
||||
return height * smoothstep(1.0, 0.0, mask);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec3 uvt = scale_uvt(UV, TIME);
|
||||
float value = sample_noise(uvt);
|
||||
|
||||
|
||||
// Build normal map from bump map
|
||||
float h_center = bump_sample(UV, uvt, 0.0, 0.0);
|
||||
float h_right = bump_sample(UV, uvt, 1.0, 0.0);
|
||||
float h_down = bump_sample(UV, uvt, 0.0, 1.0);
|
||||
float dx = (h_center - h_right) * bump_strength;
|
||||
float dy = (h_center - h_down) * bump_strength;
|
||||
vec3 normal_diff_map = normalize(vec3(dx, dy, 1.0));
|
||||
ALBEDO = normal_diff_map / 2.0 + 0.5;
|
||||
vec3 nmap = sobel_convolution(UV, uvt);
|
||||
ALBEDO = nmap / 2.0 + 0.5;
|
||||
}
|
||||
|
@ -1,3 +1,4 @@
|
||||
// -*- mode: glsl -*-
|
||||
shader_type spatial;
|
||||
render_mode depth_prepass_alpha;
|
||||
|
||||
@ -23,11 +24,6 @@ void vertex() {
|
||||
VERTEX *= 1.0 + jitter;
|
||||
}
|
||||
|
||||
float bump_sample(vec3 uvt, float dx, float dy) {
|
||||
vec2 offset = vec2(dx / pixellation, dy / pixellation);
|
||||
return texture(gunk_noise, uvt + vec3(offset, 0.0)).r;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec3 uvt = scale_uvt(UV, TIME);
|
||||
float value = sample_noise(uvt);
|
||||
@ -36,17 +32,11 @@ void fragment() {
|
||||
EMISSION = base_emission(UV, value);
|
||||
SPECULAR = base_specular();
|
||||
|
||||
// Build normal map from bump map
|
||||
float h_center = bump_sample(uvt, 0.0, 0.0);
|
||||
float h_right = bump_sample(uvt, 1.0, 0.0);
|
||||
float h_down = bump_sample(uvt, 0.0, 1.0);
|
||||
float dx = (h_center - h_right) * bump_strength;
|
||||
float dy = (h_center - h_down) * bump_strength;
|
||||
vec3 normal_diff_map = normalize(vec3(dx, dy, 1.0));
|
||||
NORMAL_MAP = normal_diff_map / 2.0 + 0.5;
|
||||
vec3 nmap = sobel_convolution(UV, uvt);
|
||||
NORMAL_MAP = nmap / 2.0 + 0.5;
|
||||
|
||||
// add fresnel
|
||||
vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * normal_diff_map;
|
||||
vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * nmap;
|
||||
EMISSION += rim_glow(
|
||||
world_normal,
|
||||
VIEW,
|
||||
|
@ -1,20 +1,10 @@
|
||||
// -*- mode: glsl -*-
|
||||
shader_type spatial;
|
||||
render_mode depth_prepass_alpha;
|
||||
|
||||
#define USE_MASK
|
||||
#include "common.gdshaderinc"
|
||||
|
||||
group_uniforms gunk_mask;
|
||||
uniform float edge_bleed = 0.25;
|
||||
uniform sampler2D gunk_mask;
|
||||
|
||||
|
||||
float bump_sample(vec2 uv, vec3 uvt, float dx, float dy) {
|
||||
vec2 offset = vec2(dx / pixellation, dy / pixellation);
|
||||
float height = texture(gunk_noise, uvt + vec3(offset, 0.0)).r;
|
||||
float mask = texture(gunk_mask, uv + offset / uv_scale).r;
|
||||
return height * smoothstep(1.0, 0.0, mask);
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec3 uvt = scale_uvt(UV, TIME);
|
||||
float value = sample_noise(uvt);
|
||||
@ -23,17 +13,16 @@ void fragment() {
|
||||
EMISSION = base_emission(UV, value);
|
||||
SPECULAR = base_specular();
|
||||
|
||||
// Build normal map from bump map
|
||||
float h_center = bump_sample(UV, uvt, 0.0, 0.0);
|
||||
float h_right = bump_sample(UV, uvt, 1.0, 0.0);
|
||||
float h_down = bump_sample(UV, uvt, 0.0, 1.0);
|
||||
float dx = (h_center - h_right) * bump_strength;
|
||||
float dy = (h_center - h_down) * bump_strength;
|
||||
vec3 normal_diff_map = normalize(vec3(dx, dy, 1.0));
|
||||
NORMAL_MAP = normal_diff_map / 2.0 + 0.5;
|
||||
// vec3 nmap = minimal_convolution(UV, uvt);
|
||||
// vec3 nmap = cross_convolution(UV, uvt);
|
||||
vec3 nmap = sobel_convolution(UV, uvt);
|
||||
// vec3 nmap = sobel_5x5_convolution(UV, uvt);
|
||||
// vec3 nmap = scharr_convolution(UV, uvt);
|
||||
// vec3 nmap = godot_convolution(UV, uvt);
|
||||
NORMAL_MAP = nmap / 2.0 + 0.5;
|
||||
|
||||
// add fresnel
|
||||
vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * normal_diff_map;
|
||||
vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * nmap;
|
||||
EMISSION += rim_glow(
|
||||
world_normal,
|
||||
VIEW,
|
||||
|
Loading…
x
Reference in New Issue
Block a user