Stylized shadows, not a post processing

The shadow value is offset by noise, without the need for post-processing, ensuring compatibility with fog and volumetric effects.

The inspiration for this shader concept comes from shader made by chrisloop on Unity.

To use this shader, some minor adjustments are required in the Godot Shader Pipeline. Specifically, you’ll need to add a custom built-in function to sample the shadows. A tutorial with the necessary steps you can find here

Shader code
shader_type spatial;

uniform sampler2D noise_texture : source_color, filter_linear_mipmap, repeat_enable;

uniform float noise_strength_1;
uniform float noise_strength_2;

uniform vec4 albedo : source_color;

uniform float shadow_strenght;

uniform vec3 uv_scale_1;
uniform vec3 uv_offset_1;

uniform vec3 uv_scale_2;
uniform vec3 uv_offset_2;

uniform bool use_world;


//https://www.shadertoy.com/view/ws3Bzf
vec4 biplanar_sample( sampler2D tex, vec3 p, vec3 n, float k )
{
	
    // grab coord derivatives for texturing
    vec3 dpdx = dFdx(p);
    vec3 dpdy = dFdy(p);
    n = abs(n);

    // major axis (in x; yz are following axis)
    ivec3 ma = (n.x>n.y && n.x>n.z) ? ivec3(0, 1, 2) : 
              ((n.y>n.z)            ? ivec3(1, 2, 0) : 
                                      ivec3(2, 0, 1));
    // minor axis (in x; yz are following axis)
    ivec3 mi = (n.x<n.y && n.x<n.z) ? ivec3(0, 1, 2) :
              ((n.y<n.z)            ? ivec3(1, 2, 0) :
                                      ivec3(2, 0, 1));
        
    // median axis (in x;  yz are following axis)
    ivec3 me = ivec3(3) - mi - ma;
    
    // project+fetch
    vec4 x = textureGrad( tex, vec2(   p[ma.y],   p[ma.z]), 
                               vec2(dpdx[ma.y],dpdx[ma.z]), 
                               vec2(dpdy[ma.y],dpdy[ma.z]) );
    vec4 y = textureGrad( tex, vec2(   p[me.y],   p[me.z]), 
                               vec2(dpdx[me.y],dpdx[me.z]),
                               vec2(dpdy[me.y],dpdy[me.z]) );
    
    // blend and return
    vec2 m = vec2(n[ma.x], n[me.x]);
    // optional - add local support (prevents discontinuty)
    m = clamp( (m-0.5773)/(1.0-0.5773), 0.0, 1.0 );
    // transition control
    m = pow( m, vec2(k/8.0) );
	return (x*m.x + y*m.y) / (m.x + m.y);
}


varying vec3 _normal;
varying vec3 _vertex;
varying mat4 model_view_mat;

void vertex() {
	
	_vertex = VERTEX;
	_normal = NORMAL;
	
	if ( use_world ){
		_vertex = (MODEL_MATRIX * vec4(VERTEX, 1.0f)).xyz;
		_normal = mat3(MODEL_MATRIX) * NORMAL;
	}
	
	model_view_mat = MODELVIEW_MATRIX;
}

varying vec3 vertex_offset_1;
varying vec3 vertex_offset_2;

void fragment(){
	
	vec4 noise_offset_1 = biplanar_sample(noise_texture, _vertex * uv_scale_1 + uv_offset_1, _normal, 8.0) * noise_strength_1;
	vec4 noise_offset_2 = biplanar_sample(noise_texture, _vertex * uv_scale_2 + uv_offset_2, _normal, 8.0) * noise_strength_2;
	 
 
	vertex_offset_1 = _vertex + noise_offset_1.xyz;
	vertex_offset_2 = _vertex + noise_offset_2.xyz;
	

	if ( use_world ){
		vertex_offset_1 = (VIEW_MATRIX * vec4(vertex_offset_1, 1.0)).xyz;
		vertex_offset_2 = (VIEW_MATRIX * vec4(vertex_offset_2, 1.0)).xyz;
	}else{
		vertex_offset_1 = (model_view_mat * vec4(vertex_offset_1, 1.0)).xyz;
		vertex_offset_2 = (model_view_mat * vec4(vertex_offset_2, 1.0)).xyz;
	}

	ALBEDO = albedo.rgb;
	
}

void light() {
	

	if( LIGHT_IS_DIRECTIONAL){
		
		float shadow_1 = sample_directional_shadow(LIGHT_INDEX, vertex_offset_1);
		float shadow_2 = sample_directional_shadow(LIGHT_INDEX, vertex_offset_2);
	
		float shadow = mix(shadow_1, shadow_2, 0.5);
		shadow = mix(1.0, shadow, shadow_strenght);
		
		DIFFUSE_LIGHT = shadow * ALBEDO;

	}
}
Tags
biplanar mapping, shadows, stylized, texture
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 ShaderError

Simulating Cloud Shadows Analytically

Related shaders

(NOT NEEDED – USE ORIGINAL) High Quality Post Process Outline (FIXED FOR 4.3+)

PS1 Post-processing

Selective post-processing via material ID masking on a second visibility layer

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments