summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
diff options
context:
space:
mode:
authorHugo Locurcio <hugo.locurcio@hugo.pro>2022-05-21 12:17:49 +0200
committerHugo Locurcio <hugo.locurcio@hugo.pro>2022-05-25 12:35:53 +0200
commite85459dcd12b6fd683d94f088d65a22c9c1320a4 (patch)
tree9edb221deedf9e7b38cccd4185baf15f746cac03 /servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
parent1c99b7415fcfd3a9128c7d2ac70f77477fe55c78 (diff)
Add Cone and Cylinder shapes to FogVolume
This complements the existing Ellipsoid and Box local fog shapes. This can be used to represent a light cone coming from a SpotLight.
Diffstat (limited to 'servers/rendering/renderer_rd/shaders/volumetric_fog.glsl')
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog.glsl23
1 files changed, 21 insertions, 2 deletions
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
index a2a4c91894..eee609fb48 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
@@ -186,12 +186,31 @@ void main() {
float sdf = -1.0;
if (params.shape == 0) {
- //Ellipsoid
+ // Ellipsoid
// https://www.shadertoy.com/view/tdS3DG
float k0 = length(local_pos.xyz / params.extents);
float k1 = length(local_pos.xyz / (params.extents * params.extents));
sdf = k0 * (k0 - 1.0) / k1;
} else if (params.shape == 1) {
+ // Cone
+ // https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
+
+ // Compute the cone angle automatically to fit within the volume's extents.
+ float inv_height = 1.0 / max(0.001, params.extents.y);
+ float radius = 1.0 / max(0.001, (min(params.extents.x, params.extents.z) * 0.5));
+ float hypotenuse = sqrt(radius * radius + inv_height * inv_height);
+ float rsin = radius / hypotenuse;
+ float rcos = inv_height / hypotenuse;
+ vec2 c = vec2(rsin, rcos);
+
+ float q = length(local_pos.xz);
+ sdf = max(dot(c, vec2(q, local_pos.y - params.extents.y)), -params.extents.y - local_pos.y);
+ } else if (params.shape == 2) {
+ // Cylinder
+ // https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
+ vec2 d = abs(vec2(length(local_pos.xz), local_pos.y)) - vec2(min(params.extents.x, params.extents.z), params.extents.y);
+ sdf = min(max(d.x, d.y), 0.0) + length(max(d, 0.0));
+ } else if (params.shape == 3) {
// Box
// https://iquilezles.org/www/articles/distfunctions/distfunctions.htm
vec3 q = abs(local_pos.xyz) - params.extents;
@@ -199,7 +218,7 @@ void main() {
}
float cull_mask = 1.0; //used to cull cells that do not contribute
- if (params.shape <= 1) {
+ if (params.shape <= 3) {
#ifndef SDF_USED
cull_mask = 1.0 - smoothstep(-0.1, 0.0, sdf);
#endif