Skip to content

Commit 2fcd822

Browse files
committedDec 20, 2024
Merge pull request #99538 from Geometror/lightmap-gi-transparent-surface
Add transparency support for LightmapGI
2 parents 0b01f3c + a3525bc commit 2fcd822

26 files changed

+441
-94
lines changed
 

‎doc/classes/ProjectSettings.xml

+3
Original file line numberDiff line numberDiff line change
@@ -2730,6 +2730,9 @@
27302730
<member name="rendering/lightmapping/bake_performance/max_rays_per_probe_pass" type="int" setter="" getter="" default="64">
27312731
The maximum number of rays that can be thrown per pass when baking dynamic object lighting in [LightmapProbe]s with [LightmapGI]. Depending on the scene, adjusting this value may result in higher GPU utilization when baking lightmaps, leading to faster bake times.
27322732
</member>
2733+
<member name="rendering/lightmapping/bake_performance/max_transparency_rays" type="int" setter="" getter="" default="8">
2734+
The maximum number of retry rays that can be thrown per pass when hitting a transparent surface when baking lightmaps with [LightmapGI]. Depending on the scene, reducing this value may lead to faster bake times.
2735+
</member>
27332736
<member name="rendering/lightmapping/bake_performance/region_size" type="int" setter="" getter="" default="512">
27342737
The region size to use when baking lightmaps with [LightmapGI].
27352738
</member>

‎drivers/gles3/rasterizer_scene_gles3.cpp

+16-12
Original file line numberDiff line numberDiff line change
@@ -977,7 +977,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p
977977
glBindFramebuffer(GL_FRAMEBUFFER, sky->radiance_framebuffer);
978978

979979
scene_state.reset_gl_state();
980-
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_DISABLED);
980+
scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);
981981
scene_state.enable_gl_blend(false);
982982

983983
for (int i = 0; i < 6; i++) {
@@ -1000,7 +1000,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p
10001000
} else {
10011001
if (sky_mode == RS::SKY_MODE_INCREMENTAL && sky->processing_layer < max_processing_layer) {
10021002
scene_state.reset_gl_state();
1003-
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_DISABLED);
1003+
scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);
10041004
scene_state.enable_gl_blend(false);
10051005

10061006
cubemap_filter->filter_radiance(sky->raw_radiance, sky->radiance, sky->radiance_framebuffer, sky->radiance_size, sky->mipmap_count, sky->processing_layer);
@@ -1433,6 +1433,10 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
14331433
if (surf->flags & GeometryInstanceSurface::FLAG_PASS_SHADOW) {
14341434
rl->add_element(surf);
14351435
}
1436+
} else if (p_pass_mode == PASS_MODE_MATERIAL) {
1437+
if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE | GeometryInstanceSurface::FLAG_PASS_ALPHA)) {
1438+
rl->add_element(surf);
1439+
}
14361440
} else {
14371441
if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE)) {
14381442
rl->add_element(surf);
@@ -2210,7 +2214,7 @@ void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
22102214
scene_state.enable_gl_depth_test(false);
22112215
scene_state.enable_gl_depth_draw(true);
22122216
glDisable(GL_CULL_FACE);
2213-
scene_state.cull_mode = GLES3::SceneShaderData::CULL_DISABLED;
2217+
scene_state.cull_mode = RS::CULL_MODE_DISABLED;
22142218
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
22152219
}
22162220

@@ -2587,7 +2591,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
25872591
scene_state.enable_gl_depth_draw(false);
25882592
scene_state.enable_gl_depth_test(false);
25892593
scene_state.enable_gl_blend(false);
2590-
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK);
2594+
scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);
25912595

25922596
Ref<CameraFeed> feed = CameraServer::get_singleton()->get_feed_by_id(camera_feed_id);
25932597

@@ -2615,7 +2619,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
26152619

26162620
scene_state.enable_gl_depth_test(true);
26172621
scene_state.enable_gl_blend(false);
2618-
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK);
2622+
scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);
26192623

26202624
Transform3D transform = render_data.cam_transform;
26212625
Projection projection = render_data.cam_projection;
@@ -3099,19 +3103,19 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
30993103
}
31003104

31013105
// Find cull variant.
3102-
GLES3::SceneShaderData::Cull cull_mode = shader->cull_mode;
3106+
RS::CullMode cull_mode = shader->cull_mode;
31033107

31043108
if (p_pass_mode == PASS_MODE_MATERIAL || (surf->flags & GeometryInstanceSurface::FLAG_USES_DOUBLE_SIDED_SHADOWS)) {
3105-
cull_mode = GLES3::SceneShaderData::CULL_DISABLED;
3109+
cull_mode = RS::CULL_MODE_DISABLED;
31063110
} else {
31073111
bool mirror = inst->mirror;
31083112
if (p_params->reverse_cull) {
31093113
mirror = !mirror;
31103114
}
3111-
if (cull_mode == GLES3::SceneShaderData::CULL_FRONT && mirror) {
3112-
cull_mode = GLES3::SceneShaderData::CULL_BACK;
3113-
} else if (cull_mode == GLES3::SceneShaderData::CULL_BACK && mirror) {
3114-
cull_mode = GLES3::SceneShaderData::CULL_FRONT;
3115+
if (cull_mode == RS::CULL_MODE_FRONT && mirror) {
3116+
cull_mode = RS::CULL_MODE_BACK;
3117+
} else if (cull_mode == RS::CULL_MODE_BACK && mirror) {
3118+
cull_mode = RS::CULL_MODE_FRONT;
31153119
}
31163120
}
31173121

@@ -3832,7 +3836,7 @@ void RasterizerSceneGLES3::_render_buffers_debug_draw(Ref<RenderSceneBuffersGLES
38323836
glActiveTexture(GL_TEXTURE0);
38333837
scene_state.enable_gl_depth_draw(true);
38343838
glDepthFunc(GL_ALWAYS);
3835-
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_DISABLED);
3839+
scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);
38363840

38373841
// Loop through quadrants and copy shadows over.
38383842
for (int quadrant = 0; quadrant < 4; quadrant++) {

‎drivers/gles3/rasterizer_scene_gles3.h

+6-6
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,7 @@ class RasterizerSceneGLES3 : public RendererSceneRender {
461461
bool used_depth_prepass = false;
462462

463463
GLES3::SceneShaderData::BlendMode current_blend_mode = GLES3::SceneShaderData::BLEND_MODE_MIX;
464-
GLES3::SceneShaderData::Cull cull_mode = GLES3::SceneShaderData::CULL_BACK;
464+
RS::CullMode cull_mode = RS::CULL_MODE_BACK;
465465

466466
bool current_blend_enabled = false;
467467
bool current_depth_draw_enabled = false;
@@ -477,24 +477,24 @@ class RasterizerSceneGLES3 : public RendererSceneRender {
477477

478478
glCullFace(GL_BACK);
479479
glEnable(GL_CULL_FACE);
480-
cull_mode = GLES3::SceneShaderData::CULL_BACK;
480+
cull_mode = RS::CULL_MODE_BACK;
481481

482482
glDepthMask(GL_FALSE);
483483
current_depth_draw_enabled = false;
484484
glDisable(GL_DEPTH_TEST);
485485
current_depth_test_enabled = false;
486486
}
487487

488-
void set_gl_cull_mode(GLES3::SceneShaderData::Cull p_mode) {
488+
void set_gl_cull_mode(RS::CullMode p_mode) {
489489
if (cull_mode != p_mode) {
490-
if (p_mode == GLES3::SceneShaderData::CULL_DISABLED) {
490+
if (p_mode == RS::CULL_MODE_DISABLED) {
491491
glDisable(GL_CULL_FACE);
492492
} else {
493-
if (cull_mode == GLES3::SceneShaderData::CULL_DISABLED) {
493+
if (cull_mode == RS::CULL_MODE_DISABLED) {
494494
// Last time was disabled, so enable and set proper face.
495495
glEnable(GL_CULL_FACE);
496496
}
497-
glCullFace(p_mode == GLES3::SceneShaderData::CULL_FRONT ? GL_FRONT : GL_BACK);
497+
glCullFace(p_mode == RS::CULL_MODE_FRONT ? GL_FRONT : GL_BACK);
498498
}
499499
cull_mode = p_mode;
500500
}

‎drivers/gles3/shaders/scene.glsl

+16
Original file line numberDiff line numberDiff line change
@@ -1883,10 +1883,18 @@ void main() {
18831883
#ifndef USE_SHADOW_TO_OPACITY
18841884

18851885
#if defined(ALPHA_SCISSOR_USED)
1886+
#ifdef RENDER_MATERIAL
1887+
if (alpha < alpha_scissor_threshold) {
1888+
alpha = 0.0;
1889+
} else {
1890+
alpha = 1.0;
1891+
}
1892+
#else
18861893
if (alpha < alpha_scissor_threshold) {
18871894
discard;
18881895
}
18891896
alpha = 1.0;
1897+
#endif // RENDER_MATERIAL
18901898
#else
18911899
#ifdef MODE_RENDER_DEPTH
18921900
#ifdef USE_OPAQUE_PREPASS
@@ -2216,9 +2224,17 @@ void main() {
22162224
alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));
22172225

22182226
#if defined(ALPHA_SCISSOR_USED)
2227+
#ifdef RENDER_MATERIAL
2228+
if (alpha < alpha_scissor_threshold) {
2229+
alpha = 0.0;
2230+
} else {
2231+
alpha = 1.0;
2232+
}
2233+
#else
22192234
if (alpha < alpha_scissor_threshold) {
22202235
discard;
22212236
}
2237+
#endif // RENDER_MATERIAL
22222238
#endif // !ALPHA_SCISSOR_USED
22232239

22242240
#endif // !MODE_RENDER_DEPTH

‎drivers/gles3/storage/material_storage.cpp

+18-5
Original file line numberDiff line numberDiff line change
@@ -2506,6 +2506,19 @@ bool MaterialStorage::material_casts_shadows(RID p_material) {
25062506
return true; //by default everything casts shadows
25072507
}
25082508

2509+
RS::CullMode MaterialStorage::material_get_cull_mode(RID p_material) const {
2510+
const GLES3::Material *material = material_owner.get_or_null(p_material);
2511+
ERR_FAIL_NULL_V(material, RS::CULL_MODE_DISABLED);
2512+
ERR_FAIL_NULL_V(material->shader, RS::CULL_MODE_DISABLED);
2513+
if (material->shader->data) {
2514+
SceneShaderData *data = dynamic_cast<SceneShaderData *>(material->shader->data);
2515+
if (data) {
2516+
return (RS::CullMode)data->cull_mode;
2517+
}
2518+
}
2519+
return RS::CULL_MODE_DISABLED;
2520+
}
2521+
25092522
void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {
25102523
GLES3::Material *material = material_owner.get_or_null(p_material);
25112524
ERR_FAIL_NULL(material);
@@ -2908,7 +2921,7 @@ void SceneShaderData::set_code(const String &p_code) {
29082921
int blend_modei = BLEND_MODE_MIX;
29092922
int depth_testi = DEPTH_TEST_ENABLED;
29102923
int alpha_antialiasing_modei = ALPHA_ANTIALIASING_OFF;
2911-
int cull_modei = CULL_BACK;
2924+
int cull_modei = RS::CULL_MODE_BACK;
29122925
int depth_drawi = DEPTH_DRAW_OPAQUE;
29132926

29142927
ShaderCompiler::IdentifierActions actions;
@@ -2931,9 +2944,9 @@ void SceneShaderData::set_code(const String &p_code) {
29312944

29322945
actions.render_mode_values["depth_test_disabled"] = Pair<int *, int>(&depth_testi, DEPTH_TEST_DISABLED);
29332946

2934-
actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, CULL_DISABLED);
2935-
actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, CULL_FRONT);
2936-
actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull_modei, CULL_BACK);
2947+
actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_DISABLED);
2948+
actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_FRONT);
2949+
actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_BACK);
29372950

29382951
actions.render_mode_flags["unshaded"] = &unshaded;
29392952
actions.render_mode_flags["wireframe"] = &wireframe;
@@ -2991,7 +3004,7 @@ void SceneShaderData::set_code(const String &p_code) {
29913004
alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei);
29923005
depth_draw = DepthDraw(depth_drawi);
29933006
depth_test = DepthTest(depth_testi);
2994-
cull_mode = Cull(cull_modei);
3007+
cull_mode = RS::CullMode(cull_modei);
29953008

29963009
vertex_input_mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL; // We can always read vertices and normals.
29973010
vertex_input_mask |= uses_tangent << RS::ARRAY_TANGENT;

‎drivers/gles3/storage/material_storage.h

+2-7
Original file line numberDiff line numberDiff line change
@@ -263,12 +263,6 @@ struct SceneShaderData : public ShaderData {
263263
DEPTH_TEST_ENABLED
264264
};
265265

266-
enum Cull {
267-
CULL_DISABLED,
268-
CULL_FRONT,
269-
CULL_BACK
270-
};
271-
272266
enum AlphaAntiAliasing {
273267
ALPHA_ANTIALIASING_OFF,
274268
ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
@@ -292,7 +286,7 @@ struct SceneShaderData : public ShaderData {
292286
AlphaAntiAliasing alpha_antialiasing_mode;
293287
DepthDraw depth_draw;
294288
DepthTest depth_test;
295-
Cull cull_mode;
289+
RS::CullMode cull_mode;
296290

297291
bool uses_point_size;
298292
bool uses_alpha;
@@ -618,6 +612,7 @@ class MaterialStorage : public RendererMaterialStorage {
618612

619613
virtual bool material_is_animated(RID p_material) override;
620614
virtual bool material_casts_shadows(RID p_material) override;
615+
virtual RS::CullMode material_get_cull_mode(RID p_material) const override;
621616

622617
virtual void material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) override;
623618

‎modules/lightmapper_rd/lightmapper_rd.cpp

+14-1
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030

3131
#include "lightmapper_rd.h"
3232

33+
#include "core/string/print_string.h"
3334
#include "lm_blendseams.glsl.gen.h"
3435
#include "lm_compute.glsl.gen.h"
3536
#include "lm_raster.glsl.gen.h"
@@ -40,6 +41,7 @@
4041
#include "editor/editor_paths.h"
4142
#include "editor/editor_settings.h"
4243
#include "servers/rendering/rendering_device_binds.h"
44+
#include "servers/rendering/rendering_server_globals.h"
4345

4446
#if defined(VULKAN_ENABLED)
4547
#include "drivers/vulkan/rendering_context_driver_vulkan.h"
@@ -477,7 +479,16 @@ void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i
477479
t.max_bounds[0] = taabb.position.x + MAX(taabb.size.x, 0.0001);
478480
t.max_bounds[1] = taabb.position.y + MAX(taabb.size.y, 0.0001);
479481
t.max_bounds[2] = taabb.position.z + MAX(taabb.size.z, 0.0001);
480-
t.pad0 = t.pad1 = 0; //make valgrind not complain
482+
483+
t.cull_mode = RS::CULL_MODE_BACK;
484+
485+
RID material = mi.data.material[i];
486+
if (material.is_valid()) {
487+
t.cull_mode = RSG::material_storage->material_get_cull_mode(material);
488+
} else {
489+
print_line("No material for mesh with vertex count ", mi.data.points.size());
490+
}
491+
t.pad1 = 0; //make valgrind not complain
481492
triangles.push_back(t);
482493
slice_triangle_count.write[t.slice]++;
483494
}
@@ -1319,6 +1330,8 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
13191330
bake_parameters.bounces = p_bounces;
13201331
bake_parameters.bounce_indirect_energy = p_bounce_indirect_energy;
13211332
bake_parameters.shadowmask_light_idx = shadowmask_light_idx;
1333+
// Same number of rays for transparency regardless of quality (it's more of a retry rather than shooting new ones).
1334+
bake_parameters.transparency_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_transparency_rays");
13221335

13231336
bake_parameters_buffer = rd->uniform_buffer_create(sizeof(BakeParameters));
13241337
rd->buffer_update(bake_parameters_buffer, 0, sizeof(BakeParameters), &bake_parameters);

‎modules/lightmapper_rd/lightmapper_rd.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,9 @@ class LightmapperRD : public Lightmapper {
5757
uint32_t bounces = 0;
5858

5959
float bounce_indirect_energy = 0.0f;
60-
int shadowmask_light_idx = 0;
61-
uint32_t pad[2] = {};
60+
uint32_t shadowmask_light_idx = 0;
61+
uint32_t transparency_rays = 0;
62+
uint32_t pad[1] = {};
6263
};
6364

6465
struct MeshInstance {
@@ -185,7 +186,7 @@ class LightmapperRD : public Lightmapper {
185186
uint32_t indices[3] = {};
186187
uint32_t slice = 0;
187188
float min_bounds[3] = {};
188-
float pad0 = 0.0;
189+
uint32_t cull_mode = 0;
189190
float max_bounds[3] = {};
190191
float pad1 = 0.0;
191192
bool operator<(const Triangle &p_triangle) const {

‎modules/lightmapper_rd/lm_common_inc.glsl

+6-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
/* SET 0, static data that does not change between any call */
21

32
layout(set = 0, binding = 0) uniform BakeParameters {
43
vec3 world_size;
@@ -18,8 +17,8 @@ layout(set = 0, binding = 0) uniform BakeParameters {
1817

1918
float bounce_indirect_energy;
2019
int shadowmask_light_idx;
20+
uint transparency_rays;
2121
uint pad0;
22-
uint pad1;
2322
}
2423
bake_params;
2524

@@ -35,11 +34,15 @@ layout(set = 0, binding = 1, std430) restrict readonly buffer Vertices {
3534
}
3635
vertices;
3736

37+
#define CULL_DISABLED 0
38+
#define CULL_FRONT 1
39+
#define CULL_BACK 2
40+
3841
struct Triangle {
3942
uvec3 indices;
4043
uint slice;
4144
vec3 min_bounds;
42-
uint pad0;
45+
uint cull_mode;
4346
vec3 max_bounds;
4447
uint pad1;
4548
};

0 commit comments

Comments
 (0)
Please sign in to comment.