Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure that only visible paired lights are used #83493

Merged
merged 1 commit into from
Oct 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions drivers/gles3/rasterizer_scene_gles3.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1254,9 +1254,14 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
inst->light_passes.clear();
inst->spot_light_gl_cache.clear();
inst->omni_light_gl_cache.clear();
uint64_t current_frame = RSG::rasterizer->get_frame_number();

if (inst->paired_omni_light_count) {
for (uint32_t j = 0; j < inst->paired_omni_light_count; j++) {
RID light_instance = inst->paired_omni_lights[j];
if (GLES3::LightStorage::get_singleton()->light_instance_get_render_pass(light_instance) != current_frame) {
continue;
}
RID light = GLES3::LightStorage::get_singleton()->light_instance_get_base_light(light_instance);
int32_t shadow_id = GLES3::LightStorage::get_singleton()->light_instance_get_shadow_id(light_instance);

Expand All @@ -1277,6 +1282,9 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
if (inst->paired_spot_light_count) {
for (uint32_t j = 0; j < inst->paired_spot_light_count; j++) {
RID light_instance = inst->paired_spot_lights[j];
if (GLES3::LightStorage::get_singleton()->light_instance_get_render_pass(light_instance) != current_frame) {
continue;
}
RID light = GLES3::LightStorage::get_singleton()->light_instance_get_base_light(light_instance);
int32_t shadow_id = GLES3::LightStorage::get_singleton()->light_instance_get_shadow_id(light_instance);

Expand Down Expand Up @@ -1712,6 +1720,8 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
r_spot_light_count++;
} break;
}

li->last_pass = RSG::rasterizer->get_frame_number();
}

if (r_omni_light_count) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ RendererRD::ForwardID RenderForwardMobile::ForwardIDStorageMobile::allocate_forw
index = forward_id_allocators[p_type].allocations.size();
forward_id_allocators[p_type].allocations.push_back(true);
forward_id_allocators[p_type].map.push_back(0xFF);
forward_id_allocators[p_type].last_pass.push_back(0);
} else {
forward_id_allocators[p_type].allocations[index] = true;
}
Expand All @@ -64,44 +65,72 @@ void RenderForwardMobile::ForwardIDStorageMobile::free_forward_id(RendererRD::Fo
forward_id_allocators[p_type].allocations[p_id] = false;
}

void RenderForwardMobile::ForwardIDStorageMobile::map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index) {
void RenderForwardMobile::ForwardIDStorageMobile::map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index, uint64_t p_last_pass) {
forward_id_allocators[p_type].map[p_id] = p_index;
forward_id_allocators[p_type].last_pass[p_id] = p_last_pass;
}

