About Dynamic Cloud Shadow
- Edited
GodotBeliever dynamic cloud shadow effect
please explain with words and not corporate buzzwords. the hell is a dynamic cloud shadow?
if you mean those blotches of light. you do that with a transparent material above the world. you put a texture on it, and then set the material to alpha scissor
, and the light will get through the holes. another way is to just use a mesh with the shapes and have it cast shadows, and the light will get through the holes.
I think you can even hide the mesh by setting it to shadows only
in geometry
.
when trying to solve a problem, be creative. think of how you would do this in the real world, most of the times it's not that complicated.
kuligs2 Thank you for your answer.yes, I used to read about this shader, but it requires a recompilation of godot, which I don't want to do
Jesusemora T Thank you for your answer. This might be another way to do that. And then make the grid, move, like a cloud in real life?
GodotBeliever like a cloud in real life?
yes. and the shadow is tied to the light source, so for changing it you would have to put your "clouds" and a second sun into their own visual layers
and keep the rest of the objects out of it. then you would be able to change the shadow opacity
and blur
of this fake sun and more.
Jesusemora I don't understand why a second fake sun is needed, if it's just on its own visual layer, if it's also on its own visual layer, so how does the shadow interact with the environment and the characters?
GodotBeliever yeah, maybe it won't work, I would have to test it myself.
the idea was to affect the shadow of the clouds independently from the one on the players.
you can still change the blur and opacity of the sun shadow.
or, here's another method I just realized: use a projector texture on the sun. this texture would add the dark spots simulating clouds, and you can make the edges softer in the texture.
- Edited
GodotBeliever Make a plane mesh that will act as a cloud layer. Assign a shader to it. Plug a noise texture into the shader. In the shader, sample the noise texture and assign its value to ALPHA
output. Also plug a float uniform (range 0-1) into the shader and assign its value to ALPHA_SCISSOR_THRESHOLD
.
The plane should now have a thresholded noise mask that will cast proper regular shadows from any light source.
You can't really do it via alpha blend transparency (without alpha scissor) as that sends the object down the transparent pipeline which disables shadow casting for that object.
Jesusemora If it's a shadow that can be adjusted, it does need a separate visual layer, and you also need to consider how the shadow affects the player and the environment. using a projector texture on the sun, you can indeed achieve the shadow of the cloud, this needs to consider what kind of texture is appropriate, I don't know how much time it takes
xyz Thank you for your answer, in fact I don't know much about shaders right now, but I'll find a way to learn to get to the part where I can implement the shader you said. Then look at the effect
- Edited
- Best Answerset by GodotBeliever
GodotBeliever This is trivial. The shader is needed only to interpret texture as alpha. Afaik there is no straightforward way to do this directly in a standard material with a procedural noise as it outputs alpha as fully opaque. There's a "trick" though using msdf.
Assign a noise texture to standard material's Albedo, enable Texture MSDF in material's Albedo section. In material's Transparency section set Transparency to "Alpha Scissor" and adjust "Alpha Scissor Threshold"
It can be done without enabling MSDF for a standard rgba file texture as that texture's alpha will be interpreted as transparency by the material.
For completeness, hare's the shader too:
shader_type spatial;
uniform sampler2D noise;
uniform float threshold;
void fragment(){
ALPHA = texture(noise, UV + TIME*.2).r;
ALPHA_SCISSOR_THRESHOLD = threshold;
}
- Edited
shader_type spatial;
uniform sampler2D noise;
uniform float threshold : hint_range(0.0, 1.0) = 0.5;
uniform float speed : hint_range(0.0, 16.0) = 1.0;
uniform vec2 uv_scale = vec2(1.0, 1.0);
void vertex()
{
UV = (UV * uv_scale) + TIME * speed;
}
void fragment(){
ALPHA = texture(noise, UV).r;
ALPHA_SCISSOR_THRESHOLD = threshold;
}
added a speed slider, uv scale, and moved shift calculation to vertex for performance.
Jesusemora I raise you some poor man's turbulence
shader_type spatial;
uniform sampler2D noise;
uniform float threshold : hint_range(0.0, 1.0) = 0.5;
uniform float speed : hint_range(0.0, 16.0) = 1.0;
uniform vec2 uv_scale = vec2(1.0, 1.0);
uniform float turbulence_frequency = 8.0;
uniform float turbulence_amplitude : hint_range(0.0, .5) = .05;
uniform float turbulence_speed = 3.0;
void vertex()
{
UV = (UV * uv_scale) + TIME * speed;
}
void fragment(){
vec2 uv = UV + vec2(
sin(UV.y * turbulence_frequency + TIME * turbulence_speed ) * turbulence_amplitude,
cos(UV.x * turbulence_frequency + TIME * turbulence_speed ) * turbulence_amplitude
);
ALPHA = texture(noise, uv).r;
ALPHA_SCISSOR_THRESHOLD = threshold;
}
I think the first one has already had a good effect, and I didn't expect you to be able to refine this effect even more, which makes me excited.
- Edited
GodotBeliever here's a turbulence using a normal texture, it is (probably) more performant while giving you more control over the deformation, you can make it all rough all of a sudden with an uneven texture.
shader_type spatial;
uniform sampler2D noise;
uniform sampler2D bump : hint_normal;
uniform float threshold : hint_range(0.0, 1.0) = 0.5;
uniform float speed : hint_range(0.0, 16.0) = 1.0;
uniform float speed2 : hint_range(0.0, 16.0) = 0.1;
uniform float distortion_value : hint_range(0.0, 16.0) = 1.0;
uniform vec2 uv_scale = vec2(1.0, 1.0);
uniform vec2 uv_detail_scale = vec2(0.5, 0.5);
varying vec2 uv_normal;
void vertex()
{
uv_normal = (UV * uv_detail_scale) + TIME * speed2;
UV = (UV * uv_scale) + TIME * speed;
}
void fragment(){
vec3 distortion = texture(bump, uv_normal).rgb * distortion_value;
ALPHA = texture(noise, UV + distortion).r;
ALPHA_SCISSOR_THRESHOLD = threshold;
}
Jesusemora ALPHA = texture(noise, UV + distortion).r;
The editor says that this line of code uses vec2+vec3, which causes the shader to not work properly. :
GodotBeliever distortion.xy
GodotBeliever my bad:
ALPHA = texture(noise, UV + distortion.xy).r;
@Jesusemora @xyz Thanks, I reworked the shader file, sometimes it can achieve interesting visuals.
GodotBeliever I love it!
Also keep in mind that slower speed
can be used for water and faster speed
will give you wind