Skip to content

Commit

Permalink
Add transparency support for LightmapGI
Browse files Browse the repository at this point in the history
Co-authored-by: Guerro323 <kaltobattle@gmail.com>
  • Loading branch information
Geometror and guerro323 committed Dec 16, 2024
1 parent 7f5c469 commit 4d1c7af
Show file tree
Hide file tree
Showing 26 changed files with 441 additions and 94 deletions.
3 changes: 3 additions & 0 deletions doc/classes/ProjectSettings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2730,6 +2730,9 @@
<member name="rendering/lightmapping/bake_performance/max_rays_per_probe_pass" type="int" setter="" getter="" default="64">
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.
</member>
<member name="rendering/lightmapping/bake_performance/max_transparency_rays" type="int" setter="" getter="" default="8">
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.
</member>
<member name="rendering/lightmapping/bake_performance/region_size" type="int" setter="" getter="" default="512">
The region size to use when baking lightmaps with [LightmapGI].
</member>
Expand Down
28 changes: 16 additions & 12 deletions drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -977,7 +977,7 @@ void RasterizerSceneGLES3::_update_sky_radiance(RID p_env, const Projection &p_p
glBindFramebuffer(GL_FRAMEBUFFER, sky->radiance_framebuffer);

scene_state.reset_gl_state();
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_DISABLED);
scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);
scene_state.enable_gl_blend(false);

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

cubemap_filter->filter_radiance(sky->raw_radiance, sky->radiance, sky->radiance_framebuffer, sky->radiance_size, sky->mipmap_count, sky->processing_layer);
Expand Down Expand Up @@ -1433,6 +1433,10 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
if (surf->flags & GeometryInstanceSurface::FLAG_PASS_SHADOW) {
rl->add_element(surf);
}
} else if (p_pass_mode == PASS_MODE_MATERIAL) {
if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE | GeometryInstanceSurface::FLAG_PASS_ALPHA)) {
rl->add_element(surf);
}
} else {
if (surf->flags & (GeometryInstanceSurface::FLAG_PASS_DEPTH | GeometryInstanceSurface::FLAG_PASS_OPAQUE)) {
rl->add_element(surf);
Expand Down Expand Up @@ -2210,7 +2214,7 @@ void RasterizerSceneGLES3::_render_shadow_pass(RID p_light, RID p_shadow_atlas,
scene_state.enable_gl_depth_test(false);
scene_state.enable_gl_depth_draw(true);
glDisable(GL_CULL_FACE);
scene_state.cull_mode = GLES3::SceneShaderData::CULL_DISABLED;
scene_state.cull_mode = RS::CULL_MODE_DISABLED;
glBindFramebuffer(GL_FRAMEBUFFER, GLES3::TextureStorage::system_fbo);
}

Expand Down Expand Up @@ -2587,7 +2591,7 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
scene_state.enable_gl_depth_draw(false);
scene_state.enable_gl_depth_test(false);
scene_state.enable_gl_blend(false);
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK);
scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);

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

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

scene_state.enable_gl_depth_test(true);
scene_state.enable_gl_blend(false);
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_BACK);
scene_state.set_gl_cull_mode(RS::CULL_MODE_BACK);

Transform3D transform = render_data.cam_transform;
Projection projection = render_data.cam_projection;
Expand Down Expand Up @@ -3099,19 +3103,19 @@ void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params,
}

// Find cull variant.
GLES3::SceneShaderData::Cull cull_mode = shader->cull_mode;
RS::CullMode cull_mode = shader->cull_mode;

