summaryrefslogtreecommitdiff
path: root/servers/rendering/renderer_rd/shaders
diff options
context:
space:
mode:
Diffstat (limited to 'servers/rendering/renderer_rd/shaders')
-rw-r--r--servers/rendering/renderer_rd/shaders/SCsub1
-rw-r--r--servers/rendering/renderer_rd/shaders/gi.glsl85
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe.glsl14
-rw-r--r--servers/rendering/renderer_rd/shaders/giprobe_write.glsl14
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl19
-rw-r--r--servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl34
-rw-r--r--servers/rendering/renderer_rd/shaders/shadow_reduce.glsl163
-rw-r--r--servers/rendering/renderer_rd/shaders/volumetric_fog.glsl24
8 files changed, 104 insertions, 250 deletions
diff --git a/servers/rendering/renderer_rd/shaders/SCsub b/servers/rendering/renderer_rd/shaders/SCsub
index 1b0197c1c1..c192574ff2 100644
--- a/servers/rendering/renderer_rd/shaders/SCsub
+++ b/servers/rendering/renderer_rd/shaders/SCsub
@@ -39,7 +39,6 @@ if "RD_GLSL" in env["BUILDERS"]:
env.RD_GLSL("sdfgi_debug.glsl")
env.RD_GLSL("sdfgi_debug_probes.glsl")
env.RD_GLSL("volumetric_fog.glsl")
- env.RD_GLSL("shadow_reduce.glsl")
env.RD_GLSL("particles.glsl")
env.RD_GLSL("particles_copy.glsl")
env.RD_GLSL("sort.glsl")
diff --git a/servers/rendering/renderer_rd/shaders/gi.glsl b/servers/rendering/renderer_rd/shaders/gi.glsl
index 35522103df..92a5682572 100644
--- a/servers/rendering/renderer_rd/shaders/gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/gi.glsl
@@ -363,57 +363,62 @@ void sdfgi_process(vec3 vertex, vec3 normal, vec3 reflection, float roughness, o
ray_pos += (ray_dir * 1.0 / max(abs_ray_dir.x, max(abs_ray_dir.y, abs_ray_dir.z)) + cam_normal * 1.4) * bias / sdfgi.cascades[cascade].to_cell;
}
float softness = 0.2 + min(1.0, roughness * 5.0) * 4.0; //approximation to roughness so it does not seem like a hard fade
- while (length(ray_pos) < max_distance) {
- for (uint i = 0; i < sdfgi.max_cascades; i++) {
- if (i >= cascade && length(ray_pos) < radius_sizes[i]) {
- cascade = max(i, cascade); //never go down
-
- vec3 pos = ray_pos - sdfgi.cascades[i].position;
- pos *= sdfgi.cascades[i].to_cell * pos_to_uvw;
-
- float distance = texture(sampler3D(sdf_cascades[i], linear_sampler), pos).r * 255.0 - 1.1;
-
- vec4 hit_light = vec4(0.0);
- if (distance < softness) {
- hit_light.rgb = texture(sampler3D(light_cascades[i], linear_sampler), pos).rgb;
- hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
- hit_light.a = clamp(1.0 - (distance / softness), 0.0, 1.0);
- hit_light.rgb *= hit_light.a;
- }
+ uint i = 0;
+ bool found = false;
+ while (true) {
+ if (length(ray_pos) >= max_distance || light_accum.a > 0.99) {
+ break;
+ }
+ if (!found && i >= cascade && length(ray_pos) < radius_sizes[i]) {
+ uint next_i = min(i + 1, sdfgi.max_cascades - 1);
+ cascade = max(i, cascade); //never go down
- distance /= sdfgi.cascades[i].to_cell;
+ vec3 pos = ray_pos - sdfgi.cascades[i].position;
+ pos *= sdfgi.cascades[i].to_cell * pos_to_uvw;
- if (i < (sdfgi.max_cascades - 1)) {
- pos = ray_pos - sdfgi.cascades[i + 1].position;
- pos *= sdfgi.cascades[i + 1].to_cell * pos_to_uvw;
+ float fdistance = textureLod(sampler3D(sdf_cascades[i], linear_sampler), pos, 0.0).r * 255.0 - 1.1;
- float distance2 = texture(sampler3D(sdf_cascades[i + 1], linear_sampler), pos).r * 255.0 - 1.1;
+ vec4 hit_light = vec4(0.0);
+ if (fdistance < softness) {
+ hit_light.rgb = textureLod(sampler3D(light_cascades[i], linear_sampler), pos, 0.0).rgb;
+ hit_light.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
+ hit_light.a = clamp(1.0 - (fdistance / softness), 0.0, 1.0);
+ hit_light.rgb *= hit_light.a;
+ }
- vec4 hit_light2 = vec4(0.0);
- if (distance2 < softness) {
- hit_light2.rgb = texture(sampler3D(light_cascades[i + 1], linear_sampler), pos).rgb;
- hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
- hit_light2.a = clamp(1.0 - (distance2 / softness), 0.0, 1.0);
- hit_light2.rgb *= hit_light2.a;
- }
+ fdistance /= sdfgi.cascades[i].to_cell;
- float prev_radius = i == 0 ? 0.0 : radius_sizes[i - 1];
- float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0);
+ if (i < (sdfgi.max_cascades - 1)) {
+ pos = ray_pos - sdfgi.cascades[next_i].position;
+ pos *= sdfgi.cascades[next_i].to_cell * pos_to_uvw;
- distance2 /= sdfgi.cascades[i + 1].to_cell;
+ float fdistance2 = textureLod(sampler3D(sdf_cascades[next_i], linear_sampler), pos, 0.0).r * 255.0 - 1.1;
- hit_light = mix(hit_light, hit_light2, blend);
- distance = mix(distance, distance2, blend);
+ vec4 hit_light2 = vec4(0.0);
+ if (fdistance2 < softness) {
+ hit_light2.rgb = textureLod(sampler3D(light_cascades[next_i], linear_sampler), pos, 0.0).rgb;
+ hit_light2.rgb *= 0.5; //approximation given value read is actually meant for anisotropy
+ hit_light2.a = clamp(1.0 - (fdistance2 / softness), 0.0, 1.0);
+ hit_light2.rgb *= hit_light2.a;
}
- light_accum += hit_light;
- ray_pos += ray_dir * distance;
- break;
+ float prev_radius = i == 0 ? 0.0 : radius_sizes[max(0, i - 1)];
+ float blend = clamp((length(ray_pos) - prev_radius) / (radius_sizes[i] - prev_radius), 0.0, 1.0);
+
+ fdistance2 /= sdfgi.cascades[next_i].to_cell;
+
+ hit_light = mix(hit_light, hit_light2, blend);
+ fdistance = mix(fdistance, fdistance2, blend);
}
- }
- if (light_accum.a > 0.99) {
- break;
+ light_accum += hit_light;
+ ray_pos += ray_dir * fdistance;
+ found = true;
+ }
+ i++;
+ if (i == sdfgi.max_cascades) {
+ i = 0;
+ found = false;
}
}
diff --git a/servers/rendering/renderer_rd/shaders/giprobe.glsl b/servers/rendering/renderer_rd/shaders/giprobe.glsl
index 4f4753d147..b931461b31 100644
--- a/servers/rendering/renderer_rd/shaders/giprobe.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe.glsl
@@ -51,10 +51,10 @@ struct Light {
float attenuation;
vec3 color;
- float spot_angle_radians;
+ float cos_spot_angle;
vec3 position;
- float spot_attenuation;
+ float inv_spot_attenuation;
vec3 direction;
bool has_shadow;
@@ -233,13 +233,15 @@ bool compute_light_vector(uint light, vec3 pos, out float attenuation, out vec3
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
vec3 rel = normalize(pos - light_pos);
- float angle = acos(dot(rel, lights.data[light].direction));
- if (angle > lights.data[light].spot_angle_radians) {
+ float cos_spot_angle = lights.data[light].cos_spot_angle;
+ float cos_angle = dot(rel, lights.data[light].direction);
+ if (cos_angle < cos_spot_angle) {
return false;
}
- float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1);
- attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation);
+ float scos = max(cos_angle, cos_spot_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
+ attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation);
}
}
diff --git a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
index 9c794f1bcc..56b3b7ccb4 100644
--- a/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
+++ b/servers/rendering/renderer_rd/shaders/giprobe_write.glsl
@@ -43,10 +43,10 @@ struct Light {
float attenuation;
vec3 color;
- float spot_angle_radians;
+ float cos_spot_angle;
vec3 position;
- float spot_attenuation;
+ float inv_spot_attenuation;
vec3 direction;
bool has_shadow;
@@ -146,13 +146,15 @@ bool compute_light_vector(uint light, uint cell, vec3 pos, out float attenuation
if (lights.data[light].type == LIGHT_TYPE_SPOT) {
vec3 rel = normalize(pos - light_pos);
- float angle = acos(dot(rel, lights.data[light].direction));
- if (angle > lights.data[light].spot_angle_radians) {
+ float cos_spot_angle = lights.data[light].cos_spot_angle;
+ float cos_angle = dot(rel, lights.data[light].direction);
+ if (cos_angle < cos_spot_angle) {
return false;
}
- float d = clamp(angle / lights.data[light].spot_angle_radians, 0, 1);
- attenuation *= pow(1.0 - d, lights.data[light].spot_attenuation);
+ float scos = max(cos_angle, cos_spot_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
+ attenuation *= 1.0 - pow(spot_rim, lights.data[light].inv_spot_attenuation);
}
}
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
index bcdfe8cc85..5e8934adb4 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_direct_light.glsl
@@ -67,8 +67,8 @@ struct Light {
float attenuation;
uint type;
- float spot_angle;
- float spot_attenuation;
+ float cos_spot_angle;
+ float inv_spot_attenuation;
float radius;
vec4 shadow_color;
@@ -266,13 +266,16 @@ void main() {
rel_vec.y /= params.y_mult;
attenuation = get_omni_attenuation(light_distance, 1.0 / lights.data[i].radius, lights.data[i].attenuation);
- float angle = acos(dot(normalize(rel_vec), -lights.data[i].direction));
- if (angle > lights.data[i].spot_angle) {
- attenuation = 0.0;
- } else {
- float d = clamp(angle / lights.data[i].spot_angle, 0, 1);
- attenuation *= pow(1.0 - d, lights.data[i].spot_attenuation);
+ float cos_spot_angle = lights.data[i].cos_spot_angle;
+ float cos_angle = dot(-direction, lights.data[i].direction);
+
+ if (cos_angle < cos_spot_angle) {
+ continue;
}
+
+ float scos = max(cos_angle, cos_spot_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - cos_spot_angle));
+ attenuation *= 1.0 - pow(spot_rim, lights.data[i].inv_spot_attenuation);
} break;
}
diff --git a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl
index e4f6f4b7ea..007e4c113a 100644
--- a/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl
+++ b/servers/rendering/renderer_rd/shaders/sdfgi_integrate.glsl
@@ -244,20 +244,26 @@ void main() {
vec4 light;
if (hit) {
- const float EPSILON = 0.001;
- vec3 hit_normal = normalize(vec3(
- texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r,
- texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r,
- texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r));
-
- vec3 hit_light = texture(sampler3D(light_cascades[hit_cascade], linear_sampler), uvw).rgb;
- vec4 aniso0 = texture(sampler3D(aniso0_cascades[hit_cascade], linear_sampler), uvw);
- vec3 hit_aniso0 = aniso0.rgb;
- vec3 hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[hit_cascade], linear_sampler), uvw).rg);
-
- //one liner magic
- light.rgb = hit_light * (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0)));
- light.a = 1.0;
+ //avoid reading different texture from different threads
+ for (uint j = params.cascade; j < params.max_cascades; j++) {
+ if (j == hit_cascade) {
+ const float EPSILON = 0.001;
+ vec3 hit_normal = normalize(vec3(
+ texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(EPSILON, 0.0, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(EPSILON, 0.0, 0.0)).r,
+ texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, EPSILON, 0.0)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, EPSILON, 0.0)).r,
+ texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw + vec3(0.0, 0.0, EPSILON)).r - texture(sampler3D(sdf_cascades[hit_cascade], linear_sampler), uvw - vec3(0.0, 0.0, EPSILON)).r));
+
+ vec3 hit_light = texture(sampler3D(light_cascades[hit_cascade], linear_sampler), uvw).rgb;
+ vec4 aniso0 = texture(sampler3D(aniso0_cascades[hit_cascade], linear_sampler), uvw);
+ vec3 hit_aniso0 = aniso0.rgb;
+ vec3 hit_aniso1 = vec3(aniso0.a, texture(sampler3D(aniso1_cascades[hit_cascade], linear_sampler), uvw).rg);
+
+ //one liner magic
+ light.rgb = hit_light * (dot(max(vec3(0.0), (hit_normal * hit_aniso0)), vec3(1.0)) + dot(max(vec3(0.0), (-hit_normal * hit_aniso1)), vec3(1.0)));
+ light.a = 1.0;
+ }
+ }
+
} else if (params.sky_mode == SKY_MODE_SKY) {
#ifdef USE_CUBEMAP_ARRAY
light.rgb = textureLod(samplerCubeArray(sky_irradiance, linear_sampler_mipmaps), vec4(ray_dir, 0.0), 2.0).rgb; //use second mipmap because we dont usually throw a lot of rays, so this compensates
diff --git a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl b/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl
deleted file mode 100644
index a29b24e560..0000000000
--- a/servers/rendering/renderer_rd/shaders/shadow_reduce.glsl
+++ /dev/null
@@ -1,163 +0,0 @@
-#[compute]
-
-#version 450
-
-VERSION_DEFINES
-
-#define BLOCK_SIZE 8
-
-#ifdef MODE_REDUCE_SUBGROUP
-
-#extension GL_KHR_shader_subgroup_ballot : enable
-#extension GL_KHR_shader_subgroup_arithmetic : enable
-
-//nvidia friendly, max 32
-layout(local_size_x = 8, local_size_y = 4, local_size_z = 1) in;
-
-#else
-
-layout(local_size_x = BLOCK_SIZE, local_size_y = BLOCK_SIZE, local_size_z = 1) in;
-
-#endif
-
-#ifdef MODE_REDUCE
-
-shared float tmp_data[BLOCK_SIZE * BLOCK_SIZE];
-const uint swizzle_table[BLOCK_SIZE] = uint[](0, 4, 2, 6, 1, 5, 3, 7);
-const uint unswizzle_table[BLOCK_SIZE] = uint[](0, 0, 0, 1, 0, 2, 1, 3);
-
-#endif
-
-#if defined(MODE_REDUCE) || defined(MODE_REDUCE_SUBGROUP)
-layout(set = 0, binding = 0) uniform sampler2D source_depth;
-#else
-layout(r16, set = 0, binding = 0) uniform restrict readonly image2D source_depth;
-#endif
-layout(r16, set = 1, binding = 0) uniform restrict writeonly image2D dst_depth;
-
-layout(push_constant, binding = 1, std430) uniform Params {
- ivec2 source_size;
- ivec2 source_offset;
- uint min_size;
- uint gaussian_kernel_version;
- ivec2 filter_dir;
-}
-params;
-
-void main() {
-#ifdef MODE_REDUCE_SUBGROUP
-
- uvec2 local_pos = gl_LocalInvocationID.xy;
- ivec2 image_offset = params.source_offset;
- ivec2 image_pos = image_offset + ivec2(gl_GlobalInvocationID.xy * ivec2(1, 2));
-
- float depth = texelFetch(source_depth, min(image_pos, params.source_size - ivec2(1)), 0).r;
- depth += texelFetch(source_depth, min(image_pos + ivec2(0, 1), params.source_size - ivec2(1)), 0).r;
- depth *= 0.5;
-
-#ifdef MODE_REDUCE_8
- //fast version, reduce all
- float depth_average = subgroupAdd(depth) / 32.0;
- if (local_pos == uvec2(0)) {
- imageStore(dst_depth, image_pos / 8, vec4(depth_average));
- }
-#else
- //bit slower version, reduce by regions
- uint group_size = (8 / params.min_size);
- uvec2 group_id = local_pos / (8 / params.min_size);
-
- uvec4 mask;
- float depth_average = 0;
-
- while (true) {
- uvec2 first = subgroupBroadcastFirst(group_id);
- mask = subgroupBallot(first == group_id);
- if (first == group_id) {
- depth_average = subgroupAdd(depth);
- break;
- }
- }
-
- depth_average /= float(group_size * group_size);
-
- if (local_pos == group_id) {
- imageStore(dst_depth, image_pos / int(group_size), vec4(depth_average));
- }
-#endif
-
-#endif
-
-#ifdef MODE_REDUCE
-
- uvec2 pos = gl_LocalInvocationID.xy;
-
- ivec2 image_offset = params.source_offset;
- ivec2 image_pos = image_offset + ivec2(gl_GlobalInvocationID.xy);
- uint dst_t = swizzle_table[pos.y] * BLOCK_SIZE + swizzle_table[pos.x];
- tmp_data[dst_t] = texelFetch(source_depth, min(image_pos, params.source_size - ivec2(1)), 0).r;
- ivec2 image_size = params.source_size;
-
- uint t = pos.y * BLOCK_SIZE + pos.x;
-
- //neighbours
- uint size = BLOCK_SIZE;
-
- do {
- groupMemoryBarrier();
- barrier();
-
- size >>= 1;
- image_size >>= 1;
- image_offset >>= 1;
-
- if (all(lessThan(pos, uvec2(size)))) {
- uint nx = t + size;
- uint ny = t + (BLOCK_SIZE * size);
- uint nxy = ny + size;
-
- tmp_data[t] += tmp_data[nx];
- tmp_data[t] += tmp_data[ny];
- tmp_data[t] += tmp_data[nxy];
- tmp_data[t] /= 4.0;
- }
-
- } while (size > params.min_size);
-
- if (all(lessThan(pos, uvec2(size)))) {
- image_pos = ivec2(unswizzle_table[size + pos.x], unswizzle_table[size + pos.y]);
- image_pos += image_offset + ivec2(gl_WorkGroupID.xy) * int(size);
-
- image_size = max(ivec2(1), image_size); //in case image size became 0
-
- if (all(lessThan(image_pos, uvec2(image_size)))) {
- imageStore(dst_depth, image_pos, vec4(tmp_data[t]));
- }
- }
-#endif
-
-#ifdef MODE_FILTER
-
- ivec2 image_pos = params.source_offset + ivec2(gl_GlobalInvocationID.xy);
- if (any(greaterThanEqual(image_pos, params.source_size))) {
- return;
- }
-
- ivec2 clamp_min = ivec2(params.source_offset);
- ivec2 clamp_max = ivec2(params.source_size) - 1;
-
- //gaussian kernel, size 9, sigma 4
- const int kernel_size = 9;
- const float gaussian_kernel[kernel_size * 3] = float[](
- 0.000229, 0.005977, 0.060598, 0.241732, 0.382928, 0.241732, 0.060598, 0.005977, 0.000229,
- 0.028532, 0.067234, 0.124009, 0.179044, 0.20236, 0.179044, 0.124009, 0.067234, 0.028532,
- 0.081812, 0.101701, 0.118804, 0.130417, 0.134535, 0.130417, 0.118804, 0.101701, 0.081812);
- float accum = 0.0;
- for (int i = 0; i < kernel_size; i++) {
- ivec2 ofs = clamp(image_pos + params.filter_dir * (i - kernel_size / 2), clamp_min, clamp_max);
- accum += imageLoad(source_depth, ofs).r * gaussian_kernel[params.gaussian_kernel_version + i];
- }
-
- imageStore(dst_depth, image_pos, vec4(accum));
-
-#endif
-}
diff --git a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
index 4cbea055fa..e7ba8feb80 100644
--- a/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
+++ b/servers/rendering/renderer_rd/shaders/volumetric_fog.glsl
@@ -497,31 +497,31 @@ void main() {
uint light_index = 32 * i + bit;
- vec3 light_pos = omni_lights.data[light_index].position;
- vec3 light_rel_vec = omni_lights.data[light_index].position - view_pos;
+ vec3 light_pos = spot_lights.data[light_index].position;
+ vec3 light_rel_vec = spot_lights.data[light_index].position - view_pos;
float d = length(light_rel_vec);
float shadow_attenuation = 1.0;
- if (d * omni_lights.data[light_index].inv_radius < 1.0) {
- float attenuation = get_omni_attenuation(d, omni_lights.data[light_index].inv_radius, omni_lights.data[light_index].attenuation);
+ if (d * spot_lights.data[light_index].inv_radius < 1.0) {
+ float attenuation = get_omni_attenuation(d, spot_lights.data[light_index].inv_radius, spot_lights.data[light_index].attenuation);
- vec3 spot_dir = omni_lights.data[light_index].direction;
- float scos = max(dot(-normalize(light_rel_vec), spot_dir), omni_lights.data[light_index].cone_angle);
- float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - omni_lights.data[light_index].cone_angle));
- attenuation *= 1.0 - pow(spot_rim, omni_lights.data[light_index].cone_attenuation);
+ vec3 spot_dir = spot_lights.data[light_index].direction;
+ float scos = max(dot(-normalize(light_rel_vec), spot_dir), spot_lights.data[light_index].cone_angle);
+ float spot_rim = max(0.0001, (1.0 - scos) / (1.0 - spot_lights.data[light_index].cone_angle));
+ attenuation *= 1.0 - pow(spot_rim, spot_lights.data[light_index].cone_attenuation);
- vec3 light = omni_lights.data[light_index].color / M_PI;
+ vec3 light = spot_lights.data[light_index].color / M_PI;
- if (omni_lights.data[light_index].shadow_enabled) {
+ if (spot_lights.data[light_index].shadow_enabled) {
//has shadow
vec4 v = vec4(view_pos, 1.0);
- vec4 splane = (omni_lights.data[light_index].shadow_matrix * v);
+ vec4 splane = (spot_lights.data[light_index].shadow_matrix * v);
splane /= splane.w;
float depth = texture(sampler2D(shadow_atlas, linear_sampler), splane.xy).r;
- shadow_attenuation = exp(min(0.0, (depth - splane.z)) / omni_lights.data[light_index].inv_radius * omni_lights.data[light_index].shadow_volumetric_fog_fade);
+ shadow_attenuation = exp(min(0.0, (depth - splane.z)) / spot_lights.data[light_index].inv_radius * spot_lights.data[light_index].shadow_volumetric_fog_fade);
}
total_light += light * attenuation * shadow_attenuation;