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 */
|
/* Gunk shader adapted to a canvas item */
|
||||||
shader_type canvas_item;
|
shader_type canvas_item;
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// -*- mode: glsl -*-
|
||||||
// Common logic for gunk shaders
|
// Common logic for gunk shaders
|
||||||
|
|
||||||
group_uniforms gunk_material;
|
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 sampler2D overlay_emission: hint_default_transparent, filter_nearest;
|
||||||
uniform float overlay_emission_scale = 1.0;
|
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 rim_glow(
|
||||||
vec3 normal,
|
vec3 normal,
|
||||||
vec3 view,
|
vec3 view,
|
||||||
@ -89,3 +107,82 @@ vec3 base_emission(vec2 uv, float value) {
|
|||||||
float base_specular() {
|
float base_specular() {
|
||||||
return 0.5 * inversesqrt(specular_contribution);
|
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;
|
shader_type spatial;
|
||||||
render_mode depth_prepass_alpha, unshaded;
|
render_mode depth_prepass_alpha, unshaded;
|
||||||
|
|
||||||
|
#define USE_MASK
|
||||||
#include "common.gdshaderinc"
|
#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() {
|
void fragment() {
|
||||||
vec3 uvt = scale_uvt(UV, TIME);
|
vec3 uvt = scale_uvt(UV, TIME);
|
||||||
float value = sample_noise(uvt);
|
float value = sample_noise(uvt);
|
||||||
|
|
||||||
|
|
||||||
// Build normal map from bump map
|
vec3 nmap = sobel_convolution(UV, uvt);
|
||||||
float h_center = bump_sample(UV, uvt, 0.0, 0.0);
|
ALBEDO = nmap / 2.0 + 0.5;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// -*- mode: glsl -*-
|
||||||
shader_type spatial;
|
shader_type spatial;
|
||||||
render_mode depth_prepass_alpha;
|
render_mode depth_prepass_alpha;
|
||||||
|
|
||||||
@ -23,11 +24,6 @@ void vertex() {
|
|||||||
VERTEX *= 1.0 + jitter;
|
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() {
|
void fragment() {
|
||||||
vec3 uvt = scale_uvt(UV, TIME);
|
vec3 uvt = scale_uvt(UV, TIME);
|
||||||
float value = sample_noise(uvt);
|
float value = sample_noise(uvt);
|
||||||
@ -36,17 +32,11 @@ void fragment() {
|
|||||||
EMISSION = base_emission(UV, value);
|
EMISSION = base_emission(UV, value);
|
||||||
SPECULAR = base_specular();
|
SPECULAR = base_specular();
|
||||||
|
|
||||||
// Build normal map from bump map
|
vec3 nmap = sobel_convolution(UV, uvt);
|
||||||
float h_center = bump_sample(uvt, 0.0, 0.0);
|
NORMAL_MAP = nmap / 2.0 + 0.5;
|
||||||
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;
|
|
||||||
|
|
||||||
// add fresnel
|
// add fresnel
|
||||||
vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * normal_diff_map;
|
vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * nmap;
|
||||||
EMISSION += rim_glow(
|
EMISSION += rim_glow(
|
||||||
world_normal,
|
world_normal,
|
||||||
VIEW,
|
VIEW,
|
||||||
|
@ -1,20 +1,10 @@
|
|||||||
|
// -*- mode: glsl -*-
|
||||||
shader_type spatial;
|
shader_type spatial;
|
||||||
render_mode depth_prepass_alpha;
|
render_mode depth_prepass_alpha;
|
||||||
|
|
||||||
|
#define USE_MASK
|
||||||
#include "common.gdshaderinc"
|
#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() {
|
void fragment() {
|
||||||
vec3 uvt = scale_uvt(UV, TIME);
|
vec3 uvt = scale_uvt(UV, TIME);
|
||||||
float value = sample_noise(uvt);
|
float value = sample_noise(uvt);
|
||||||
@ -23,17 +13,16 @@ void fragment() {
|
|||||||
EMISSION = base_emission(UV, value);
|
EMISSION = base_emission(UV, value);
|
||||||
SPECULAR = base_specular();
|
SPECULAR = base_specular();
|
||||||
|
|
||||||
// Build normal map from bump map
|
// vec3 nmap = minimal_convolution(UV, uvt);
|
||||||
float h_center = bump_sample(UV, uvt, 0.0, 0.0);
|
// vec3 nmap = cross_convolution(UV, uvt);
|
||||||
float h_right = bump_sample(UV, uvt, 1.0, 0.0);
|
vec3 nmap = sobel_convolution(UV, uvt);
|
||||||
float h_down = bump_sample(UV, uvt, 0.0, 1.0);
|
// vec3 nmap = sobel_5x5_convolution(UV, uvt);
|
||||||
float dx = (h_center - h_right) * bump_strength;
|
// vec3 nmap = scharr_convolution(UV, uvt);
|
||||||
float dy = (h_center - h_down) * bump_strength;
|
// vec3 nmap = godot_convolution(UV, uvt);
|
||||||
vec3 normal_diff_map = normalize(vec3(dx, dy, 1.0));
|
NORMAL_MAP = nmap / 2.0 + 0.5;
|
||||||
NORMAL_MAP = normal_diff_map / 2.0 + 0.5;
|
|
||||||
|
|
||||||
// add fresnel
|
// add fresnel
|
||||||
vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * normal_diff_map;
|
vec3 world_normal = mat3(TANGENT, BINORMAL, NORMAL) * nmap;
|
||||||
EMISSION += rim_glow(
|
EMISSION += rim_glow(
|
||||||
world_normal,
|
world_normal,
|
||||||
VIEW,
|
VIEW,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user