Skip to content

Instantly share code, notes, and snippets.

@HungryProton
Created July 24, 2024 07:58
Show Gist options
  • Save HungryProton/2459d9c4ba4a3e710d9435e24d39b6f2 to your computer and use it in GitHub Desktop.
Save HungryProton/2459d9c4ba4a3e710d9435e24d39b6f2 to your computer and use it in GitHub Desktop.
Random experiments for POM from the "Godot Effects and Shaders" discord group, based on Tentabrobpy's shader.
// NOTE: Shader automatically converted from Godot Engine 4.3.beta3's StandardMaterial3D.
shader_type spatial;
render_mode blend_mix, depth_draw_opaque;
uniform vec4 albedo : source_color;
uniform sampler2D texture_albedo : source_color, filter_linear_mipmap, repeat_enable;
uniform sampler2D texture_normal : hint_roughness_normal,filter_linear_mipmap,repeat_enable;
uniform float normal_scale : hint_range(-16,16);
uniform sampler2D texture_heightmap : hint_default_black, filter_linear_mipmap, repeat_enable;
uniform float heightmap_scale : hint_range(-16.0, 16.0, 0.001);
uniform int heightmap_min_layers : hint_range(1, 64);
uniform int heightmap_max_layers : hint_range(1, 64);
uniform vec2 heightmap_flip;
uniform vec3 uv1_scale;
uniform vec3 uv1_offset;
uniform vec3 uv2_scale;
uniform vec3 uv2_offset;
void vertex() {
UV = UV * uv1_scale.xy + uv1_offset.xy;
}
void fragment() {
vec2 base_uv = UV;
vec3 view_dir = normalize(normalize(-VERTEX + EYE_OFFSET) * mat3(TANGENT * heightmap_flip.x, -BINORMAL * heightmap_flip.y, NORMAL));
float num_layers = mix(float(heightmap_max_layers),float(heightmap_min_layers), abs(dot(vec3(0.0, 0.0, 1.0), view_dir)));
float layer_depth = 1.0 / num_layers;
float current_layer_depth = 0.0;
vec2 P = view_dir.xy / view_dir.z * heightmap_scale * 0.01;
vec2 delta = P / num_layers;
vec2 ofs = base_uv;
float depth = 1.0 - texture(texture_heightmap, ofs).r;
float current_depth = 0.0;
while(current_depth < depth) {
ofs -= delta;
depth = 1.0 - texture(texture_heightmap, ofs).r;
current_depth += layer_depth;
}
vec2 prev_ofs = ofs + delta;
float after_depth = depth - current_depth;
float before_depth = ( 1.0 - texture(texture_heightmap, prev_ofs).r ) - current_depth + layer_depth;
float weight = after_depth / (after_depth - before_depth);
ofs = mix(ofs,prev_ofs,weight);
float xz_distance = length(ofs - base_uv) * 16.0;
base_uv=ofs;
float surface_depth = 1.0 - texture(texture_heightmap, base_uv).r;
float view_depth = sqrt(xz_distance * xz_distance + surface_depth * surface_depth);
vec3 offset_vertex = VERTEX - vec3(0, 0, 1) * view_depth * heightmap_scale * 0.01;
LIGHT_VERTEX = offset_vertex;
vec4 vertex_ndc = PROJECTION_MATRIX * vec4(offset_vertex, 1.0);
float offset_depth = vertex_ndc.z / vertex_ndc.w;
DEPTH = offset_depth;
vec4 albedo_tex = texture(texture_albedo,base_uv);
ALBEDO = albedo.rgb * albedo_tex.rgb;
NORMAL_MAP = texture(texture_normal,base_uv).rgb;
NORMAL_MAP_DEPTH = normal_scale;
if (base_uv.x < 0.0 || base_uv.x > 1.0 || base_uv.y < 0.0 || base_uv.y > 1.0) {
discard;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment