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/effects/copy.glsl26
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl2
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl58
-rw-r--r--servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl21
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/gi.glsl6
-rw-r--r--servers/rendering/renderer_rd/shaders/environment/sky.glsl61
-rw-r--r--servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl8
-rw-r--r--servers/rendering/renderer_rd/shaders/particles.glsl13
-rw-r--r--servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl3
9 files changed, 123 insertions, 75 deletions
diff --git a/servers/rendering/renderer_rd/shaders/effects/copy.glsl b/servers/rendering/renderer_rd/shaders/effects/copy.glsl
index 5cc2ed7622..3a82861057 100644
--- a/servers/rendering/renderer_rd/shaders/effects/copy.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/copy.glsl
@@ -14,8 +14,7 @@ layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
#define FLAG_FLIP_Y (1 << 5)
#define FLAG_FORCE_LUMINANCE (1 << 6)
#define FLAG_COPY_ALL_SOURCE (1 << 7)
-#define FLAG_HIGH_QUALITY_GLOW (1 << 8)
-#define FLAG_ALPHA_TO_ONE (1 << 9)
+#define FLAG_ALPHA_TO_ONE (1 << 8)
layout(push_constant, std430) uniform Params {
ivec4 section;
@@ -93,25 +92,14 @@ void main() {
#ifdef MODE_GAUSSIAN_BLUR
// First pass copy texture into 16x16 local memory for every 8x8 thread block
- vec2 quad_center_uv = clamp(vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
+ vec2 quad_center_uv = clamp(vec2(params.section.xy + gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.5) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
uint dest_index = gl_LocalInvocationID.x * 2 + gl_LocalInvocationID.y * 2 * 16;
-#ifdef MODE_GLOW
- if (bool(params.flags & FLAG_HIGH_QUALITY_GLOW)) {
- vec2 quad_offset_uv = clamp((vec2(gl_GlobalInvocationID.xy + gl_LocalInvocationID.xy - 3.0)) / params.section.zw, vec2(0.5 / params.section.zw), vec2(1.0 - 1.5 / params.section.zw));
-
- local_cache[dest_index] = (textureLod(source_color, quad_center_uv, 0) + textureLod(source_color, quad_offset_uv, 0)) * 0.5;
- local_cache[dest_index + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.z, 0.0), 0)) * 0.5;
- local_cache[dest_index + 16] = (textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0) + textureLod(source_color, quad_offset_uv + vec2(0.0, 1.0 / params.section.w), 0)) * 0.5;
- local_cache[dest_index + 16 + 1] = (textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0) + textureLod(source_color, quad_offset_uv + vec2(1.0 / params.section.zw), 0)) * 0.5;
- } else
-#endif
- {
- local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0);
- local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0);
- local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0);
- local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0);
- }
+ local_cache[dest_index] = textureLod(source_color, quad_center_uv, 0);
+ local_cache[dest_index + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.z, 0.0), 0);
+ local_cache[dest_index + 16] = textureLod(source_color, quad_center_uv + vec2(0.0, 1.0 / params.section.w), 0);
+ local_cache[dest_index + 16 + 1] = textureLod(source_color, quad_center_uv + vec2(1.0 / params.section.zw), 0);
+
#ifdef MODE_GLOW
if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
// Tonemap initial samples to reduce weight of fireflies: https://graphicrants.blogspot.com/2013/12/tone-mapping.html
diff --git a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
index 46bb99794d..6137224162 100644
--- a/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/copy_to_fb.glsl
@@ -88,6 +88,7 @@ layout(push_constant, std430) uniform Params {
}
params;
+#ifndef MODE_SET_COLOR
#ifdef MULTIVIEW
layout(location = 0) in vec3 uv_interp;
#else
@@ -106,6 +107,7 @@ layout(set = 0, binding = 0) uniform sampler2D source_color;
layout(set = 1, binding = 0) uniform sampler2D source_color2;
#endif /* MODE_TWO_SOURCES */
#endif /* MULTIVIEW */
+#endif /* !SET_COLOR */
layout(location = 0) out vec4 frag_color;
diff --git a/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl b/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl
index c8eb78a2f0..221e97bece 100644
--- a/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl
@@ -1,32 +1,32 @@
-/*************************************************************************/
-/* fsr_upscale.glsl */
-/*************************************************************************/
-/* This file is part of: */
-/* GODOT ENGINE */
-/* https://godotengine.org */
-/*************************************************************************/
-/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
-/* */
-/* Permission is hereby granted, free of charge, to any person obtaining */
-/* a copy of this software and associated documentation files (the */
-/* "Software"), to deal in the Software without restriction, including */
-/* without limitation the rights to use, copy, modify, merge, publish, */
-/* distribute, sublicense, and/or sell copies of the Software, and to */
-/* permit persons to whom the Software is furnished to do so, subject to */
-/* the following conditions: */
-/* */
-/* The above copyright notice and this permission notice shall be */
-/* included in all copies or substantial portions of the Software. */
-/* */
-/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
-/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
-/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
-/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
-/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
-/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
-/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
-/*************************************************************************/
+/**************************************************************************/
+/* fsr_upscale.glsl */
+/**************************************************************************/
+/* This file is part of: */
+/* GODOT ENGINE */
+/* https://godotengine.org */
+/**************************************************************************/
+/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
+/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
+/* */
+/* Permission is hereby granted, free of charge, to any person obtaining */
+/* a copy of this software and associated documentation files (the */
+/* "Software"), to deal in the Software without restriction, including */
+/* without limitation the rights to use, copy, modify, merge, publish, */
+/* distribute, sublicense, and/or sell copies of the Software, and to */
+/* permit persons to whom the Software is furnished to do so, subject to */
+/* the following conditions: */
+/* */
+/* The above copyright notice and this permission notice shall be */
+/* included in all copies or substantial portions of the Software. */
+/* */
+/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
+/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
+/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
+/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
+/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
+/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
+/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
+/**************************************************************************/
#[compute]
diff --git a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
index 9d8294a7da..631d1968b0 100644
--- a/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
+++ b/servers/rendering/renderer_rd/shaders/effects/screen_space_reflection.glsl
@@ -66,6 +66,19 @@ void main() {
vec4 normal_roughness = imageLoad(source_normal_roughness, ssC);
vec3 normal = normal_roughness.xyz * 2.0 - 1.0;
+ float roughness = normal_roughness.w;
+
+ // The roughness cutoff of 0.6 is chosen to match the roughness fadeout from GH-69828.
+ if (roughness > 0.6) {
+ // Do not compute SSR for rough materials to improve performance at the cost of
+ // subtle artifacting.
+#ifdef MODE_ROUGH
+ imageStore(blur_radius_image, ssC, vec4(0.0));
+#endif
+ imageStore(ssr_image, ssC, vec4(0.0));
+ return;
+ }
+
normal = normalize(normal);
normal.y = -normal.y; //because this code reads flipped
@@ -81,8 +94,6 @@ void main() {
imageStore(ssr_image, ssC, vec4(0.0));
return;
}
- //ray_dir = normalize(view_dir - normal * dot(normal,view_dir) * 2.0);
- //ray_dir = normalize(vec3(1.0, 1.0, -1.0));
////////////////
@@ -212,6 +223,9 @@ void main() {
float grad = (steps_taken + 1.0) / float(params.num_steps);
float initial_fade = params.curve_fade_in == 0.0 ? 1.0 : pow(clamp(grad, 0.0, 1.0), params.curve_fade_in);
float fade = pow(clamp(1.0 - grad, 0.0, 1.0), params.distance_fade) * initial_fade;
+ // This is an ad-hoc term to fade out the SSR as roughness increases. Values used
+ // are meant to match the visual appearance of a ReflectionProbe.
+ float roughness_fade = smoothstep(0.4, 0.7, 1.0 - normal_roughness.w);
final_pos = pos;
vec4 final_color;
@@ -220,7 +234,6 @@ void main() {
// if roughness is enabled, do screen space cone tracing
float blur_radius = 0.0;
- float roughness = normal_roughness.w;
if (roughness > 0.001) {
float cone_angle = min(roughness, 0.999) * M_PI * 0.5;
@@ -246,7 +259,7 @@ void main() {
#endif // MODE_ROUGH
- final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend);
+ final_color = vec4(imageLoad(source_diffuse, ivec2(final_pos - 0.5)).rgb, fade * margin_blend * roughness_fade);
// Schlick term.
float metallic = texelFetch(source_metallic, ssC << 1, 0).w;
diff --git a/servers/rendering/renderer_rd/shaders/environment/gi.glsl b/servers/rendering/renderer_rd/shaders/environment/gi.glsl
index ab927df678..459c4dcb1d 100644
--- a/servers/rendering/renderer_rd/shaders/environment/gi.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/gi.glsl
@@ -108,7 +108,9 @@ layout(set = 0, binding = 18, std140) uniform SceneData {
}
scene_data;
+#ifdef USE_VRS
layout(r8ui, set = 0, binding = 19) uniform restrict readonly uimage2D vrs_buffer;
+#endif
layout(push_constant, std430) uniform Params {
uint max_voxel_gi_instances;
@@ -661,6 +663,7 @@ void main() {
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
uint vrs_x, vrs_y;
+#ifdef USE_VRS
if (sc_use_vrs) {
ivec2 vrs_pos;
@@ -684,6 +687,7 @@ void main() {
return;
}
}
+#endif
if (sc_half_res) {
pos <<= 1;
@@ -708,6 +712,7 @@ void main() {
imageStore(ambient_buffer, pos, ambient_light);
imageStore(reflection_buffer, pos, reflection_light);
+#ifdef USE_VRS
if (sc_use_vrs) {
if (vrs_x > 1) {
imageStore(ambient_buffer, pos + ivec2(1, 0), ambient_light);
@@ -766,4 +771,5 @@ void main() {
imageStore(reflection_buffer, pos + ivec2(3, 3), reflection_light);
}
}
+#endif
}
diff --git a/servers/rendering/renderer_rd/shaders/environment/sky.glsl b/servers/rendering/renderer_rd/shaders/environment/sky.glsl
index d523461600..bf974a3fd5 100644
--- a/servers/rendering/renderer_rd/shaders/environment/sky.glsl
+++ b/servers/rendering/renderer_rd/shaders/environment/sky.glsl
@@ -14,7 +14,7 @@ layout(location = 0) out vec2 uv_interp;
layout(push_constant, std430) uniform Params {
mat3 orientation;
- vec4 projections[MAX_VIEWS];
+ vec4 projection; // only applicable if not multiview
vec3 position;
float time;
vec3 pad;
@@ -54,7 +54,7 @@ layout(location = 0) in vec2 uv_interp;
layout(push_constant, std430) uniform Params {
mat3 orientation;
- vec4 projections[MAX_VIEWS];
+ vec4 projection; // only applicable if not multiview
vec3 position;
float time;
vec3 pad;
@@ -82,7 +82,10 @@ layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalShaderUnifor
}
global_shader_uniforms;
-layout(set = 0, binding = 2, std140) uniform SceneData {
+layout(set = 0, binding = 2, std140) uniform SkySceneData {
+ mat4 view_inv_projections[2];
+ vec4 view_eye_offsets[2];
+
bool volumetric_fog_enabled; // 4 - 4
float volumetric_fog_inv_length; // 4 - 8
float volumetric_fog_detail_spread; // 4 - 12
@@ -101,7 +104,7 @@ layout(set = 0, binding = 2, std140) uniform SceneData {
uint pad1; // 4 - 60
uint pad2; // 4 - 64
}
-scene_data;
+sky_scene_data;
struct DirectionalLightData {
vec4 direction_energy;
@@ -124,6 +127,9 @@ layout(set = 2, binding = 0) uniform textureCube radiance;
#ifdef USE_CUBEMAP_PASS
layout(set = 2, binding = 1) uniform textureCube half_res;
layout(set = 2, binding = 2) uniform textureCube quarter_res;
+#elif defined(USE_MULTIVIEW)
+layout(set = 2, binding = 1) uniform texture2DArray half_res;
+layout(set = 2, binding = 2) uniform texture2DArray quarter_res;
#else
layout(set = 2, binding = 1) uniform texture2D half_res;
layout(set = 2, binding = 2) uniform texture2D quarter_res;
@@ -169,15 +175,15 @@ vec4 volumetric_fog_process(vec2 screen_uv) {
}
vec4 fog_process(vec3 view, vec3 sky_color) {
- vec3 fog_color = mix(scene_data.fog_light_color, sky_color, scene_data.fog_aerial_perspective);
+ vec3 fog_color = mix(sky_scene_data.fog_light_color, sky_color, sky_scene_data.fog_aerial_perspective);
- if (scene_data.fog_sun_scatter > 0.001) {
+ if (sky_scene_data.fog_sun_scatter > 0.001) {
vec4 sun_scatter = vec4(0.0);
float sun_total = 0.0;
- for (uint i = 0; i < scene_data.directional_light_count; i++) {
+ for (uint i = 0; i < sky_scene_data.directional_light_count; i++) {
vec3 light_color = directional_lights.data[i].color_size.xyz * directional_lights.data[i].direction_energy.w;
float light_amount = pow(max(dot(view, directional_lights.data[i].direction_energy.xyz), 0.0), 8.0);
- fog_color += light_color * light_amount * scene_data.fog_sun_scatter;
+ fog_color += light_color * light_amount * sky_scene_data.fog_sun_scatter;
}
}
@@ -186,9 +192,17 @@ vec4 fog_process(vec3 view, vec3 sky_color) {
void main() {
vec3 cube_normal;
+#ifdef USE_MULTIVIEW
+ // In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject.
+ vec4 unproject = vec4(uv_interp.x, -uv_interp.y, 1.0, 1.0);
+ vec4 unprojected = sky_scene_data.view_inv_projections[ViewIndex] * unproject;
+ cube_normal = unprojected.xyz / unprojected.w;
+ cube_normal += sky_scene_data.view_eye_offsets[ViewIndex].xyz;
+#else
cube_normal.z = -1.0;
- cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projections[ViewIndex].x)) / params.projections[ViewIndex].y;
- cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projections[ViewIndex].z)) / params.projections[ViewIndex].w;
+ cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projection.x)) / params.projection.y;
+ cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projection.z)) / params.projection.w;
+#endif
cube_normal = mat3(params.orientation) * cube_normal;
cube_normal = normalize(cube_normal);
@@ -209,20 +223,33 @@ void main() {
vec4 custom_fog = vec4(0.0);
#ifdef USE_CUBEMAP_PASS
+
#ifdef USES_HALF_RES_COLOR
half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) / params.luminance_multiplier;
#endif
#ifdef USES_QUARTER_RES_COLOR
quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) / params.luminance_multiplier;
#endif
+
#else
+
#ifdef USES_HALF_RES_COLOR
+#ifdef USE_MULTIVIEW
+ half_res_color = textureLod(sampler2DArray(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0) / params.luminance_multiplier;
+#else
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) / params.luminance_multiplier;
-#endif
+#endif // USE_MULTIVIEW
+#endif // USES_HALF_RES_COLOR
+
#ifdef USES_QUARTER_RES_COLOR
+#ifdef USE_MULTIVIEW
+ quarter_res_color = textureLod(sampler2DArray(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0) / params.luminance_multiplier;
+#else
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) / params.luminance_multiplier;
-#endif
-#endif
+#endif // USE_MULTIVIEW
+#endif // USES_QUARTER_RES_COLOR
+
+#endif //USE_CUBEMAP_PASS
{
@@ -236,14 +263,14 @@ void main() {
#if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
- if (scene_data.fog_enabled) {
+ if (sky_scene_data.fog_enabled) {
vec4 fog = fog_process(cube_normal, frag_color.rgb);
- frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.fog_sky_affect);
+ frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * sky_scene_data.fog_sky_affect);
}
- if (scene_data.volumetric_fog_enabled) {
+ if (sky_scene_data.volumetric_fog_enabled) {
vec4 fog = volumetric_fog_process(uv);
- frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.volumetric_fog_sky_affect);
+ frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * sky_scene_data.volumetric_fog_sky_affect);
}
if (custom_fog.a > 0.0) {
diff --git a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
index b45c68db5a..5e64d4e651 100644
--- a/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
+++ b/servers/rendering/renderer_rd/shaders/forward_mobile/scene_forward_mobile.glsl
@@ -866,7 +866,7 @@ void main() {
uint decal_indices = draw_call.decals.x;
for (uint i = 0; i < 8; i++) {
uint decal_index = decal_indices & 0xFF;
- if (i == 4) {
+ if (i == 3) {
decal_indices = draw_call.decals.y;
} else {
decal_indices = decal_indices >> 8;
@@ -1148,7 +1148,7 @@ void main() {
for (uint i = 0; i < 8; i++) {
uint reflection_index = reflection_indices & 0xFF;
- if (i == 4) {
+ if (i == 3) {
reflection_indices = draw_call.reflection_probes.y;
} else {
reflection_indices = reflection_indices >> 8;
@@ -1551,7 +1551,7 @@ void main() {
uint light_indices = draw_call.omni_lights.x;
for (uint i = 0; i < 8; i++) {
uint light_index = light_indices & 0xFF;
- if (i == 4) {
+ if (i == 3) {
light_indices = draw_call.omni_lights.y;
} else {
light_indices = light_indices >> 8;
@@ -1596,7 +1596,7 @@ void main() {
uint light_indices = draw_call.spot_lights.x;
for (uint i = 0; i < 8; i++) {
uint light_index = light_indices & 0xFF;
- if (i == 4) {
+ if (i == 3) {
light_indices = draw_call.spot_lights.y;
} else {
light_indices = light_indices >> 8;
diff --git a/servers/rendering/renderer_rd/shaders/particles.glsl b/servers/rendering/renderer_rd/shaders/particles.glsl
index 9f6aa7adc0..a609076e2c 100644
--- a/servers/rendering/renderer_rd/shaders/particles.glsl
+++ b/servers/rendering/renderer_rd/shaders/particles.glsl
@@ -243,8 +243,14 @@ void main() {
if (params.trail_size > 1) {
if (params.trail_pass) {
+ if (particle >= params.total_particles * (params.trail_size - 1)) {
+ return;
+ }
particle += (particle / (params.trail_size - 1)) + 1;
} else {
+ if (particle >= params.total_particles) {
+ return;
+ }
particle *= params.trail_size;
}
}
@@ -298,12 +304,17 @@ void main() {
PARTICLE.flags = PARTICLE_FLAG_TRAILED | ((frame_history.data[0].frame & PARTICLE_FRAME_MASK) << PARTICLE_FRAME_SHIFT); //mark it as trailed, save in which frame it will start
PARTICLE.xform = particles.data[src_idx].xform;
}
-
+ if (!bool(particles.data[src_idx].flags & PARTICLE_FLAG_ACTIVE)) {
+ // Disable the entire trail if the parent is no longer active.
+ PARTICLE.flags = 0;
+ return;
+ }
if (bool(PARTICLE.flags & PARTICLE_FLAG_TRAILED) && ((PARTICLE.flags >> PARTICLE_FRAME_SHIFT) == (FRAME.frame & PARTICLE_FRAME_MASK))) { //check this is trailed and see if it should start now
// we just assume that this is the first frame of the particle, the rest is deterministic
PARTICLE.flags = PARTICLE_FLAG_ACTIVE | (particles.data[src_idx].flags & (PARTICLE_FRAME_MASK << PARTICLE_FRAME_SHIFT));
return; //- this appears like it should be correct, but it seems not to be.. wonder why.
}
+
} else {
PARTICLE.flags &= ~PARTICLE_FLAG_STARTED;
}
diff --git a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
index ba31b9c6dd..b30b0c8169 100644
--- a/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
+++ b/servers/rendering/renderer_rd/shaders/scene_forward_lights_inc.glsl
@@ -134,7 +134,8 @@ void light_compute(vec3 N, vec3 L, vec3 V, float A, vec3 light_color, float atte
#endif
#if defined(LIGHT_RIM_USED)
- float rim_light = pow(max(0.0, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
+ // Epsilon min to prevent pow(0, 0) singularity which results in undefined behavior.
+ float rim_light = pow(max(1e-4, 1.0 - cNdotV), max(0.0, (1.0 - roughness) * 16.0));
diffuse_light += rim_light * rim * mix(vec3(1.0), albedo, rim_tint) * light_color;
#endif