if (p_pass_mode == PASS_MODE_MATERIAL || (surf->flags & GeometryInstanceSurface::FLAG_USES_DOUBLE_SIDED_SHADOWS)) {
cull_mode = GLES3::SceneShaderData::CULL_DISABLED;
cull_mode = RS::CULL_MODE_DISABLED;
} else {
bool mirror = inst->mirror;
if (p_params->reverse_cull) {
mirror = !mirror;
}
if (cull_mode == GLES3::SceneShaderData::CULL_FRONT && mirror) {
cull_mode = GLES3::SceneShaderData::CULL_BACK;
} else if (cull_mode == GLES3::SceneShaderData::CULL_BACK && mirror) {
cull_mode = GLES3::SceneShaderData::CULL_FRONT;
if (cull_mode == RS::CULL_MODE_FRONT && mirror) {
cull_mode = RS::CULL_MODE_BACK;
} else if (cull_mode == RS::CULL_MODE_BACK && mirror) {
cull_mode = RS::CULL_MODE_FRONT;
}
}

Expand Down Expand Up @@ -3832,7 +3836,7 @@ void RasterizerSceneGLES3::_render_buffers_debug_draw(Ref<RenderSceneBuffersGLES
glActiveTexture(GL_TEXTURE0);
scene_state.enable_gl_depth_draw(true);
glDepthFunc(GL_ALWAYS);
scene_state.set_gl_cull_mode(GLES3::SceneShaderData::CULL_DISABLED);
scene_state.set_gl_cull_mode(RS::CULL_MODE_DISABLED);

// Loop through quadrants and copy shadows over.
for (int quadrant = 0; quadrant < 4; quadrant++) {
Expand Down
12 changes: 6 additions & 6 deletions drivers/gles3/rasterizer_scene_gles3.h
Original file line number Diff line number Diff line change
Expand Up @@ -461,7 +461,7 @@ class RasterizerSceneGLES3 : public RendererSceneRender {
bool used_depth_prepass = false;

GLES3::SceneShaderData::BlendMode current_blend_mode = GLES3::SceneShaderData::BLEND_MODE_MIX;
GLES3::SceneShaderData::Cull cull_mode = GLES3::SceneShaderData::CULL_BACK;
RS::CullMode cull_mode = RS::CULL_MODE_BACK;

bool current_blend_enabled = false;
bool current_depth_draw_enabled = false;
Expand All @@ -477,24 +477,24 @@ class RasterizerSceneGLES3 : public RendererSceneRender {

glCullFace(GL_BACK);
glEnable(GL_CULL_FACE);
cull_mode = GLES3::SceneShaderData::CULL_BACK;
cull_mode = RS::CULL_MODE_BACK;

glDepthMask(GL_FALSE);
current_depth_draw_enabled = false;
glDisable(GL_DEPTH_TEST);
current_depth_test_enabled = false;
}

void set_gl_cull_mode(GLES3::SceneShaderData::Cull p_mode) {
void set_gl_cull_mode(RS::CullMode p_mode) {
if (cull_mode != p_mode) {
if (p_mode == GLES3::SceneShaderData::CULL_DISABLED) {
if (p_mode == RS::CULL_MODE_DISABLED) {
glDisable(GL_CULL_FACE);
} else {
if (cull_mode == GLES3::SceneShaderData::CULL_DISABLED) {
if (cull_mode == RS::CULL_MODE_DISABLED) {
// Last time was disabled, so enable and set proper face.
glEnable(GL_CULL_FACE);
}
glCullFace(p_mode == GLES3::SceneShaderData::CULL_FRONT ? GL_FRONT : GL_BACK);
glCullFace(p_mode == RS::CULL_MODE_FRONT ? GL_FRONT : GL_BACK);
}
cull_mode = p_mode;
}
Expand Down
16 changes: 16 additions & 0 deletions drivers/gles3/shaders/scene.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -1882,10 +1882,18 @@ void main() {
#ifndef USE_SHADOW_TO_OPACITY

#if defined(ALPHA_SCISSOR_USED)
#ifdef RENDER_MATERIAL
if (alpha < alpha_scissor_threshold) {
alpha = 0.0;
} else {
alpha = 1.0;
}
#else
if (alpha < alpha_scissor_threshold) {
discard;
}
alpha = 1.0;
#endif // RENDER_MATERIAL
#else
#ifdef MODE_RENDER_DEPTH
#ifdef USE_OPAQUE_PREPASS
Expand Down Expand Up @@ -2215,9 +2223,17 @@ void main() {
alpha = min(alpha, clamp(length(ambient_light), 0.0, 1.0));

#if defined(ALPHA_SCISSOR_USED)
#ifdef RENDER_MATERIAL
if (alpha < alpha_scissor_threshold) {
alpha = 0.0;
} else {
alpha = 1.0;
}
#else
if (alpha < alpha_scissor_threshold) {
discard;
}
#endif // RENDER_MATERIAL
#endif // !ALPHA_SCISSOR_USED

#endif // !MODE_RENDER_DEPTH
Expand Down
24 changes: 19 additions & 5 deletions drivers/gles3/storage/material_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/**************************************************************************/

#include "core/error/error_macros.h"
#ifdef GLES3_ENABLED

#include "core/config/project_settings.h"
Expand Down Expand Up @@ -2505,6 +2506,19 @@ bool MaterialStorage::material_casts_shadows(RID p_material) {
return true; //by default everything casts shadows
}

RS::CullMode MaterialStorage::material_get_cull_mode(RID p_material) const {
const GLES3::Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_NULL_V(material, RS::CULL_MODE_DISABLED);
ERR_FAIL_NULL_V(material->shader, RS::CULL_MODE_DISABLED);
if (material->shader->data) {
SceneShaderData *data = dynamic_cast<SceneShaderData *>(material->shader->data);
if (data) {
return (RS::CullMode)data->cull_mode;
}
}
return RS::CULL_MODE_DISABLED;
}

void MaterialStorage::material_get_instance_shader_parameters(RID p_material, List<InstanceShaderParam> *r_parameters) {
GLES3::Material *material = material_owner.get_or_null(p_material);
ERR_FAIL_NULL(material);
Expand Down Expand Up @@ -2907,7 +2921,7 @@ void SceneShaderData::set_code(const String &p_code) {
int blend_modei = BLEND_MODE_MIX;
int depth_testi = DEPTH_TEST_ENABLED;
int alpha_antialiasing_modei = ALPHA_ANTIALIASING_OFF;
int cull_modei = CULL_BACK;
int cull_modei = RS::CULL_MODE_BACK;
int depth_drawi = DEPTH_DRAW_OPAQUE;

ShaderCompiler::IdentifierActions actions;
Expand All @@ -2930,9 +2944,9 @@ void SceneShaderData::set_code(const String &p_code) {

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

actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, CULL_DISABLED);
actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, CULL_FRONT);
actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull_modei, CULL_BACK);
actions.render_mode_values["cull_disabled"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_DISABLED);
actions.render_mode_values["cull_front"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_FRONT);
actions.render_mode_values["cull_back"] = Pair<int *, int>(&cull_modei, RS::CULL_MODE_BACK);

actions.render_mode_flags["unshaded"] = &unshaded;
actions.render_mode_flags["wireframe"] = &wireframe;
Expand Down Expand Up @@ -2990,7 +3004,7 @@ void SceneShaderData::set_code(const String &p_code) {
alpha_antialiasing_mode = AlphaAntiAliasing(alpha_antialiasing_modei);
depth_draw = DepthDraw(depth_drawi);
depth_test = DepthTest(depth_testi);
cull_mode = Cull(cull_modei);
cull_mode = RS::CullMode(cull_modei);

vertex_input_mask = RS::ARRAY_FORMAT_VERTEX | RS::ARRAY_FORMAT_NORMAL; // We can always read vertices and normals.
vertex_input_mask |= uses_tangent << RS::ARRAY_TANGENT;
Expand Down
9 changes: 2 additions & 7 deletions drivers/gles3/storage/material_storage.h
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,6 @@ struct SceneShaderData : public ShaderData {
DEPTH_TEST_ENABLED
};

enum Cull {
CULL_DISABLED,
CULL_FRONT,
CULL_BACK
};

enum AlphaAntiAliasing {
ALPHA_ANTIALIASING_OFF,
ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE,
Expand All @@ -292,7 +286,7 @@ struct SceneShaderData : public ShaderData {
AlphaAntiAliasing alpha_antialiasing_mode;
DepthDraw depth_draw;
DepthTest depth_test;
Cull cull_mode;
RS::CullMode cull_mode;

bool uses_point_size;
bool uses_alpha;
Expand Down Expand Up @@ -618,6 +612,7 @@ class MaterialStorage : public RendererMaterialStorage {

virtual bool material_is_animated(RID p_material) override;
virtual bool material_casts_shadows(RID p_material) override;
virtual RS::CullMode material_get_cull_mode(RID p_material) const override;

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

Expand Down
15 changes: 14 additions & 1 deletion modules/lightmapper_rd/lightmapper_rd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "lightmapper_rd.h"

#include "core/string/print_string.h"
#include "lm_blendseams.glsl.gen.h"
#include "lm_compute.glsl.gen.h"
#include "lm_raster.glsl.gen.h"
Expand All @@ -40,6 +41,7 @@
#include "editor/editor_paths.h"
#include "editor/editor_settings.h"
#include "servers/rendering/rendering_device_binds.h"
#include "servers/rendering/rendering_server_globals.h"

#if defined(VULKAN_ENABLED)
#include "drivers/vulkan/rendering_context_driver_vulkan.h"
Expand Down Expand Up @@ -477,7 +479,16 @@ void LightmapperRD::_create_acceleration_structures(RenderingDevice *rd, Size2i
t.max_bounds[0] = taabb.position.x + MAX(taabb.size.x, 0.0001);
t.max_bounds[1] = taabb.position.y + MAX(taabb.size.y, 0.0001);
t.max_bounds[2] = taabb.position.z + MAX(taabb.size.z, 0.0001);
t.pad0 = t.pad1 = 0; //make valgrind not complain

t.cull_mode = RS::CULL_MODE_BACK;

RID material = mi.data.material[i];
if (material.is_valid()) {
t.cull_mode = RSG::material_storage->material_get_cull_mode(material);
} else {
print_line("No material for mesh with vertex count ", mi.data.points.size());
}
t.pad1 = 0; //make valgrind not complain
triangles.push_back(t);
slice_triangle_count.write[t.slice]++;
}
Expand Down Expand Up @@ -1319,6 +1330,8 @@ LightmapperRD::BakeError LightmapperRD::bake(BakeQuality p_quality, bool p_use_d
bake_parameters.bounces = p_bounces;
bake_parameters.bounce_indirect_energy = p_bounce_indirect_energy;
bake_parameters.shadowmask_light_idx = shadowmask_light_idx;
// Same number of rays for transparency regardless of quality (it's more of a retry rather than shooting new ones).
bake_parameters.transparency_rays = GLOBAL_GET("rendering/lightmapping/bake_performance/max_transparency_rays");

bake_parameters_buffer = rd->uniform_buffer_create(sizeof(BakeParameters));
rd->buffer_update(bake_parameters_buffer, 0, sizeof(BakeParameters), &bake_parameters);
Expand Down
7 changes: 4 additions & 3 deletions modules/lightmapper_rd/lightmapper_rd.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,9 @@ class LightmapperRD : public Lightmapper {
uint32_t bounces = 0;

float bounce_indirect_energy = 0.0f;
int shadowmask_light_idx = 0;
uint32_t pad[2] = {};
uint32_t shadowmask_light_idx = 0;
uint32_t transparency_rays = 0;
uint32_t pad[1] = {};
};

struct MeshInstance {
Expand Down Expand Up @@ -185,7 +186,7 @@ class LightmapperRD : public Lightmapper {
uint32_t indices[3] = {};
uint32_t slice = 0;
float min_bounds[3] = {};
float pad0 = 0.0;
uint32_t cull_mode = 0;
float max_bounds[3] = {};
float pad1 = 0.0;
bool operator<(const Triangle &p_triangle) const {
Expand Down
9 changes: 6 additions & 3 deletions modules/lightmapper_rd/lm_common_inc.glsl
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* SET 0, static data that does not change between any call */

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

float bounce_indirect_energy;
int shadowmask_light_idx;
uint transparency_rays;
uint pad0;
uint pad1;
}
bake_params;

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

#define CULL_DISABLED 0
#define CULL_FRONT 1
#define CULL_BACK 2

struct Triangle {
uvec3 indices;
uint slice;
vec3 min_bounds;
uint pad0;
uint cull_mode;
vec3 max_bounds;
uint pad1;
};
Expand Down
Loading

0 comments on commit 4d1c7af

Please sign in to comment.