void RenderForwardMobile::fill_push_constant_instance_indices(SceneState::InstanceData *p_instance_data, const GeometryInstanceForwardMobile *p_instance) {
// First zero out our indices.
uint64_t current_frame = RSG::rasterizer->get_frame_number();

p_instance_data->omni_lights[0] = 0xFFFFFFFF;
p_instance_data->omni_lights[1] = 0xFFFFFFFF;

p_instance_data->spot_lights[0] = 0xFFFFFFFF;
p_instance_data->spot_lights[1] = 0xFFFFFFFF;

p_instance_data->decals[0] = 0xFFFFFFFF;
p_instance_data->decals[1] = 0xFFFFFFFF;

p_instance_data->reflection_probes[0] = 0xFFFFFFFF;
p_instance_data->reflection_probes[1] = 0xFFFFFFFF;

for (uint32_t i = 0; i < MAX_RDL_CULL; i++) {
uint32_t ofs = i < 4 ? 0 : 1;
uint32_t shift = (i & 0x3) << 3;
uint32_t idx = 0;
for (uint32_t i = 0; i < p_instance->omni_light_count; i++) {
uint32_t ofs = idx < 4 ? 0 : 1;
uint32_t shift = (idx & 0x3) << 3;
uint32_t mask = ~(0xFF << shift);
if (i < p_instance->omni_light_count) {

if (forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT].last_pass[p_instance->omni_lights[i]] == current_frame) {
p_instance_data->omni_lights[ofs] &= mask;
p_instance_data->omni_lights[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT].map[p_instance->omni_lights[i]]) << shift;
idx++;
}
if (i < p_instance->spot_light_count) {
}

p_instance_data->spot_lights[0] = 0xFFFFFFFF;
p_instance_data->spot_lights[1] = 0xFFFFFFFF;

idx = 0;
for (uint32_t i = 0; i < p_instance->spot_light_count; i++) {
uint32_t ofs = idx < 4 ? 0 : 1;
uint32_t shift = (idx & 0x3) << 3;
uint32_t mask = ~(0xFF << shift);
if (forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT].last_pass[p_instance->spot_lights[i]] == current_frame) {
p_instance_data->spot_lights[ofs] &= mask;
p_instance_data->spot_lights[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT].map[p_instance->spot_lights[i]]) << shift;
idx++;
}
if (i < p_instance->decals_count) {
}

p_instance_data->decals[0] = 0xFFFFFFFF;
p_instance_data->decals[1] = 0xFFFFFFFF;

idx = 0;
for (uint32_t i = 0; i < p_instance->decals_count; i++) {
uint32_t ofs = idx < 4 ? 0 : 1;
uint32_t shift = (idx & 0x3) << 3;
uint32_t mask = ~(0xFF << shift);
if (forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_DECAL].last_pass[p_instance->decals[i]] == current_frame) {
p_instance_data->decals[ofs] &= mask;
p_instance_data->decals[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_DECAL].map[p_instance->decals[i]]) << shift;
idx++;
}
if (i < p_instance->reflection_probe_count) {
}

p_instance_data->reflection_probes[0] = 0xFFFFFFFF;
p_instance_data->reflection_probes[1] = 0xFFFFFFFF;

idx = 0;
for (uint32_t i = 0; i < p_instance->reflection_probe_count; i++) {
uint32_t ofs = idx < 4 ? 0 : 1;
uint32_t shift = (idx & 0x3) << 3;
uint32_t mask = ~(0xFF << shift);
if (forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_REFLECTION_PROBE].last_pass[p_instance->reflection_probes[i]] == current_frame) {
p_instance_data->reflection_probes[ofs] &= mask;
p_instance_data->reflection_probes[ofs] |= uint32_t(forward_id_storage_mobile->forward_id_allocators[RendererRD::FORWARD_ID_TYPE_REFLECTION_PROBE].map[p_instance->reflection_probes[i]]) << shift;
idx++;
}
}
}
Expand Down Expand Up @@ -539,7 +568,6 @@ void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, co

void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();

p_render_data->cube_shadows.clear();
p_render_data->shadows.clear();
Expand Down Expand Up @@ -598,28 +626,11 @@ void RenderForwardMobile::_pre_opaque_render(RenderDataRD *p_render_data) {

//full barrier here, we need raster, transfer and compute and it depends from the previous work
RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS);

bool using_shadows = true;

if (p_render_data->reflection_probe.is_valid()) {
if (!RSG::light_storage->reflection_probe_renders_shadows(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
using_shadows = false;
}
} else {
//do not render reflections when rendering a reflection probe
light_storage->update_reflection_probe_buffer(p_render_data, *p_render_data->reflection_probes, p_render_data->scene_data->cam_transform.affine_inverse(), p_render_data->environment);
}

uint32_t directional_light_count = 0;
uint32_t positional_light_count = 0;
light_storage->update_light_buffers(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
texture_storage->update_decal_buffer(*p_render_data->decals, p_render_data->scene_data->cam_transform);

p_render_data->directional_light_count = directional_light_count;
}

void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();

ERR_FAIL_NULL(p_render_data);

Expand Down Expand Up @@ -668,6 +679,25 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
bool using_subpass_transparent = true;
bool using_subpass_post_process = true;

bool using_shadows = true;

if (p_render_data->reflection_probe.is_valid()) {
if (!RSG::light_storage->reflection_probe_renders_shadows(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
using_shadows = false;
}
} else {
//do not render reflections when rendering a reflection probe
light_storage->update_reflection_probe_buffer(p_render_data, *p_render_data->reflection_probes, p_render_data->scene_data->cam_transform.affine_inverse(), p_render_data->environment);
}

// Update light and decal buffer first so we know what lights and decals are safe to pair with.
uint32_t directional_light_count = 0;
uint32_t positional_light_count = 0;
light_storage->update_light_buffers(p_render_data, *p_render_data->lights, p_render_data->scene_data->cam_transform, p_render_data->shadow_atlas, using_shadows, directional_light_count, positional_light_count, p_render_data->directional_light_soft_shadows);
texture_storage->update_decal_buffer(*p_render_data->decals, p_render_data->scene_data->cam_transform);

p_render_data->directional_light_count = directional_light_count;

// fill our render lists early so we can find out if we use various features
_fill_render_list(RENDER_LIST_OPAQUE, p_render_data, PASS_MODE_COLOR);
render_list[RENDER_LIST_OPAQUE].sort_by_key();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -535,14 +535,15 @@ class RenderForwardMobile : public RendererSceneRenderRD {
struct ForwardIDAllocator {
LocalVector<bool> allocations;
LocalVector<uint8_t> map;
LocalVector<uint64_t> last_pass;
};

ForwardIDAllocator forward_id_allocators[RendererRD::FORWARD_ID_MAX];

public:
virtual RendererRD::ForwardID allocate_forward_id(RendererRD::ForwardIDType p_type) override;
virtual void free_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id) override;
virtual void map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index) override;
virtual void map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index, uint64_t p_last_pass) override;
virtual bool uses_forward_ids() const override { return true; }
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class ForwardIDStorage {

virtual RendererRD::ForwardID allocate_forward_id(RendererRD::ForwardIDType p_type) { return -1; }
virtual void free_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id) {}
virtual void map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index) {}
virtual void map_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id, uint32_t p_index, uint64_t p_last_pass) {}
virtual bool uses_forward_ids() const { return false; }
};

Expand Down
4 changes: 2 additions & 2 deletions servers/rendering/renderer_rd/storage_rd/light_storage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -793,7 +793,7 @@ void LightStorage::update_light_buffers(RenderDataRD *p_render_data, const Paged
real_t distance = (i < omni_light_count) ? omni_light_sort[index].depth : spot_light_sort[index].depth;

if (using_forward_ids) {
forward_id_storage->map_forward_id(type == RS::LIGHT_OMNI ? RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT : RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT, light_instance->forward_id, index);
forward_id_storage->map_forward_id(type == RS::LIGHT_OMNI ? RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT : RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT, light_instance->forward_id, index, light_instance->last_pass);
}

Transform3D light_transform = light_instance->transform;
Expand Down Expand Up @@ -1670,7 +1670,7 @@ void LightStorage::update_reflection_probe_buffer(RenderDataRD *p_render_data, c
ReflectionProbeInstance *rpi = reflection_sort[i].probe_instance;

if (using_forward_ids) {
forward_id_storage->map_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE, rpi->forward_id, i);
forward_id_storage->map_forward_id(FORWARD_ID_TYPE_REFLECTION_PROBE, rpi->forward_id, i, rpi->last_pass);
}

ReflectionProbe *probe = reflection_probe_owner.get_or_null(rpi->probe);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2862,7 +2862,7 @@ void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const
Decal *decal = decal_sort[i].decal;

if (using_forward_ids) {
forward_id_storage->map_forward_id(FORWARD_ID_TYPE_DECAL, decal_instance->forward_id, i);
forward_id_storage->map_forward_id(FORWARD_ID_TYPE_DECAL, decal_instance->forward_id, i, RSG::rasterizer->get_frame_number());
}

decal_instance->cull_mask = decal->cull_mask;
Expand Down
Loading