From 43b0702a0266a823ae42d0c048a6d6baeaceaa06 Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Tue, 21 Mar 2023 12:18:15 +0300 Subject: [PATCH] Fix "Light Only" mode of `CanvasItemMaterial` --- drivers/gles3/rasterizer_canvas_gles3.cpp | 4 ++-- drivers/gles3/shaders/canvas.glsl | 12 +++++++++++- .../renderer_rd/renderer_canvas_render_rd.cpp | 4 ++-- servers/rendering/renderer_rd/shaders/canvas.glsl | 12 +++++++++++- 4 files changed, 26 insertions(+), 6 deletions(-) diff --git a/drivers/gles3/rasterizer_canvas_gles3.cpp b/drivers/gles3/rasterizer_canvas_gles3.cpp index 19f2cfd47dc6..5d3e8ad39dd7 100644 --- a/drivers/gles3/rasterizer_canvas_gles3.cpp +++ b/drivers/gles3/rasterizer_canvas_gles3.cpp @@ -175,7 +175,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ state.light_uniforms[index].color[i] = l->color[i]; } - state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate + state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate if (state.shadow_fb != 0) { state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth); @@ -238,7 +238,7 @@ void RasterizerCanvasGLES3::canvas_render_items(RID p_to_render_target, Item *p_ state.light_uniforms[index].color[i] = l->color[i]; } - state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate + state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate if (state.shadow_fb != 0) { state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth); diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl index ae3892fb61a1..e47e3ae9a32b 100644 --- a/drivers/gles3/shaders/canvas.glsl +++ b/drivers/gles3/shaders/canvas.glsl @@ -648,7 +648,7 @@ void main() { vec4 base_color = color; #ifdef MODE_LIGHT_ONLY - color = vec4(0.0); + float light_only_alpha = 0.0; #elif !defined(MODE_UNSHADED) color *= canvas_modulation; #endif @@ -691,6 +691,9 @@ void main() { } light_blend_compute(light_base, light_color, color.rgb); +#ifdef MODE_LIGHT_ONLY + light_only_alpha += light_color.a; +#endif } // Positional Lights @@ -788,8 +791,15 @@ void main() { } light_blend_compute(light_base, light_color, color.rgb); +#ifdef MODE_LIGHT_ONLY + light_only_alpha += light_color.a; +#endif } #endif +#ifdef MODE_LIGHT_ONLY + color.a *= light_only_alpha; +#endif + frag_color = color; } diff --git a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp index 5c6f630355ce..f14e54cd2a4d 100644 --- a/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp +++ b/servers/rendering/renderer_rd/renderer_canvas_render_rd.cpp @@ -1202,7 +1202,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p state.light_uniforms[index].color[i] = l->color[i]; } - state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate + state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate if (state.shadow_fb.is_valid()) { state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth); @@ -1264,7 +1264,7 @@ void RendererCanvasRenderRD::canvas_render_items(RID p_to_render_target, Item *p state.light_uniforms[index].color[i] = l->color[i]; } - state.light_uniforms[index].color[3] = l->energy; //use alpha for energy, so base color can go separate + state.light_uniforms[index].color[3] *= l->energy; //use alpha for energy, so base color can go separate if (state.shadow_fb.is_valid()) { state.light_uniforms[index].shadow_pixel_size = (1.0 / state.shadow_texture_size) * (1.0 + l->shadow_smooth); diff --git a/servers/rendering/renderer_rd/shaders/canvas.glsl b/servers/rendering/renderer_rd/shaders/canvas.glsl index c96524b5c93e..7deeacf86ec0 100644 --- a/servers/rendering/renderer_rd/shaders/canvas.glsl +++ b/servers/rendering/renderer_rd/shaders/canvas.glsl @@ -568,7 +568,7 @@ void main() { } #ifdef MODE_LIGHT_ONLY - color = vec4(0.0); + float light_only_alpha = 0.0; #elif !defined(MODE_UNSHADED) color *= canvas_data.canvas_modulation; #endif @@ -611,6 +611,9 @@ void main() { } light_blend_compute(light_base, light_color, color.rgb); +#ifdef MODE_LIGHT_ONLY + light_only_alpha += light_color.a; +#endif } // Positional Lights @@ -695,8 +698,15 @@ void main() { } light_blend_compute(light_base, light_color, color.rgb); +#ifdef MODE_LIGHT_ONLY + light_only_alpha += light_color.a; +#endif } #endif +#ifdef MODE_LIGHT_ONLY + color.a *= light_only_alpha; +#endif + frag_color = color; }