Fake Godrays (Godot 4.x)
Okay, I need GodRays for my game, but I don’t like setting up volumetric fog. Here’s my setup.
I saw this video https://www.youtube.com/watch?v=hZI2pqcp8ig&ab_channel=LaneWallace.
A beautiful and more old-fashioned way. Here is my setup for Godot.
HOW TO USE:
I used CSGCylinder3d – in cone mode, to create the shape on which the shader is placed.
I also added SpotLight3d to it to create an actual light.
Take a look at the screenshot, in addition to the starting parameters, you need to add a NoiseTexture and a transparency gradient.
For alpha, 1D gradient is used.
For the “dust” the standard Godot noise texture is used.
UPD:
Fresnel fade added.
Shader code
shader_type spatial;
render_mode blend_add, depth_draw_opaque, cull_back, diffuse_burley, shadows_disabled;
uniform float alpha : hint_range(0.0, 1.0) = 0.5;
uniform float rim_power : hint_range(0.0, 5.0) = 1.0;
uniform sampler2D texture_emission : source_color, hint_default_black,filter_linear_mipmap,repeat_enable;
uniform sampler2D gradient : source_color, hint_default_black,filter_linear_mipmap,repeat_enable;
uniform vec4 emission : source_color;
uniform float emission_energy : hint_range(0.0, 1.0) = 0.5;
uniform vec3 uv1_scale = vec3(5.0, 0.0, 0.0);
uniform vec3 uv1_offset = vec3(0.0, 1.0, 0.0); //change y to whooooosh effect
varying vec2 base_uv;
// rotate on 90 degrees
vec2 rotateUV(vec2 uv) {
return vec2(1.0 * (uv.y - 0.5) + 0.5, -1.0 * (uv.y - 0.5) + 0.5);
}
void vertex() {
base_uv = rotateUV(UV);
UV = UV * uv1_scale.xy + uv1_offset.xy;
// UV.y += TIME * 0.02; // If you need animation, this needs some work.
}
void fragment() {
vec3 fallof = texture(gradient, base_uv).rgb;
float fresnel = pow(1.0 - dot(normalize(NORMAL), normalize(VIEW)), rim_power);
float fade = mix(1.0, -1.0, fresnel);
ROUGHNESS = 0.0;
SPECULAR = 0.0;
vec3 emission_tex = texture(texture_emission, UV).rgb;
EMISSION = (emission.rgb + emission_tex) * emission_energy * fallof;
ALPHA = clamp(fade, 0.0, 1.0) * EMISSION.r * alpha;
}
very useful, thank you.