diff options
author | Hugo Locurcio <hugo.locurcio@hugo.pro> | 2022-05-21 12:17:49 +0200 |
---|---|---|
committer | Hugo Locurcio <hugo.locurcio@hugo.pro> | 2022-05-25 12:35:53 +0200 |
commit | e85459dcd12b6fd683d94f088d65a22c9c1320a4 (patch) | |
tree | 9edb221deedf9e7b38cccd4185baf15f746cac03 /servers/rendering/renderer_rd/shaders/volumetric_fog.glsl | |
parent | 1c99b7415fcfd3a9128c7d2ac70f77477fe55c78 (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.glsl | 23 |
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 |