Snow-Covered Surface

Displays snow colour on upward-facing surfaces, and accounts for normal map while we’re at it.

Mostly exists so I could try out converting a normal map to a worldspace vector.

Shader code
shader_type spatial;

uniform sampler2D normal:hint_normal;
uniform vec3 base_colour:source_color = vec3(0.5, 0.5, 0.5);

uniform vec3 snow_colour : source_color = vec3(0.9, 1.0, 1.0);

uniform float snow_ammount = 0.2;
uniform float snow_softness = 10.0;


// converts two-channel normal map into proper vector
vec3 convert_normal_map(vec2 normal_sample) {
	vec3 result;
	result.xy = normal_sample * 2.0 - 1.0;
    result.z = sqrt(1.0 - dot(result.xy, result.xy));
	return result;
}

void fragment() {
	// snow mask based on normal map
	vec4 normal_map = texture(normal, UV * 3.0);
    vec3 normal_map_vector = convert_normal_map(normal_map.rg);
    vec3 viewspace_normal = normalize(TANGENT * normal_map_vector.r + BINORMAL * normal_map_vector.g + NORMAL * normal_map_vector.b);
    vec3 world_normal = (INV_VIEW_MATRIX * vec4(viewspace_normal, 0.0)).xyz;
    vec3 up = vec3(0, 1, 0);
    float mapped_snow_mask = smoothstep(0.0, 1.0 - snow_ammount, dot(world_normal, up));
	mapped_snow_mask = pow(mapped_snow_mask, snow_softness);

	// snow mask based on vertex normal
	world_normal = (INV_VIEW_MATRIX * vec4(NORMAL, 0.0)).xyz;
	float vertex_snow_mask = smoothstep(0.0, 1.0 - snow_ammount, dot(world_normal, up));
	vertex_snow_mask = pow(vertex_snow_mask, snow_softness);

	// get higher of both
	float snow_mask = max(vertex_snow_mask, mapped_snow_mask);

    ALBEDO = mix(base_colour, snow_colour, snow_mask);
	NORMAL_MAP = mix(normal_map.rgb, vec3(0.5), snow_mask); // snow smooths out normals
}
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from rrh

Screen-space oriented texture display

Stencil-based silhouette

Related shaders

PSX Style Water Surface – Pixelation, Waves, Scrolling Textures

Surface Embedded Sprites

Cast Texture To Surface

guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments