120 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Plaintext
		
	
			
		
		
	
	
			120 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Plaintext
		
	
| /*
 | |
| Shader from Godot Shaders - the free shader library.
 | |
| godotshaders.com/shader/god-rays
 | |
| 
 | |
| Feel free to use, improve and change this shader according to your needs
 | |
| and consider sharing the modified result on godotshaders.com.
 | |
| */
 | |
| 
 | |
| shader_type canvas_item;
 | |
| 
 | |
| uniform sampler2D SCREEN_TEXTURE : hint_screen_texture, filter_linear_mipmap;
 | |
| 
 | |
| uniform float angle : hint_range(-5, 5) = -0.3;
 | |
| uniform float position = -0.2;
 | |
| uniform float spread : hint_range(0.0, 1.0) = 0.5;
 | |
| uniform float cutoff : hint_range(-1.0, 1.0) = 0.1;
 | |
| uniform float falloff : hint_range(0.0, 2.0) = 0.2;
 | |
| uniform float edge_fade : hint_range(0.0, 1.0) = 0.15;
 | |
| 
 | |
| uniform float speed = 1.0;
 | |
| uniform float ray1_density = 8.0;
 | |
| uniform float ray2_density = 30.0;
 | |
| uniform float ray2_intensity : hint_range(0.0, 1.0) = 0.3;
 | |
| 
 | |
| uniform vec4 color : source_color = vec4(1.0, 0.9, 0.65, 0.8);
 | |
| 
 | |
| uniform bool hdr = false;
 | |
| uniform float seed = 5.0;
 | |
| 
 | |
| // Random and noise functions from Book of Shader's chapter on Noise.
 | |
| float random(vec2 _uv) {
 | |
| 	_uv += min(TIME,0.0);
 | |
|     return fract(sin(dot(_uv.xy,
 | |
|         vec2(12.9898, 78.233))) *
 | |
|         43758.5453123);
 | |
| }
 | |
| 
 | |
| float noise (in vec2 uv) {
 | |
|     vec2 i = floor(uv);
 | |
|     vec2 f = fract(uv);
 | |
| 
 | |
|     // Four corners in 2D of a tile
 | |
|     float a = random(i);
 | |
|     float b = random(i + vec2(1.0, 0.0));
 | |
|     float c = random(i + vec2(0.0, 1.0));
 | |
|     float d = random(i + vec2(1.0, 1.0));
 | |
| 
 | |
| 
 | |
|     // Smooth Interpolation
 | |
| 
 | |
|     // Cubic Hermine Curve. Same as SmoothStep()
 | |
|     vec2 u = f * f * (3.0-2.0 * f);
 | |
| 
 | |
|     // Mix 4 coorners percentages
 | |
|     return mix(a, b, u.x) +
 | |
|             (c - a)* u.y * (1.0 - u.x) +
 | |
|             (d - b) * u.x * u.y;
 | |
| }
 | |
| 
 | |
| mat2 rotate(float _angle){
 | |
|     return mat2(vec2(cos(_angle), -sin(_angle)),
 | |
|                 vec2(sin(_angle), cos(_angle)));
 | |
| }
 | |
| 
 | |
| vec4 screen(vec4 base, vec4 blend){
 | |
| 	return 1.0 - (1.0 - base) * (1.0 - blend);
 | |
| }
 | |
| 
 | |
| float custom_smooth_step(float limit1, float limit2, float x) {
 | |
|     if (x <= limit1) {
 | |
|         return 0.0;
 | |
|     } else if (x >= limit2) {
 | |
|         return 1.0;
 | |
|     }
 | |
|     return (limit1 + x) / (limit1 + limit2);
 | |
| }
 | |
| 
 | |
| void fragment()
 | |
| {
 | |
| 	
 | |
| 	// Rotate, skew and move the UVs
 | |
| 	vec2 transformed_uv = ( rotate(angle) * (UV - position) )  / ( (UV.y + spread) - (UV.y * spread) );
 | |
| 	
 | |
| 	// Animate the ray according the the new transformed UVs
 | |
| 	vec2 ray1 = vec2(transformed_uv.x * ray1_density + sin(TIME * 0.1 * speed) * (ray1_density * 0.2) + seed, 1.0);
 | |
| 	vec2 ray2 = vec2(transformed_uv.x * ray2_density + sin(TIME * 0.2 * speed) * (ray1_density * 0.2) + seed, 1.0);
 | |
| 	
 | |
| 	// Cut off the ray's edges
 | |
| 	float cut = step(cutoff, transformed_uv.x) * step(cutoff, 1.0 - transformed_uv.x);
 | |
| 	ray1 *= cut;
 | |
| 	ray2 *= cut;
 | |
| 	
 | |
| 	// Apply the noise pattern (i.e. create the rays)
 | |
| 	float rays;
 | |
| 	
 | |
| 	if (hdr){
 | |
| 		// This is not really HDR, but check this to not clamp the two merged rays making 
 | |
| 		// their values go over 1.0. Can make for some nice effect
 | |
| 		rays = noise(ray1) + (noise(ray2) * ray2_intensity);
 | |
| 	}
 | |
| 	else{
 | |
| 		 rays = clamp(noise(ray1) + (noise(ray2) * ray2_intensity), 0., 1.);
 | |
| 	}
 | |
| 	
 | |
| 	// Fade out edges
 | |
| 	rays *= custom_smooth_step(0.0, falloff, (1.0 - UV.y)); // Bottom
 | |
| 	rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, transformed_uv.x); // Left
 | |
| 	rays *= smoothstep(0.0 + cutoff, edge_fade + cutoff, 1.0 - transformed_uv.x); // Right
 | |
| 	
 | |
| 	// Color to the rays
 | |
| 	vec3 shine = vec3(rays) * color.rgb;
 | |
| 
 | |
| 	// Try different blending modes for a nicer effect. "Screen" is included in the code,
 | |
| 	// but take a look at https://godotshaders.com/snippet/blending-modes/ for more.
 | |
| 	// With "Screen" blend mode:
 | |
| 	shine = screen(texture(SCREEN_TEXTURE, SCREEN_UV), vec4(color)).rgb;
 | |
| 	
 | |
| 	COLOR = vec4(shine, rays * color.a);
 | |
| }
 |