mirror of
https://github.com/godotengine/godot.git
synced 2024-11-27 09:16:35 +08:00
Move cluster builder, sdfgi and gi structures to clustered renderer, move light and probe elements into storage and reorganise our render_scene method.
This commit is contained in:
parent
4b52c6caef
commit
ddc4ae1175
@ -43,7 +43,7 @@ RID Fog::fog_volume_allocate() {
|
||||
void Fog::fog_volume_initialize(RID p_rid) {
|
||||
}
|
||||
|
||||
void Fog::fog_free(RID p_rid) {
|
||||
void Fog::fog_volume_free(RID p_rid) {
|
||||
}
|
||||
|
||||
void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
|
||||
|
@ -46,7 +46,7 @@ public:
|
||||
|
||||
virtual RID fog_volume_allocate() override;
|
||||
virtual void fog_volume_initialize(RID p_rid) override;
|
||||
virtual void fog_free(RID p_rid) override;
|
||||
virtual void fog_volume_free(RID p_rid) override;
|
||||
|
||||
virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override;
|
||||
virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override;
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
#include "servers/rendering/rendering_server_globals.h"
|
||||
#include "storage/config.h"
|
||||
#include "storage/light_storage.h"
|
||||
#include "storage/mesh_storage.h"
|
||||
#include "storage/texture_storage.h"
|
||||
|
||||
@ -70,7 +69,7 @@ void RasterizerSceneGLES3::GeometryInstanceGLES3::pair_light_instances(const RID
|
||||
spot_lights.clear();
|
||||
|
||||
for (uint32_t i = 0; i < p_light_instance_count; i++) {
|
||||
RS::LightType type = RasterizerSceneGLES3::get_singleton()->light_instance_get_type(p_light_instances[i]);
|
||||
RS::LightType type = GLES3::LightStorage::get_singleton()->light_instance_get_type(p_light_instances[i]);
|
||||
switch (type) {
|
||||
case RS::LIGHT_OMNI: {
|
||||
if (omni_light_count < (uint32_t)config->max_lights_per_object) {
|
||||
@ -399,32 +398,6 @@ void RasterizerSceneGLES3::_geometry_instance_update(RenderGeometryInstance *p_g
|
||||
ginstance->dirty_list_element.remove_from_list();
|
||||
}
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
RID RasterizerSceneGLES3::shadow_atlas_create() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) {
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
|
||||
}
|
||||
|
||||
bool RasterizerSceneGLES3::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {
|
||||
}
|
||||
|
||||
int RasterizerSceneGLES3::get_directional_light_shadow_size(RID p_light_intance) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::set_directional_shadow_count(int p_count) {
|
||||
}
|
||||
|
||||
/* SKY API */
|
||||
|
||||
void RasterizerSceneGLES3::_free_sky_data(Sky *p_sky) {
|
||||
@ -625,7 +598,7 @@ void RasterizerSceneGLES3::_setup_sky(const RenderDataGLES3 *p_render_data, cons
|
||||
if (shader_data->uses_light) {
|
||||
sky_globals.directional_light_count = 0;
|
||||
for (int i = 0; i < (int)p_lights.size(); i++) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_lights[i]);
|
||||
GLES3::LightInstance *li = GLES3::LightStorage::get_singleton()->get_light_instance(p_lights[i]);
|
||||
if (!li) {
|
||||
continue;
|
||||
}
|
||||
@ -1084,38 +1057,6 @@ void RasterizerSceneGLES3::positional_soft_shadow_filter_set_quality(RS::ShadowQ
|
||||
void RasterizerSceneGLES3::directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) {
|
||||
}
|
||||
|
||||
RID RasterizerSceneGLES3::light_instance_create(RID p_light) {
|
||||
RID li = light_instance_owner.make_rid(LightInstance());
|
||||
|
||||
LightInstance *light_instance = light_instance_owner.get_or_null(li);
|
||||
|
||||
light_instance->self = li;
|
||||
light_instance->light = p_light;
|
||||
light_instance->light_type = RSG::light_storage->light_get_type(p_light);
|
||||
|
||||
return li;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) {
|
||||
LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);
|
||||
ERR_FAIL_COND(!light_instance);
|
||||
|
||||
light_instance->transform = p_transform;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {
|
||||
LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);
|
||||
ERR_FAIL_COND(!light_instance);
|
||||
|
||||
light_instance->aabb = p_aabb;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::light_instance_mark_visible(RID p_light_instance) {
|
||||
}
|
||||
|
||||
RID RasterizerSceneGLES3::fog_volume_instance_create(RID p_fog_volume) {
|
||||
return RID();
|
||||
}
|
||||
@ -1134,57 +1075,6 @@ Vector3 RasterizerSceneGLES3::fog_volume_instance_get_position(RID p_fog_volume_
|
||||
return Vector3();
|
||||
}
|
||||
|
||||
RID RasterizerSceneGLES3::reflection_atlas_create() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
int RasterizerSceneGLES3::reflection_atlas_get_size(RID p_ref_atlas) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) {
|
||||
}
|
||||
|
||||
RID RasterizerSceneGLES3::reflection_probe_instance_create(RID p_probe) {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) {
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::reflection_probe_release_atlas_index(RID p_instance) {
|
||||
}
|
||||
|
||||
bool RasterizerSceneGLES3::reflection_probe_instance_needs_redraw(RID p_instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RasterizerSceneGLES3::reflection_probe_instance_has_reflection(RID p_instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RasterizerSceneGLES3::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RasterizerSceneGLES3::reflection_probe_instance_postprocess_step(RID p_instance) {
|
||||
return true;
|
||||
}
|
||||
|
||||
RID RasterizerSceneGLES3::decal_instance_create(RID p_decal) {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) {
|
||||
}
|
||||
|
||||
RID RasterizerSceneGLES3::lightmap_instance_create(RID p_lightmap) {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES3::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) {
|
||||
}
|
||||
|
||||
RID RasterizerSceneGLES3::voxel_gi_instance_create(RID p_voxel_gi) {
|
||||
return RID();
|
||||
}
|
||||
@ -1257,13 +1147,13 @@ void RasterizerSceneGLES3::_fill_render_list(RenderListType p_render_list, const
|
||||
if (inst->omni_light_count) {
|
||||
inst->omni_light_gl_cache.resize(inst->omni_light_count);
|
||||
for (uint32_t j = 0; j < inst->omni_light_count; j++) {
|
||||
inst->omni_light_gl_cache[j] = light_instance_get_gl_id(inst->omni_lights[j]);
|
||||
inst->omni_light_gl_cache[j] = GLES3::LightStorage::get_singleton()->light_instance_get_gl_id(inst->omni_lights[j]);
|
||||
}
|
||||
}
|
||||
if (inst->spot_light_count) {
|
||||
inst->spot_light_gl_cache.resize(inst->spot_light_count);
|
||||
for (uint32_t j = 0; j < inst->spot_light_count; j++) {
|
||||
inst->spot_light_gl_cache[j] = light_instance_get_gl_id(inst->spot_lights[j]);
|
||||
inst->spot_light_gl_cache[j] = GLES3::LightStorage::get_singleton()->light_instance_get_gl_id(inst->spot_lights[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1501,7 +1391,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
|
||||
int num_lights = lights.size();
|
||||
|
||||
for (int i = 0; i < num_lights; i++) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(lights[i]);
|
||||
GLES3::LightInstance *li = GLES3::LightStorage::get_singleton()->get_light_instance(lights[i]);
|
||||
if (!li) {
|
||||
continue;
|
||||
}
|
||||
@ -1606,12 +1496,12 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
|
||||
}
|
||||
|
||||
if (r_omni_light_count) {
|
||||
SortArray<InstanceSort<LightInstance>> sorter;
|
||||
SortArray<InstanceSort<GLES3::LightInstance>> sorter;
|
||||
sorter.sort(scene_state.omni_light_sort, r_omni_light_count);
|
||||
}
|
||||
|
||||
if (r_spot_light_count) {
|
||||
SortArray<InstanceSort<LightInstance>> sorter;
|
||||
SortArray<InstanceSort<GLES3::LightInstance>> sorter;
|
||||
sorter.sort(scene_state.spot_light_sort, r_spot_light_count);
|
||||
}
|
||||
|
||||
@ -1619,7 +1509,7 @@ void RasterizerSceneGLES3::_setup_lights(const RenderDataGLES3 *p_render_data, b
|
||||
uint32_t index = (i < r_omni_light_count) ? i : i - (r_omni_light_count);
|
||||
LightData &light_data = (i < r_omni_light_count) ? scene_state.omni_lights[index] : scene_state.spot_lights[index];
|
||||
RS::LightType type = (i < r_omni_light_count) ? RS::LIGHT_OMNI : RS::LIGHT_SPOT;
|
||||
LightInstance *li = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].instance : scene_state.spot_light_sort[index].instance;
|
||||
GLES3::LightInstance *li = (i < r_omni_light_count) ? scene_state.omni_light_sort[index].instance : scene_state.spot_light_sort[index].instance;
|
||||
RID base = li->light;
|
||||
|
||||
Transform3D light_transform = li->transform;
|
||||
@ -2390,10 +2280,8 @@ bool RasterizerSceneGLES3::free(RID p_rid) {
|
||||
ERR_FAIL_COND_V(!sky, false);
|
||||
_free_sky_data(sky);
|
||||
sky_owner.free(p_rid);
|
||||
} else if (light_instance_owner.owns(p_rid)) {
|
||||
LightInstance *light_instance = light_instance_owner.get_or_null(p_rid);
|
||||
ERR_FAIL_COND_V(!light_instance, false);
|
||||
light_instance_owner.free(p_rid);
|
||||
} else if (GLES3::LightStorage::get_singleton()->owns_light_instance(p_rid)) {
|
||||
GLES3::LightStorage::get_singleton()->light_instance_free(p_rid);
|
||||
} else if (RSG::camera_attributes->owns_camera_attributes(p_rid)) {
|
||||
//not much to delete, just free it
|
||||
RSG::camera_attributes->camera_attributes_free(p_rid);
|
||||
@ -2433,13 +2321,13 @@ RasterizerSceneGLES3::RasterizerSceneGLES3() {
|
||||
|
||||
uint32_t light_buffer_size = config->max_renderable_lights * sizeof(LightData);
|
||||
scene_state.omni_lights = memnew_arr(LightData, config->max_renderable_lights);
|
||||
scene_state.omni_light_sort = memnew_arr(InstanceSort<LightInstance>, config->max_renderable_lights);
|
||||
scene_state.omni_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);
|
||||
glGenBuffers(1, &scene_state.omni_light_buffer);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, scene_state.omni_light_buffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, light_buffer_size, nullptr, GL_STREAM_DRAW);
|
||||
|
||||
scene_state.spot_lights = memnew_arr(LightData, config->max_renderable_lights);
|
||||
scene_state.spot_light_sort = memnew_arr(InstanceSort<LightInstance>, config->max_renderable_lights);
|
||||
scene_state.spot_light_sort = memnew_arr(InstanceSort<GLES3::LightInstance>, config->max_renderable_lights);
|
||||
glGenBuffers(1, &scene_state.spot_light_buffer);
|
||||
glBindBuffer(GL_UNIFORM_BUFFER, scene_state.spot_light_buffer);
|
||||
glBufferData(GL_UNIFORM_BUFFER, light_buffer_size, nullptr, GL_STREAM_DRAW);
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "shader_gles3.h"
|
||||
#include "shaders/cubemap_filter.glsl.gen.h"
|
||||
#include "shaders/sky.glsl.gen.h"
|
||||
#include "storage/light_storage.h"
|
||||
#include "storage/material_storage.h"
|
||||
#include "storage/render_scene_buffers_gles3.h"
|
||||
#include "storage/utilities.h"
|
||||
@ -183,34 +184,6 @@ private:
|
||||
};
|
||||
static_assert(sizeof(DirectionalLightData) % 16 == 0, "DirectionalLightData size must be a multiple of 16 bytes");
|
||||
|
||||
struct LightInstance {
|
||||
RS::LightType light_type = RS::LIGHT_DIRECTIONAL;
|
||||
|
||||
AABB aabb;
|
||||
RID self;
|
||||
RID light;
|
||||
Transform3D transform;
|
||||
|
||||
Vector3 light_vector;
|
||||
Vector3 spot_vector;
|
||||
float linear_att = 0.0;
|
||||
|
||||
uint64_t shadow_pass = 0;
|
||||
uint64_t last_scene_pass = 0;
|
||||
uint64_t last_scene_shadow_pass = 0;
|
||||
uint64_t last_pass = 0;
|
||||
uint32_t cull_mask = 0;
|
||||
uint32_t light_directional_index = 0;
|
||||
|
||||
Rect2 directional_rect;
|
||||
|
||||
uint32_t gl_id = -1;
|
||||
|
||||
LightInstance() {}
|
||||
};
|
||||
|
||||
mutable RID_Owner<LightInstance> light_instance_owner;
|
||||
|
||||
class GeometryInstanceGLES3;
|
||||
|
||||
// Cached data for drawing surfaces
|
||||
@ -398,8 +371,8 @@ private:
|
||||
LightData *omni_lights = nullptr;
|
||||
LightData *spot_lights = nullptr;
|
||||
|
||||
InstanceSort<LightInstance> *omni_light_sort;
|
||||
InstanceSort<LightInstance> *spot_light_sort;
|
||||
InstanceSort<GLES3::LightInstance> *omni_light_sort;
|
||||
InstanceSort<GLES3::LightInstance> *spot_light_sort;
|
||||
GLuint omni_light_buffer = 0;
|
||||
GLuint spot_light_buffer = 0;
|
||||
uint32_t omni_light_count = 0;
|
||||
@ -605,17 +578,6 @@ public:
|
||||
|
||||
uint32_t geometry_instance_get_pair_mask() override;
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
RID shadow_atlas_create() override;
|
||||
void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override;
|
||||
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override;
|
||||
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override;
|
||||
|
||||
void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override;
|
||||
int get_directional_light_shadow_size(RID p_light_intance) override;
|
||||
void set_directional_shadow_count(int p_count) override;
|
||||
|
||||
/* SDFGI UPDATE */
|
||||
|
||||
void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {}
|
||||
@ -666,45 +628,12 @@ public:
|
||||
void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override;
|
||||
void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override;
|
||||
|
||||
RID light_instance_create(RID p_light) override;
|
||||
void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override;
|
||||
void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override;
|
||||
void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override;
|
||||
void light_instance_mark_visible(RID p_light_instance) override;
|
||||
|
||||
_FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->light_type;
|
||||
}
|
||||
_FORCE_INLINE_ uint32_t light_instance_get_gl_id(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->gl_id;
|
||||
}
|
||||
|
||||
RID fog_volume_instance_create(RID p_fog_volume) override;
|
||||
void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) override;
|
||||
void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) override;
|
||||
RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const override;
|
||||
Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const override;
|
||||
|
||||
RID reflection_atlas_create() override;
|
||||
int reflection_atlas_get_size(RID p_ref_atlas) const override;
|
||||
void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override;
|
||||
|
||||
RID reflection_probe_instance_create(RID p_probe) override;
|
||||
void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override;
|
||||
void reflection_probe_release_atlas_index(RID p_instance) override;
|
||||
bool reflection_probe_instance_needs_redraw(RID p_instance) override;
|
||||
bool reflection_probe_instance_has_reflection(RID p_instance) override;
|
||||
bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override;
|
||||
bool reflection_probe_instance_postprocess_step(RID p_instance) override;
|
||||
|
||||
RID decal_instance_create(RID p_decal) override;
|
||||
void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override;
|
||||
|
||||
RID lightmap_instance_create(RID p_lightmap) override;
|
||||
void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override;
|
||||
|
||||
RID voxel_gi_instance_create(RID p_voxel_gi) override;
|
||||
void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override;
|
||||
bool voxel_gi_needs_update(RID p_probe) const override;
|
||||
|
@ -333,6 +333,46 @@ AABB LightStorage::light_get_aabb(RID p_light) const {
|
||||
ERR_FAIL_V(AABB());
|
||||
}
|
||||
|
||||
/* LIGHT INSTANCE API */
|
||||
|
||||
RID LightStorage::light_instance_create(RID p_light) {
|
||||
RID li = light_instance_owner.make_rid(LightInstance());
|
||||
|
||||
LightInstance *light_instance = light_instance_owner.get_or_null(li);
|
||||
|
||||
light_instance->self = li;
|
||||
light_instance->light = p_light;
|
||||
light_instance->light_type = light_get_type(p_light);
|
||||
|
||||
return li;
|
||||
}
|
||||
|
||||
void LightStorage::light_instance_free(RID p_light_instance) {
|
||||
LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);
|
||||
ERR_FAIL_COND(!light_instance);
|
||||
light_instance_owner.free(p_light_instance);
|
||||
}
|
||||
|
||||
void LightStorage::light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) {
|
||||
LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);
|
||||
ERR_FAIL_COND(!light_instance);
|
||||
|
||||
light_instance->transform = p_transform;
|
||||
}
|
||||
|
||||
void LightStorage::light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) {
|
||||
LightInstance *light_instance = light_instance_owner.get_or_null(p_light_instance);
|
||||
ERR_FAIL_COND(!light_instance);
|
||||
|
||||
light_instance->aabb = p_aabb;
|
||||
}
|
||||
|
||||
void LightStorage::light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale, float p_range_begin, const Vector2 &p_uv_scale) {
|
||||
}
|
||||
|
||||
void LightStorage::light_instance_mark_visible(RID p_light_instance) {
|
||||
}
|
||||
|
||||
/* PROBE API */
|
||||
|
||||
RID LightStorage::reflection_probe_allocate() {
|
||||
@ -419,6 +459,53 @@ float LightStorage::reflection_probe_get_mesh_lod_threshold(RID p_probe) const {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
/* REFLECTION ATLAS */
|
||||
|
||||
RID LightStorage::reflection_atlas_create() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void LightStorage::reflection_atlas_free(RID p_ref_atlas) {
|
||||
}
|
||||
|
||||
int LightStorage::reflection_atlas_get_size(RID p_ref_atlas) const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LightStorage::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) {
|
||||
}
|
||||
|
||||
/* REFLECTION PROBE INSTANCE */
|
||||
|
||||
RID LightStorage::reflection_probe_instance_create(RID p_probe) {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void LightStorage::reflection_probe_instance_free(RID p_instance) {
|
||||
}
|
||||
|
||||
void LightStorage::reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) {
|
||||
}
|
||||
|
||||
void LightStorage::reflection_probe_release_atlas_index(RID p_instance) {
|
||||
}
|
||||
|
||||
bool LightStorage::reflection_probe_instance_needs_redraw(RID p_instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LightStorage::reflection_probe_instance_has_reflection(RID p_instance) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LightStorage::reflection_probe_instance_postprocess_step(RID p_instance) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* LIGHTMAP CAPTURE */
|
||||
|
||||
RID LightStorage::lightmap_allocate() {
|
||||
@ -484,6 +571,18 @@ float LightStorage::lightmap_get_probe_capture_update_speed() const {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* LIGHTMAP INSTANCE */
|
||||
|
||||
RID LightStorage::lightmap_instance_create(RID p_lightmap) {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void LightStorage::lightmap_instance_free(RID p_lightmap) {
|
||||
}
|
||||
|
||||
void LightStorage::lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) {
|
||||
}
|
||||
|
||||
/* LIGHT SHADOW MAPPING */
|
||||
/*
|
||||
|
||||
@ -584,4 +683,36 @@ void LightStorage::canvas_light_occluder_set_polylines(RID p_occluder, const Poo
|
||||
}
|
||||
*/
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
RID LightStorage::shadow_atlas_create() {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void LightStorage::shadow_atlas_free(RID p_atlas) {
|
||||
}
|
||||
|
||||
void LightStorage::shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits) {
|
||||
}
|
||||
|
||||
void LightStorage::shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) {
|
||||
}
|
||||
|
||||
bool LightStorage::shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void LightStorage::shadow_atlas_update(RID p_atlas) {
|
||||
}
|
||||
|
||||
void LightStorage::directional_shadow_atlas_set_size(int p_size, bool p_16_bits) {
|
||||
}
|
||||
|
||||
int LightStorage::get_directional_light_shadow_size(RID p_light_intance) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void LightStorage::set_directional_shadow_count(int p_count) {
|
||||
}
|
||||
|
||||
#endif // !GLES3_ENABLED
|
||||
|
@ -76,6 +76,33 @@ struct Light {
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
/* Light instance */
|
||||
struct LightInstance {
|
||||
RS::LightType light_type = RS::LIGHT_DIRECTIONAL;
|
||||
|
||||
AABB aabb;
|
||||
RID self;
|
||||
RID light;
|
||||
Transform3D transform;
|
||||
|
||||
Vector3 light_vector;
|
||||
Vector3 spot_vector;
|
||||
float linear_att = 0.0;
|
||||
|
||||
uint64_t shadow_pass = 0;
|
||||
uint64_t last_scene_pass = 0;
|
||||
uint64_t last_scene_shadow_pass = 0;
|
||||
uint64_t last_pass = 0;
|
||||
uint32_t cull_mask = 0;
|
||||
uint32_t light_directional_index = 0;
|
||||
|
||||
Rect2 directional_rect;
|
||||
|
||||
uint32_t gl_id = -1;
|
||||
|
||||
LightInstance() {}
|
||||
};
|
||||
|
||||
/* REFLECTION PROBE */
|
||||
|
||||
struct ReflectionProbe {
|
||||
@ -128,6 +155,9 @@ private:
|
||||
/* LIGHT */
|
||||
mutable RID_Owner<Light, true> light_owner;
|
||||
|
||||
/* Light instance */
|
||||
mutable RID_Owner<LightInstance> light_instance_owner;
|
||||
|
||||
/* REFLECTION PROBE */
|
||||
mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner;
|
||||
|
||||
@ -268,6 +298,28 @@ public:
|
||||
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
|
||||
virtual uint64_t light_get_version(RID p_light) const override;
|
||||
|
||||
/* LIGHT INSTANCE API */
|
||||
|
||||
LightInstance *get_light_instance(RID p_rid) { return light_instance_owner.get_or_null(p_rid); };
|
||||
bool owns_light_instance(RID p_rid) { return light_instance_owner.owns(p_rid); };
|
||||
|
||||
virtual RID light_instance_create(RID p_light) override;
|
||||
virtual void light_instance_free(RID p_light_instance) override;
|
||||
|
||||
virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override;
|
||||
virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override;
|
||||
virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override;
|
||||
virtual void light_instance_mark_visible(RID p_light_instance) override;
|
||||
|
||||
_FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->light_type;
|
||||
}
|
||||
_FORCE_INLINE_ uint32_t light_instance_get_gl_id(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->gl_id;
|
||||
}
|
||||
|
||||
/* PROBE API */
|
||||
|
||||
virtual RID reflection_probe_allocate() override;
|
||||
@ -298,6 +350,24 @@ public:
|
||||
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override;
|
||||
virtual bool reflection_probe_renders_shadows(RID p_probe) const override;
|
||||
|
||||
/* REFLECTION ATLAS */
|
||||
|
||||
virtual RID reflection_atlas_create() override;
|
||||
virtual void reflection_atlas_free(RID p_ref_atlas) override;
|
||||
virtual int reflection_atlas_get_size(RID p_ref_atlas) const override;
|
||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override;
|
||||
|
||||
/* REFLECTION PROBE INSTANCE */
|
||||
|
||||
virtual RID reflection_probe_instance_create(RID p_probe) override;
|
||||
virtual void reflection_probe_instance_free(RID p_instance) override;
|
||||
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override;
|
||||
virtual void reflection_probe_release_atlas_index(RID p_instance) override;
|
||||
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override;
|
||||
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override;
|
||||
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override;
|
||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override;
|
||||
|
||||
/* LIGHTMAP CAPTURE */
|
||||
|
||||
Lightmap *get_lightmap(RID p_rid) { return lightmap_owner.get_or_null(p_rid); };
|
||||
@ -338,6 +408,26 @@ public:
|
||||
RID canvas_light_occluder_create();
|
||||
void canvas_light_occluder_set_polylines(RID p_occluder, const LocalVector<Vector2> &p_lines);
|
||||
*/
|
||||
|
||||
/* LIGHTMAP INSTANCE */
|
||||
|
||||
virtual RID lightmap_instance_create(RID p_lightmap) override;
|
||||
virtual void lightmap_instance_free(RID p_lightmap) override;
|
||||
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override;
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
virtual RID shadow_atlas_create() override;
|
||||
virtual void shadow_atlas_free(RID p_atlas) override;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override;
|
||||
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override;
|
||||
|
||||
virtual void shadow_atlas_update(RID p_atlas) override;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override;
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance) override;
|
||||
virtual void set_directional_shadow_count(int p_count) override;
|
||||
};
|
||||
|
||||
} // namespace GLES3
|
||||
|
@ -1183,6 +1183,18 @@ AABB TextureStorage::decal_get_aabb(RID p_decal) const {
|
||||
return AABB();
|
||||
}
|
||||
|
||||
/* DECAL INSTANCE API */
|
||||
|
||||
RID TextureStorage::decal_instance_create(RID p_decal) {
|
||||
return RID();
|
||||
}
|
||||
|
||||
void TextureStorage::decal_instance_free(RID p_decal_instance) {
|
||||
}
|
||||
|
||||
void TextureStorage::decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) {
|
||||
}
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
GLuint TextureStorage::system_fbo = 0;
|
||||
|
@ -509,6 +509,12 @@ public:
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
|
||||
/* DECAL INSTANCE */
|
||||
|
||||
virtual RID decal_instance_create(RID p_decal) override;
|
||||
virtual void decal_instance_free(RID p_decal_instance) override;
|
||||
virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override;
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
static GLuint system_fbo;
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
|
||||
virtual RID fog_volume_allocate() override { return RID(); }
|
||||
virtual void fog_volume_initialize(RID p_rid) override {}
|
||||
virtual void fog_free(RID p_rid) override {}
|
||||
virtual void fog_volume_free(RID p_rid) override {}
|
||||
|
||||
virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override {}
|
||||
virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override {}
|
||||
|
@ -93,17 +93,6 @@ public:
|
||||
|
||||
uint32_t geometry_instance_get_pair_mask() override { return 0; }
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
RID shadow_atlas_create() override { return RID(); }
|
||||
void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override {}
|
||||
void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override {}
|
||||
bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override { return false; }
|
||||
|
||||
void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override {}
|
||||
int get_directional_light_shadow_size(RID p_light_intance) override { return 0; }
|
||||
void set_directional_shadow_count(int p_count) override {}
|
||||
|
||||
/* SDFGI UPDATE */
|
||||
|
||||
void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) override {}
|
||||
@ -143,36 +132,12 @@ public:
|
||||
void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override {}
|
||||
void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) override {}
|
||||
|
||||
RID light_instance_create(RID p_light) override { return RID(); }
|
||||
void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override {}
|
||||
void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override {}
|
||||
void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {}
|
||||
void light_instance_mark_visible(RID p_light_instance) override {}
|
||||
|
||||
RID fog_volume_instance_create(RID p_fog_volume) override { return RID(); }
|
||||
void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) override {}
|
||||
void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) override {}
|
||||
RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const override { return RID(); }
|
||||
Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const override { return Vector3(); }
|
||||
|
||||
RID reflection_atlas_create() override { return RID(); }
|
||||
int reflection_atlas_get_size(RID p_ref_atlas) const override { return 0; }
|
||||
void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override {}
|
||||
|
||||
RID reflection_probe_instance_create(RID p_probe) override { return RID(); }
|
||||
void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override {}
|
||||
void reflection_probe_release_atlas_index(RID p_instance) override {}
|
||||
bool reflection_probe_instance_needs_redraw(RID p_instance) override { return false; }
|
||||
bool reflection_probe_instance_has_reflection(RID p_instance) override { return false; }
|
||||
bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override { return false; }
|
||||
bool reflection_probe_instance_postprocess_step(RID p_instance) override { return true; }
|
||||
|
||||
RID decal_instance_create(RID p_decal) override { return RID(); }
|
||||
void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override {}
|
||||
|
||||
RID lightmap_instance_create(RID p_lightmap) override { return RID(); }
|
||||
void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override {}
|
||||
|
||||
RID voxel_gi_instance_create(RID p_voxel_gi) override { return RID(); }
|
||||
void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) override {}
|
||||
bool voxel_gi_needs_update(RID p_probe) const override { return false; }
|
||||
|
@ -81,6 +81,15 @@ public:
|
||||
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) override { return 0; }
|
||||
virtual uint64_t light_get_version(RID p_light) const override { return 0; }
|
||||
|
||||
/* LIGHT INSTANCE API */
|
||||
|
||||
RID light_instance_create(RID p_light) override { return RID(); }
|
||||
void light_instance_free(RID p_light) override {}
|
||||
void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override {}
|
||||
void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override {}
|
||||
void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override {}
|
||||
void light_instance_mark_visible(RID p_light_instance) override {}
|
||||
|
||||
/* PROBE API */
|
||||
virtual RID reflection_probe_allocate() override { return RID(); }
|
||||
virtual void reflection_probe_initialize(RID p_rid) override {}
|
||||
@ -110,7 +119,26 @@ public:
|
||||
virtual float reflection_probe_get_origin_max_distance(RID p_probe) const override { return 0.0; }
|
||||
virtual bool reflection_probe_renders_shadows(RID p_probe) const override { return false; }
|
||||
|
||||
/* REFLECTION ATLAS */
|
||||
|
||||
virtual RID reflection_atlas_create() override { return RID(); }
|
||||
virtual void reflection_atlas_free(RID p_ref_atlas) override {}
|
||||
virtual int reflection_atlas_get_size(RID p_ref_atlas) const override { return 0; }
|
||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override {}
|
||||
|
||||
/* REFLECTION PROBE INSTANCE */
|
||||
|
||||
virtual RID reflection_probe_instance_create(RID p_probe) override { return RID(); }
|
||||
virtual void reflection_probe_instance_free(RID p_instance) override {}
|
||||
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override {}
|
||||
virtual void reflection_probe_release_atlas_index(RID p_instance) override {}
|
||||
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override { return false; }
|
||||
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override { return false; }
|
||||
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override { return false; }
|
||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override { return true; }
|
||||
|
||||
/* LIGHTMAP CAPTURE */
|
||||
|
||||
virtual RID lightmap_allocate() override { return RID(); }
|
||||
virtual void lightmap_initialize(RID p_rid) override {}
|
||||
virtual void lightmap_free(RID p_rid) override {}
|
||||
@ -129,6 +157,25 @@ public:
|
||||
virtual bool lightmap_is_interior(RID p_lightmap) const override { return false; }
|
||||
virtual void lightmap_set_probe_capture_update_speed(float p_speed) override {}
|
||||
virtual float lightmap_get_probe_capture_update_speed() const override { return 0; }
|
||||
|
||||
/* LIGHTMAP INSTANCE */
|
||||
|
||||
RID lightmap_instance_create(RID p_lightmap) override { return RID(); }
|
||||
void lightmap_instance_free(RID p_lightmap) override {}
|
||||
void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override {}
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
virtual RID shadow_atlas_create() override { return RID(); }
|
||||
virtual void shadow_atlas_free(RID p_atlas) override {}
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override {}
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override {}
|
||||
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) override { return false; }
|
||||
|
||||
virtual void shadow_atlas_update(RID p_atlas) override {}
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override {}
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance) override { return 0; }
|
||||
virtual void set_directional_shadow_count(int p_count) override {}
|
||||
};
|
||||
|
||||
} // namespace RendererDummy
|
||||
|
@ -146,6 +146,12 @@ public:
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) override {}
|
||||
|
||||
/* DECAL INSTANCE */
|
||||
|
||||
virtual RID decal_instance_create(RID p_decal) override { return RID(); }
|
||||
virtual void decal_instance_free(RID p_decal_instance) override {}
|
||||
virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override {}
|
||||
|
||||
/* RENDER TARGET */
|
||||
|
||||
virtual RID render_target_create() override { return RID(); }
|
||||
|
@ -41,7 +41,7 @@ public:
|
||||
|
||||
virtual RID fog_volume_allocate() = 0;
|
||||
virtual void fog_volume_initialize(RID p_rid) = 0;
|
||||
virtual void fog_free(RID p_rid) = 0;
|
||||
virtual void fog_volume_free(RID p_rid) = 0;
|
||||
|
||||
virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) = 0;
|
||||
virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) = 0;
|
||||
|
@ -29,7 +29,8 @@
|
||||
/*************************************************************************/
|
||||
|
||||
#include "fsr.h"
|
||||
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
|
||||
#include "../storage_rd/material_storage.h"
|
||||
#include "../uniform_set_cache_rd.h"
|
||||
|
||||
using namespace RendererRD;
|
||||
|
||||
|
@ -31,11 +31,10 @@
|
||||
#ifndef FSR_RD_H
|
||||
#define FSR_RD_H
|
||||
|
||||
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/effects/fsr_upscale.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
|
||||
#include "../pipeline_cache_rd.h"
|
||||
#include "../shaders/effects/fsr_upscale.glsl.gen.h"
|
||||
#include "../storage_rd/render_scene_buffers_rd.h"
|
||||
#include "servers/rendering/renderer_scene_render.h"
|
||||
|
||||
#include "servers/rendering_server.h"
|
||||
|
||||
namespace RendererRD {
|
||||
|
@ -57,12 +57,19 @@ void Fog::fog_volume_initialize(RID p_rid) {
|
||||
fog_volume_owner.initialize_rid(p_rid, FogVolume());
|
||||
}
|
||||
|
||||
void Fog::fog_free(RID p_rid) {
|
||||
void Fog::fog_volume_free(RID p_rid) {
|
||||
FogVolume *fog_volume = fog_volume_owner.get_or_null(p_rid);
|
||||
fog_volume->dependency.deleted_notify(p_rid);
|
||||
fog_volume_owner.free(p_rid);
|
||||
}
|
||||
|
||||
Dependency *Fog::fog_volume_get_dependency(RID p_fog_volume) const {
|
||||
FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
|
||||
ERR_FAIL_NULL_V(fog_volume, nullptr);
|
||||
|
||||
return &fog_volume->dependency;
|
||||
}
|
||||
|
||||
void Fog::fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) {
|
||||
FogVolume *fog_volume = fog_volume_owner.get_or_null(p_fog_volume);
|
||||
ERR_FAIL_COND(!fog_volume);
|
||||
|
@ -46,7 +46,9 @@
|
||||
namespace RendererRD {
|
||||
|
||||
class Fog : public RendererFog {
|
||||
public:
|
||||
private:
|
||||
static Fog *singleton;
|
||||
|
||||
/* FOG VOLUMES */
|
||||
|
||||
struct FogVolume {
|
||||
@ -58,16 +60,14 @@ public:
|
||||
Dependency dependency;
|
||||
};
|
||||
|
||||
mutable RID_Owner<FogVolume, true> fog_volume_owner;
|
||||
|
||||
struct FogVolumeInstance {
|
||||
RID volume;
|
||||
Transform3D transform;
|
||||
bool active = false;
|
||||
};
|
||||
|
||||
private:
|
||||
static Fog *singleton;
|
||||
|
||||
mutable RID_Owner<FogVolume, true> fog_volume_owner;
|
||||
mutable RID_Owner<FogVolumeInstance> fog_volume_instance_owner;
|
||||
|
||||
/* Volumetric Fog */
|
||||
@ -240,12 +240,12 @@ public:
|
||||
|
||||
/* FOG VOLUMES */
|
||||
|
||||
FogVolume *get_fog_volume(RID p_rid) { return fog_volume_owner.get_or_null(p_rid); };
|
||||
bool owns_fog_volume(RID p_rid) { return fog_volume_owner.owns(p_rid); };
|
||||
|
||||
virtual RID fog_volume_allocate() override;
|
||||
virtual void fog_volume_initialize(RID p_rid) override;
|
||||
virtual void fog_free(RID p_rid) override;
|
||||
virtual void fog_volume_free(RID p_rid) override;
|
||||
Dependency *fog_volume_get_dependency(RID p_fog_volume) const;
|
||||
|
||||
virtual void fog_volume_set_shape(RID p_fog_volume, RS::FogVolumeShape p_shape) override;
|
||||
virtual void fog_volume_set_extents(RID p_fog_volume, const Vector3 &p_extents) override;
|
||||
@ -257,12 +257,35 @@ public:
|
||||
|
||||
/* FOG VOLUMES INSTANCE */
|
||||
|
||||
FogVolumeInstance *get_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.get_or_null(p_rid); };
|
||||
bool owns_fog_volume_instance(RID p_rid) { return fog_volume_instance_owner.owns(p_rid); };
|
||||
|
||||
RID fog_volume_instance_create(RID p_fog_volume);
|
||||
void fog_instance_free(RID p_rid);
|
||||
|
||||
void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) {
|
||||
Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);
|
||||
ERR_FAIL_COND(!fvi);
|
||||
fvi->transform = p_transform;
|
||||
}
|
||||
|
||||
void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) {
|
||||
Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);
|
||||
ERR_FAIL_COND(!fvi);
|
||||
fvi->active = p_active;
|
||||
}
|
||||
|
||||
RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const {
|
||||
Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);
|
||||
ERR_FAIL_COND_V(!fvi, RID());
|
||||
return fvi->volume;
|
||||
}
|
||||
|
||||
Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const {
|
||||
Fog::FogVolumeInstance *fvi = fog_volume_instance_owner.get_or_null(p_fog_volume_instance);
|
||||
ERR_FAIL_COND_V(!fvi, Vector3());
|
||||
return fvi->transform.get_origin();
|
||||
}
|
||||
|
||||
/* Volumetric FOG */
|
||||
class VolumetricFog : public RenderBufferCustomDataRD {
|
||||
GDCLASS(VolumetricFog, RenderBufferCustomDataRD)
|
||||
|
@ -1798,7 +1798,8 @@ void GI::SDFGI::debug_probes(RID p_framebuffer, const uint32_t p_view_count, con
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
|
||||
void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render) {
|
||||
void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data) {
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
/* Update general SDFGI Buffer */
|
||||
|
||||
SDFGIData sdfgi_data;
|
||||
@ -1881,40 +1882,43 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r
|
||||
|
||||
SDFGIShader::Light lights[SDFGI::MAX_DYNAMIC_LIGHTS];
|
||||
uint32_t idx = 0;
|
||||
for (uint32_t j = 0; j < (uint32_t)p_scene_render->render_state.sdfgi_update_data->directional_lights->size(); j++) {
|
||||
for (uint32_t j = 0; j < (uint32_t)p_render_data->sdfgi_update_data->directional_lights->size(); j++) {
|
||||
if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {
|
||||
break;
|
||||
}
|
||||
|
||||
RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_scene_render->render_state.sdfgi_update_data->directional_lights->get(j));
|
||||
ERR_CONTINUE(!li);
|
||||
RID light_instance = p_render_data->sdfgi_update_data->directional_lights->get(j);
|
||||
ERR_CONTINUE(!light_storage->owns_light_instance(light_instance));
|
||||
|
||||
if (RSG::light_storage->light_directional_get_sky_mode(li->light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
|
||||
RID light = light_storage->light_instance_get_base_light(light_instance);
|
||||
Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance);
|
||||
|
||||
if (RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector3 dir = -li->transform.basis.get_column(Vector3::AXIS_Z);
|
||||
Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z);
|
||||
dir.y *= y_mult;
|
||||
dir.normalize();
|
||||
lights[idx].direction[0] = dir.x;
|
||||
lights[idx].direction[1] = dir.y;
|
||||
lights[idx].direction[2] = dir.z;
|
||||
Color color = RSG::light_storage->light_get_color(li->light);
|
||||
Color color = RSG::light_storage->light_get_color(light);
|
||||
color = color.srgb_to_linear();
|
||||
lights[idx].color[0] = color.r;
|
||||
lights[idx].color[1] = color.g;
|
||||
lights[idx].color[2] = color.b;
|
||||
lights[idx].type = RS::LIGHT_DIRECTIONAL;
|
||||
lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
|
||||
if (p_scene_render->is_using_physical_light_units()) {
|
||||
lights[idx].energy *= RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INTENSITY);
|
||||
lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
|
||||
if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {
|
||||
lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);
|
||||
}
|
||||
|
||||
if (p_render_data->camera_attributes.is_valid()) {
|
||||
lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
|
||||
}
|
||||
|
||||
lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light);
|
||||
lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light);
|
||||
|
||||
idx++;
|
||||
}
|
||||
@ -1923,45 +1927,49 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r
|
||||
cascade_aabb.position = Vector3((Vector3i(1, 1, 1) * -int32_t(cascade_size >> 1) + cascade.position)) * cascade.cell_size;
|
||||
cascade_aabb.size = Vector3(1, 1, 1) * cascade_size * cascade.cell_size;
|
||||
|
||||
for (uint32_t j = 0; j < p_scene_render->render_state.sdfgi_update_data->positional_light_count; j++) {
|
||||
for (uint32_t j = 0; j < p_render_data->sdfgi_update_data->positional_light_count; j++) {
|
||||
if (idx == SDFGI::MAX_DYNAMIC_LIGHTS) {
|
||||
break;
|
||||
}
|
||||
|
||||
RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_scene_render->render_state.sdfgi_update_data->positional_light_instances[j]);
|
||||
ERR_CONTINUE(!li);
|
||||
RID light_instance = p_render_data->sdfgi_update_data->positional_light_instances[j];
|
||||
ERR_CONTINUE(!light_storage->owns_light_instance(light_instance));
|
||||
|
||||
uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(li->light);
|
||||
RID light = light_storage->light_instance_get_base_light(light_instance);
|
||||
AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance);
|
||||
Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance);
|
||||
|
||||
uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light);
|
||||
if (i > max_sdfgi_cascade) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cascade_aabb.intersects(li->aabb)) {
|
||||
if (!cascade_aabb.intersects(light_aabb)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Vector3 dir = -li->transform.basis.get_column(Vector3::AXIS_Z);
|
||||
Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z);
|
||||
//faster to not do this here
|
||||
//dir.y *= y_mult;
|
||||
//dir.normalize();
|
||||
lights[idx].direction[0] = dir.x;
|
||||
lights[idx].direction[1] = dir.y;
|
||||
lights[idx].direction[2] = dir.z;
|
||||
Vector3 pos = li->transform.origin;
|
||||
Vector3 pos = light_transform.origin;
|
||||
pos.y *= y_mult;
|
||||
lights[idx].position[0] = pos.x;
|
||||
lights[idx].position[1] = pos.y;
|
||||
lights[idx].position[2] = pos.z;
|
||||
Color color = RSG::light_storage->light_get_color(li->light);
|
||||
Color color = RSG::light_storage->light_get_color(light);
|
||||
color = color.srgb_to_linear();
|
||||
lights[idx].color[0] = color.r;
|
||||
lights[idx].color[1] = color.g;
|
||||
lights[idx].color[2] = color.b;
|
||||
lights[idx].type = RSG::light_storage->light_get_type(li->light);
|
||||
lights[idx].type = RSG::light_storage->light_get_type(light);
|
||||
|
||||
lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
|
||||
if (p_scene_render->is_using_physical_light_units()) {
|
||||
lights[idx].energy *= RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INTENSITY);
|
||||
lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
|
||||
if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {
|
||||
lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);
|
||||
|
||||
// Convert from Luminous Power to Luminous Intensity
|
||||
if (lights[idx].type == RS::LIGHT_OMNI) {
|
||||
@ -1977,11 +1985,11 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r
|
||||
lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
|
||||
}
|
||||
|
||||
lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light);
|
||||
lights[idx].attenuation = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
|
||||
lights[idx].radius = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
|
||||
lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
|
||||
lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light);
|
||||
lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
|
||||
lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE);
|
||||
lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));
|
||||
lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
|
||||
idx++;
|
||||
}
|
||||
@ -1994,7 +2002,7 @@ void GI::SDFGI::pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_r
|
||||
}
|
||||
}
|
||||
|
||||
void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render, float p_exposure_normalization) {
|
||||
void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, float p_exposure_normalization) {
|
||||
//print_line("rendering region " + itos(p_region));
|
||||
ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but...
|
||||
AABB bounds;
|
||||
@ -2015,7 +2023,7 @@ void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_
|
||||
}
|
||||
|
||||
//print_line("rendering cascade " + itos(p_region) + " objects: " + itos(p_cull_count) + " bounds: " + bounds + " from: " + from + " size: " + size + " cell size: " + rtos(cascades[cascade].cell_size));
|
||||
p_scene_render->_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, render_albedo, render_emission, render_emission_aniso, render_geom_facing, p_exposure_normalization);
|
||||
RendererSceneRenderRD::get_singleton()->_render_sdfgi(p_render_buffers, from, size, bounds, p_instances, render_albedo, render_emission, render_emission_aniso, render_geom_facing, p_exposure_normalization);
|
||||
|
||||
if (cascade_next != cascade) {
|
||||
RD::get_singleton()->draw_command_begin_label("SDFGI Pre-Process Cascade");
|
||||
@ -2353,9 +2361,11 @@ void GI::SDFGI::render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_
|
||||
}
|
||||
}
|
||||
|
||||
void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render) {
|
||||
void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result) {
|
||||
ERR_FAIL_COND(p_render_buffers.is_null()); // we wouldn't be here if this failed but...
|
||||
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
|
||||
RD::get_singleton()->draw_command_begin_label("SDFGI Render Static Lights");
|
||||
|
||||
update_cascades();
|
||||
@ -2381,21 +2391,25 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderScen
|
||||
break;
|
||||
}
|
||||
|
||||
RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_positional_light_cull_result[i][j]);
|
||||
ERR_CONTINUE(!li);
|
||||
RID light_instance = p_positional_light_cull_result[i][j];
|
||||
ERR_CONTINUE(!light_storage->owns_light_instance(light_instance));
|
||||
|
||||
uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(li->light);
|
||||
RID light = light_storage->light_instance_get_base_light(light_instance);
|
||||
AABB light_aabb = light_storage->light_instance_get_base_aabb(light_instance);
|
||||
Transform3D light_transform = light_storage->light_instance_get_base_transform(light_instance);
|
||||
|
||||
uint32_t max_sdfgi_cascade = RSG::light_storage->light_get_max_sdfgi_cascade(light);
|
||||
if (p_cascade_indices[i] > max_sdfgi_cascade) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!cascade_aabb.intersects(li->aabb)) {
|
||||
if (!cascade_aabb.intersects(light_aabb)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
lights[idx].type = RSG::light_storage->light_get_type(li->light);
|
||||
lights[idx].type = RSG::light_storage->light_get_type(light);
|
||||
|
||||
Vector3 dir = -li->transform.basis.get_column(Vector3::AXIS_Z);
|
||||
Vector3 dir = -light_transform.basis.get_column(Vector3::AXIS_Z);
|
||||
if (lights[idx].type == RS::LIGHT_DIRECTIONAL) {
|
||||
dir.y *= y_mult; //only makes sense for directional
|
||||
dir.normalize();
|
||||
@ -2403,20 +2417,20 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderScen
|
||||
lights[idx].direction[0] = dir.x;
|
||||
lights[idx].direction[1] = dir.y;
|
||||
lights[idx].direction[2] = dir.z;
|
||||
Vector3 pos = li->transform.origin;
|
||||
Vector3 pos = light_transform.origin;
|
||||
pos.y *= y_mult;
|
||||
lights[idx].position[0] = pos.x;
|
||||
lights[idx].position[1] = pos.y;
|
||||
lights[idx].position[2] = pos.z;
|
||||
Color color = RSG::light_storage->light_get_color(li->light);
|
||||
Color color = RSG::light_storage->light_get_color(light);
|
||||
color = color.srgb_to_linear();
|
||||
lights[idx].color[0] = color.r;
|
||||
lights[idx].color[1] = color.g;
|
||||
lights[idx].color[2] = color.b;
|
||||
|
||||
lights[idx].energy = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
|
||||
if (p_scene_render->is_using_physical_light_units()) {
|
||||
lights[idx].energy *= RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_INTENSITY);
|
||||
lights[idx].energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
|
||||
if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {
|
||||
lights[idx].energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);
|
||||
|
||||
// Convert from Luminous Power to Luminous Intensity
|
||||
if (lights[idx].type == RS::LIGHT_OMNI) {
|
||||
@ -2432,11 +2446,11 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderScen
|
||||
lights[idx].energy *= RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
|
||||
}
|
||||
|
||||
lights[idx].has_shadow = RSG::light_storage->light_has_shadow(li->light);
|
||||
lights[idx].attenuation = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_ATTENUATION);
|
||||
lights[idx].radius = RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_RANGE);
|
||||
lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ANGLE)));
|
||||
lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(li->light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
lights[idx].has_shadow = RSG::light_storage->light_has_shadow(light);
|
||||
lights[idx].attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
|
||||
lights[idx].radius = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_RANGE);
|
||||
lights[idx].cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));
|
||||
lights[idx].inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
|
||||
idx++;
|
||||
}
|
||||
@ -2492,7 +2506,8 @@ void GI::SDFGI::render_static_lights(RenderDataRD *p_render_data, Ref<RenderScen
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// VoxelGIInstance
|
||||
|
||||
void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
|
||||
void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) {
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
|
||||
|
||||
uint32_t data_version = gi->voxel_gi_get_data_version(probe);
|
||||
@ -2834,7 +2849,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
|
||||
last_probe_data_version = data_version;
|
||||
p_update_light_instances = true; //just in case
|
||||
|
||||
p_scene_render->_base_uniforms_changed();
|
||||
RendererSceneRenderRD::get_singleton()->base_uniforms_changed();
|
||||
}
|
||||
|
||||
// UDPDATE TIME
|
||||
@ -2857,7 +2872,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
|
||||
for (uint32_t i = 0; i < light_count; i++) {
|
||||
VoxelGILight &l = gi->voxel_gi_lights[i];
|
||||
RID light_instance = p_light_instances[i];
|
||||
RID light = p_scene_render->light_instance_get_base_light(light_instance);
|
||||
RID light = light_storage->light_instance_get_base_light(light_instance);
|
||||
|
||||
l.type = RSG::light_storage->light_get_type(light);
|
||||
if (l.type == RS::LIGHT_DIRECTIONAL && RSG::light_storage->light_directional_get_sky_mode(light) == RS::LIGHT_DIRECTIONAL_SKY_MODE_SKY_ONLY) {
|
||||
@ -2868,7 +2883,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
|
||||
l.attenuation = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ATTENUATION);
|
||||
l.energy = RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_ENERGY) * RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INDIRECT_ENERGY);
|
||||
|
||||
if (p_scene_render->is_using_physical_light_units()) {
|
||||
if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {
|
||||
l.energy *= RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_INTENSITY);
|
||||
|
||||
l.energy *= gi->voxel_gi_get_baked_exposure_normalization(probe);
|
||||
@ -2892,7 +2907,7 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
|
||||
l.cos_spot_angle = Math::cos(Math::deg_to_rad(RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ANGLE)));
|
||||
l.inv_spot_attenuation = 1.0f / RSG::light_storage->light_get_param(light, RS::LIGHT_PARAM_SPOT_ATTENUATION);
|
||||
|
||||
Transform3D xform = p_scene_render->light_instance_get_base_transform(light_instance);
|
||||
Transform3D xform = light_storage->light_instance_get_base_transform(light_instance);
|
||||
|
||||
Vector3 pos = to_probe_xform.xform(xform.origin);
|
||||
Vector3 dir = to_probe_xform.basis.xform(-xform.basis.get_column(2)).normalized();
|
||||
@ -3087,17 +3102,17 @@ void GI::VoxelGIInstance::update(bool p_update_light_instances, const Vector<RID
|
||||
Projection cm;
|
||||
cm.set_orthogonal(-rect.size.width / 2, rect.size.width / 2, -rect.size.height / 2, rect.size.height / 2, 0.0001, aabb.size[z_axis]);
|
||||
|
||||
if (p_scene_render->cull_argument.size() == 0) {
|
||||
p_scene_render->cull_argument.push_back(nullptr);
|
||||
if (RendererSceneRenderRD::get_singleton()->cull_argument.size() == 0) {
|
||||
RendererSceneRenderRD::get_singleton()->cull_argument.push_back(nullptr);
|
||||
}
|
||||
p_scene_render->cull_argument[0] = instance;
|
||||
RendererSceneRenderRD::get_singleton()->cull_argument[0] = instance;
|
||||
|
||||
float exposure_normalization = 1.0;
|
||||
if (p_scene_render->is_using_physical_light_units()) {
|
||||
if (RendererSceneRenderRD::get_singleton()->is_using_physical_light_units()) {
|
||||
exposure_normalization = gi->voxel_gi_get_baked_exposure_normalization(probe);
|
||||
}
|
||||
|
||||
p_scene_render->_render_material(to_world_xform * xform, cm, true, p_scene_render->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size), exposure_normalization);
|
||||
RendererSceneRenderRD::get_singleton()->_render_material(to_world_xform * xform, cm, true, RendererSceneRenderRD::get_singleton()->cull_argument, dynamic_maps[0].fb, Rect2i(Vector2i(), rect.size), exposure_normalization);
|
||||
|
||||
VoxelGIDynamicPushConstant push_constant;
|
||||
memset(&push_constant, 0, sizeof(VoxelGIDynamicPushConstant));
|
||||
@ -3591,7 +3606,7 @@ Ref<GI::SDFGI> GI::create_sdfgi(RID p_env, const Vector3 &p_world_position, uint
|
||||
return sdfgi;
|
||||
}
|
||||
|
||||
void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render) {
|
||||
void GI::setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used) {
|
||||
ERR_FAIL_COND(p_render_buffers.is_null());
|
||||
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
@ -4051,11 +4066,11 @@ bool GI::voxel_gi_needs_update(RID p_probe) const {
|
||||
return voxel_gi->last_probe_version != voxel_gi_get_version(voxel_gi->probe);
|
||||
}
|
||||
|
||||
void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render) {
|
||||
void GI::voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects) {
|
||||
VoxelGIInstance *voxel_gi = voxel_gi_instance_owner.get_or_null(p_probe);
|
||||
ERR_FAIL_COND(!voxel_gi);
|
||||
|
||||
voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects, p_scene_render);
|
||||
voxel_gi->update(p_update_light_instances, p_light_instances, p_dynamic_objects);
|
||||
}
|
||||
|
||||
void GI::debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha) {
|
||||
|
@ -145,7 +145,7 @@ public:
|
||||
|
||||
Transform3D transform;
|
||||
|
||||
void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render);
|
||||
void update(bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects);
|
||||
void debug(RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
|
||||
void free_resources();
|
||||
};
|
||||
@ -687,9 +687,9 @@ public:
|
||||
void debug_draw(uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, int p_width, int p_height, RID p_render_target, RID p_texture, const Vector<RID> &p_texture_views);
|
||||
void debug_probes(RID p_framebuffer, const uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth);
|
||||
|
||||
void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data, RendererSceneRenderRD *p_scene_render);
|
||||
void render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, RendererSceneRenderRD *p_scene_render, float p_exposure_normalization);
|
||||
void render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result, RendererSceneRenderRD *p_scene_render);
|
||||
void pre_process_gi(const Transform3D &p_transform, RenderDataRD *p_render_data);
|
||||
void render_region(Ref<RenderSceneBuffersRD> p_render_buffers, int p_region, const PagedArray<RenderGeometryInstance *> &p_instances, float p_exposure_normalization);
|
||||
void render_static_lights(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result);
|
||||
};
|
||||
|
||||
RS::EnvironmentSDFGIRayCount sdfgi_ray_count = RS::ENV_SDFGI_RAY_COUNT_16;
|
||||
@ -812,13 +812,13 @@ public:
|
||||
|
||||
Ref<SDFGI> create_sdfgi(RID p_env, const Vector3 &p_world_position, uint32_t p_requested_history_size);
|
||||
|
||||
void setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used, RendererSceneRenderRD *p_scene_render);
|
||||
void setup_voxel_gi_instances(RenderDataRD *p_render_data, Ref<RenderSceneBuffersRD> p_render_buffers, const Transform3D &p_transform, const PagedArray<RID> &p_voxel_gi_instances, uint32_t &r_voxel_gi_instances_used);
|
||||
void process_gi(Ref<RenderSceneBuffersRD> p_render_buffers, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer, RID p_environment, uint32_t p_view_count, const Projection *p_projections, const Vector3 *p_eye_offsets, const Transform3D &p_cam_transform, const PagedArray<RID> &p_voxel_gi_instances);
|
||||
|
||||
RID voxel_gi_instance_create(RID p_base);
|
||||
void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform);
|
||||
bool voxel_gi_needs_update(RID p_probe) const;
|
||||
void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects, RendererSceneRenderRD *p_scene_render);
|
||||
void voxel_gi_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RenderGeometryInstance *> &p_dynamic_objects);
|
||||
void debug_voxel_gi(RID p_voxel_gi, RD::DrawListID p_draw_list, RID p_framebuffer, const Projection &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
|
||||
};
|
||||
|
||||
|
@ -1200,18 +1200,17 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P
|
||||
// This can't be done in RenderSceneRenderRD::_setup lights because that needs to be called
|
||||
// after the depth prepass, but this runs before the depth prepass
|
||||
for (int i = 0; i < (int)p_lights.size(); i++) {
|
||||
RendererSceneRenderRD::LightInstance *li = p_scene_render->light_instance_owner.get_or_null(p_lights[i]);
|
||||
if (!li) {
|
||||
if (!light_storage->owns_light_instance(p_lights[i])) {
|
||||
continue;
|
||||
}
|
||||
RID base = li->light;
|
||||
RID base = light_storage->light_instance_get_base_light(p_lights[i]);
|
||||
|
||||
ERR_CONTINUE(base.is_null());
|
||||
|
||||
RS::LightType type = light_storage->light_get_type(base);
|
||||
if (type == RS::LIGHT_DIRECTIONAL && light_storage->light_directional_get_sky_mode(base) != RS::LIGHT_DIRECTIONAL_SKY_MODE_LIGHT_ONLY) {
|
||||
SkyDirectionalLightData &sky_light_data = sky_scene_state.directional_lights[sky_scene_state.ubo.directional_light_count];
|
||||
Transform3D light_transform = li->transform;
|
||||
Transform3D light_transform = light_storage->light_instance_get_base_transform(p_lights[i]);
|
||||
Vector3 world_direction = light_transform.basis.xform(Vector3(0, 0, 1)).normalized();
|
||||
|
||||
sky_light_data.direction[0] = world_direction.x;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -32,7 +32,9 @@
|
||||
#define RENDER_FORWARD_CLUSTERED_H
|
||||
|
||||
#include "core/templates/paged_allocator.h"
|
||||
#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
|
||||
#include "servers/rendering/renderer_rd/effects/resolve.h"
|
||||
#include "servers/rendering/renderer_rd/effects/ss_effects.h"
|
||||
#include "servers/rendering/renderer_rd/effects/taa.h"
|
||||
#include "servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h"
|
||||
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
|
||||
@ -99,7 +101,21 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
||||
RD::TextureSamples texture_samples = RD::TEXTURE_SAMPLES_1;
|
||||
|
||||
public:
|
||||
//for rendering, may be MSAAd
|
||||
ClusterBuilderRD *cluster_builder = nullptr;
|
||||
|
||||
struct SSEffectsData {
|
||||
RID linear_depth;
|
||||
Vector<RID> linear_depth_slices;
|
||||
|
||||
RID downsample_uniform_set;
|
||||
|
||||
Projection last_frame_projection;
|
||||
Transform3D last_frame_transform;
|
||||
|
||||
RendererRD::SSEffects::SSAORenderBuffers ssao;
|
||||
RendererRD::SSEffects::SSILRenderBuffers ssil;
|
||||
RendererRD::SSEffects::SSRRenderBuffers ssr;
|
||||
} ss_effects_data;
|
||||
|
||||
enum DepthFrameBufferType {
|
||||
DEPTH_FB,
|
||||
@ -139,6 +155,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
||||
RID get_depth_fb(DepthFrameBufferType p_type = DEPTH_FB);
|
||||
RID get_specular_only_fb();
|
||||
|
||||
RID get_ao_texture() const { return ss_effects_data.ssao.ao_final; }
|
||||
RID get_ssil_texture() const { return ss_effects_data.ssil.ssil_final; }
|
||||
|
||||
virtual void configure(RenderSceneBuffersRD *p_render_buffers) override;
|
||||
virtual void free_data() override;
|
||||
};
|
||||
@ -149,10 +168,6 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
||||
|
||||
uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
|
||||
|
||||
virtual void _base_uniforms_changed() override;
|
||||
virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
|
||||
virtual RID _render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
|
||||
|
||||
bool base_uniform_set_updated = false;
|
||||
void _update_render_base_uniform_set();
|
||||
RID _setup_sdfgi_render_pass_uniform_set(RID p_albedo_texture, RID p_emission_texture, RID p_emission_aniso_texture, RID p_geom_facing_texture);
|
||||
@ -558,16 +573,54 @@ class RenderForwardClustered : public RendererSceneRenderRD {
|
||||
|
||||
virtual void _update_shader_quality_settings() override;
|
||||
|
||||
/* Effects */
|
||||
|
||||
RendererRD::Resolve *resolve_effects = nullptr;
|
||||
RendererRD::TAA *taa = nullptr;
|
||||
RendererRD::SSEffects *ss_effects = nullptr;
|
||||
|
||||
/* Cluster builder */
|
||||
|
||||
ClusterBuilderSharedDataRD cluster_builder_shared;
|
||||
ClusterBuilderRD *current_cluster_builder = nullptr;
|
||||
|
||||
/* SDFGI */
|
||||
void _update_sdfgi(RenderDataRD *p_render_data);
|
||||
|
||||
/* Volumetric fog */
|
||||
RID shadow_sampler;
|
||||
|
||||
void _update_volumetric_fog(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
|
||||
|
||||
/* Render shadows */
|
||||
|
||||
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
|
||||
void _render_shadow_begin();
|
||||
void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
|
||||
void _render_shadow_process();
|
||||
void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL);
|
||||
|
||||
/* Render Scene */
|
||||
void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection);
|
||||
void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform);
|
||||
void _copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers);
|
||||
void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer);
|
||||
void _process_ssr(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive);
|
||||
void _process_sss(Ref<RenderSceneBuffersRD> p_render_buffers, const Projection &p_camera);
|
||||
|
||||
/* Debug */
|
||||
void _debug_draw_cluster(Ref<RenderSceneBuffersRD> p_render_buffers);
|
||||
|
||||
protected:
|
||||
virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
|
||||
/* setup */
|
||||
|
||||
virtual void _render_shadow_begin() override;
|
||||
virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr) override;
|
||||
virtual void _render_shadow_process() override;
|
||||
virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override;
|
||||
virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
|
||||
virtual RID _render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
|
||||
|
||||
/* Rendering */
|
||||
|
||||
virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
|
||||
virtual void _render_buffers_debug_draw(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer) override;
|
||||
|
||||
virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region, float p_exposure_normalization) override;
|
||||
virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
|
||||
@ -577,6 +630,15 @@ protected:
|
||||
public:
|
||||
static RenderForwardClustered *get_singleton() { return singleton; }
|
||||
|
||||
ClusterBuilderSharedDataRD *get_cluster_builder_shared() { return &cluster_builder_shared; }
|
||||
RendererRD::SSEffects *get_ss_effects() { return ss_effects; }
|
||||
|
||||
/* callback from updating our lighting UBOs, used to populate cluster builder */
|
||||
virtual void setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_extents) override;
|
||||
virtual void setup_added_light(const RS::LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture) override;
|
||||
virtual void setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_extents) override;
|
||||
|
||||
virtual void base_uniforms_changed() override;
|
||||
_FORCE_INLINE_ virtual void update_uniform_sets() override {
|
||||
base_uniform_set_updated = true;
|
||||
_update_render_base_uniform_set();
|
||||
|
@ -39,7 +39,7 @@
|
||||
|
||||
using namespace RendererSceneRenderImplementation;
|
||||
|
||||
RenderForwardMobile::ForwardID RenderForwardMobile::_allocate_forward_id(ForwardIDType p_type) {
|
||||
RendererRD::ForwardID RenderForwardMobile::ForwardIDStorageMobile::allocate_forward_id(RendererRD::ForwardIDType p_type) {
|
||||
int32_t index = -1;
|
||||
for (uint32_t i = 0; i < forward_id_allocators[p_type].allocations.size(); i++) {
|
||||
if (forward_id_allocators[p_type].allocations[i] == false) {
|
||||
@ -58,15 +58,66 @@ RenderForwardMobile::ForwardID RenderForwardMobile::_allocate_forward_id(Forward
|
||||
|
||||
return index;
|
||||
}
|
||||
void RenderForwardMobile::_free_forward_id(ForwardIDType p_type, ForwardID p_id) {
|
||||
ERR_FAIL_INDEX(p_id, (ForwardID)forward_id_allocators[p_type].allocations.size());
|
||||
void RenderForwardMobile::ForwardIDStorageMobile::free_forward_id(RendererRD::ForwardIDType p_type, RendererRD::ForwardID p_id) {
|
||||
ERR_FAIL_INDEX(p_id, (RendererRD::ForwardID)forward_id_allocators[p_type].allocations.size());
|
||||
forward_id_allocators[p_type].allocations[p_id] = false;
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_map_forward_id(ForwardIDType p_type, 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) {
|
||||
forward_id_allocators[p_type].map[p_id] = p_index;
|
||||
}
|
||||
|
||||
void RenderForwardMobile::ForwardIDStorageMobile::fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance) {
|
||||
// first zero out our indices
|
||||
|
||||
p_push_constant->omni_lights[0] = 0xFFFF;
|
||||
p_push_constant->omni_lights[1] = 0xFFFF;
|
||||
|
||||
p_push_constant->spot_lights[0] = 0xFFFF;
|
||||
p_push_constant->spot_lights[1] = 0xFFFF;
|
||||
|
||||
p_push_constant->decals[0] = 0xFFFF;
|
||||
p_push_constant->decals[1] = 0xFFFF;
|
||||
|
||||
p_push_constant->reflection_probes[0] = 0xFFFF;
|
||||
p_push_constant->reflection_probes[1] = 0xFFFF;
|
||||
|
||||
if (p_instance->omni_light_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_OMNI_LIGHTS;
|
||||
}
|
||||
if (p_instance->spot_light_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_SPOT_LIGHTS;
|
||||
}
|
||||
if (p_instance->reflection_probe_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_REFLECTION_PROBES;
|
||||
}
|
||||
if (p_instance->decals_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_DECALS;
|
||||
}
|
||||
|
||||
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 mask = ~(0xFF << shift);
|
||||
if (i < p_instance->omni_light_count) {
|
||||
p_push_constant->omni_lights[ofs] &= mask;
|
||||
p_push_constant->omni_lights[ofs] |= uint32_t(forward_id_allocators[RendererRD::FORWARD_ID_TYPE_OMNI_LIGHT].map[p_instance->omni_lights[i]]) << shift;
|
||||
}
|
||||
if (i < p_instance->spot_light_count) {
|
||||
p_push_constant->spot_lights[ofs] &= mask;
|
||||
p_push_constant->spot_lights[ofs] |= uint32_t(forward_id_allocators[RendererRD::FORWARD_ID_TYPE_SPOT_LIGHT].map[p_instance->spot_lights[i]]) << shift;
|
||||
}
|
||||
if (i < p_instance->decals_count) {
|
||||
p_push_constant->decals[ofs] &= mask;
|
||||
p_push_constant->decals[ofs] |= uint32_t(forward_id_allocators[RendererRD::FORWARD_ID_TYPE_DECAL].map[p_instance->decals[i]]) << shift;
|
||||
}
|
||||
if (i < p_instance->reflection_probe_count) {
|
||||
p_push_constant->reflection_probes[ofs] &= mask;
|
||||
p_push_constant->reflection_probes[ofs] |= uint32_t(forward_id_allocators[RendererRD::FORWARD_ID_TYPE_REFLECTION_PROBE].map[p_instance->reflection_probes[i]]) << shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Render buffer */
|
||||
|
||||
void RenderForwardMobile::RenderBufferDataForwardMobile::free_data() {
|
||||
@ -300,6 +351,7 @@ bool RenderForwardMobile::_render_buffers_can_be_storage() {
|
||||
}
|
||||
|
||||
RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas, int p_index) {
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
|
||||
|
||||
//there should always be enough uniform buffers for render passes, otherwise bugs
|
||||
@ -340,7 +392,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
||||
}
|
||||
|
||||
{
|
||||
RID ref_texture = (p_render_data && p_render_data->reflection_atlas.is_valid()) ? reflection_atlas_get_texture(p_render_data->reflection_atlas) : RID();
|
||||
RID ref_texture = (p_render_data && p_render_data->reflection_atlas.is_valid()) ? light_storage->reflection_atlas_get_texture(p_render_data->reflection_atlas) : RID();
|
||||
RD::Uniform u;
|
||||
u.binding = 3;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
@ -358,7 +410,7 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
RID texture;
|
||||
if (p_render_data && p_render_data->shadow_atlas.is_valid()) {
|
||||
texture = shadow_atlas_get_texture(p_render_data->shadow_atlas);
|
||||
texture = light_storage->shadow_atlas_get_texture(p_render_data->shadow_atlas);
|
||||
}
|
||||
if (!texture.is_valid()) {
|
||||
texture = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH);
|
||||
@ -370,8 +422,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
||||
RD::Uniform u;
|
||||
u.binding = 5;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
|
||||
if (p_use_directional_shadow_atlas && directional_shadow_get_texture().is_valid()) {
|
||||
u.append_id(directional_shadow_get_texture());
|
||||
if (p_use_directional_shadow_atlas && light_storage->directional_shadow_get_texture().is_valid()) {
|
||||
u.append_id(light_storage->directional_shadow_get_texture());
|
||||
} else {
|
||||
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_DEPTH));
|
||||
}
|
||||
@ -387,8 +439,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
||||
RID default_tex = texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
|
||||
for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
|
||||
if (p_render_data && i < p_render_data->lightmaps->size()) {
|
||||
RID base = lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]);
|
||||
RID texture = RendererRD::LightStorage::get_singleton()->lightmap_get_texture(base);
|
||||
RID base = light_storage->lightmap_instance_get_lightmap((*p_render_data->lightmaps)[i]);
|
||||
RID texture = light_storage->lightmap_get_texture(base);
|
||||
RID rd_texture = texture_storage->texture_get_rd_texture(texture);
|
||||
u.append_id(rd_texture);
|
||||
} else {
|
||||
@ -467,6 +519,8 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform) {
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
|
||||
// This probably needs to change...
|
||||
scene_state.lightmaps_used = 0;
|
||||
for (int i = 0; i < (int)p_lightmaps.size(); i++) {
|
||||
@ -474,20 +528,20 @@ void RenderForwardMobile::_setup_lightmaps(const RenderDataRD *p_render_data, co
|
||||
break;
|
||||
}
|
||||
|
||||
RID lightmap = lightmap_instance_get_lightmap(p_lightmaps[i]);
|
||||
RID lightmap = light_storage->lightmap_instance_get_lightmap(p_lightmaps[i]);
|
||||
|
||||
Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
|
||||
Basis to_lm = light_storage->lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
|
||||
to_lm = to_lm.inverse().transposed(); //will transform normals
|
||||
RendererRD::MaterialStorage::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
|
||||
scene_state.lightmaps[i].exposure_normalization = 1.0;
|
||||
if (p_render_data->camera_attributes.is_valid()) {
|
||||
float baked_exposure = RendererRD::LightStorage::get_singleton()->lightmap_get_baked_exposure_normalization(lightmap);
|
||||
float baked_exposure = light_storage->lightmap_get_baked_exposure_normalization(lightmap);
|
||||
float enf = RSG::camera_attributes->camera_attributes_get_exposure_normalization_factor(p_render_data->camera_attributes);
|
||||
scene_state.lightmaps[i].exposure_normalization = enf / baked_exposure;
|
||||
}
|
||||
|
||||
scene_state.lightmap_ids[i] = p_lightmaps[i];
|
||||
scene_state.lightmap_has_sh[i] = RendererRD::LightStorage::get_singleton()->lightmap_uses_spherical_harmonics(lightmap);
|
||||
scene_state.lightmap_has_sh[i] = light_storage->lightmap_uses_spherical_harmonics(lightmap);
|
||||
|
||||
scene_state.lightmaps_used++;
|
||||
}
|
||||
@ -496,12 +550,103 @@ 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();
|
||||
p_render_data->directional_shadows.clear();
|
||||
|
||||
Plane camera_plane(-p_render_data->scene_data->cam_transform.basis.get_column(Vector3::AXIS_Z), p_render_data->scene_data->cam_transform.origin);
|
||||
float lod_distance_multiplier = p_render_data->scene_data->cam_projection.get_lod_multiplier();
|
||||
{
|
||||
for (int i = 0; i < p_render_data->render_shadow_count; i++) {
|
||||
RID li = p_render_data->render_shadows[i].light;
|
||||
RID base = light_storage->light_instance_get_base_light(li);
|
||||
|
||||
if (light_storage->light_get_type(base) == RS::LIGHT_DIRECTIONAL) {
|
||||
p_render_data->directional_shadows.push_back(i);
|
||||
} else if (light_storage->light_get_type(base) == RS::LIGHT_OMNI && light_storage->light_omni_get_shadow_mode(base) == RS::LIGHT_OMNI_SHADOW_CUBE) {
|
||||
p_render_data->cube_shadows.push_back(i);
|
||||
} else {
|
||||
p_render_data->shadows.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
//cube shadows are rendered in their own way
|
||||
for (uint32_t i = 0; i < p_render_data->cube_shadows.size(); i++) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->cube_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->cube_shadows[i]].pass, p_render_data->render_shadows[p_render_data->cube_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, true, true, true, p_render_data->render_info);
|
||||
}
|
||||
|
||||
if (p_render_data->directional_shadows.size()) {
|
||||
//open the pass for directional shadows
|
||||
light_storage->update_directional_shadow_atlas();
|
||||
RD::get_singleton()->draw_list_begin(light_storage->direction_shadow_get_fb(), RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_CONTINUE);
|
||||
RD::get_singleton()->draw_list_end();
|
||||
}
|
||||
}
|
||||
|
||||
bool render_shadows = p_render_data->directional_shadows.size() || p_render_data->shadows.size();
|
||||
|
||||
if (render_shadows) {
|
||||
RENDER_TIMESTAMP("Render Shadows");
|
||||
}
|
||||
|
||||
//prepare shadow rendering
|
||||
if (render_shadows) {
|
||||
_render_shadow_begin();
|
||||
|
||||
//render directional shadows
|
||||
for (uint32_t i = 0; i < p_render_data->directional_shadows.size(); i++) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->directional_shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->directional_shadows[i]].pass, p_render_data->render_shadows[p_render_data->directional_shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, false, i == p_render_data->directional_shadows.size() - 1, false, p_render_data->render_info);
|
||||
}
|
||||
//render positional shadows
|
||||
for (uint32_t i = 0; i < p_render_data->shadows.size(); i++) {
|
||||
_render_shadow_pass(p_render_data->render_shadows[p_render_data->shadows[i]].light, p_render_data->shadow_atlas, p_render_data->render_shadows[p_render_data->shadows[i]].pass, p_render_data->render_shadows[p_render_data->shadows[i]].instances, camera_plane, lod_distance_multiplier, p_render_data->scene_data->screen_mesh_lod_threshold, i == 0, i == p_render_data->shadows.size() - 1, true, p_render_data->render_info);
|
||||
}
|
||||
|
||||
_render_shadow_process();
|
||||
|
||||
_render_shadow_end(RD::BARRIER_MASK_NO_BARRIER);
|
||||
}
|
||||
|
||||
//full barrier here, we need raster, transfer and compute and it depends from the previous work
|
||||
RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL, RD::BARRIER_MASK_ALL);
|
||||
|
||||
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.affine_inverse());
|
||||
|
||||
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();
|
||||
|
||||
Ref<RenderSceneBuffersRD> rb;
|
||||
Ref<RenderBufferDataForwardMobile> rb_data;
|
||||
if (p_render_data->render_buffers.is_valid()) {
|
||||
rb_data = p_render_data->render_buffers->get_custom_data(RB_SCOPE_MOBILE);
|
||||
rb = p_render_data->render_buffers;
|
||||
rb_data = rb->get_custom_data(RB_SCOPE_MOBILE);
|
||||
}
|
||||
|
||||
RENDER_TIMESTAMP("Prepare 3D Scene");
|
||||
|
||||
_update_vrs(rb);
|
||||
|
||||
RENDER_TIMESTAMP("Setup 3D Scene");
|
||||
|
||||
/* TODO
|
||||
@ -532,9 +677,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
bool using_subpass_transparent = true;
|
||||
bool using_subpass_post_process = true;
|
||||
|
||||
bool using_ssr = false; // I don't think we support this in our mobile renderer so probably should phase it out
|
||||
bool using_sss = false; // I don't think we support this in our mobile renderer so probably should phase it out
|
||||
|
||||
// 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();
|
||||
@ -559,7 +701,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
using_subpass_post_process = false;
|
||||
}
|
||||
|
||||
if (using_ssr || using_sss || scene_state.used_screen_texture || scene_state.used_depth_texture) {
|
||||
if (scene_state.used_screen_texture || scene_state.used_depth_texture) {
|
||||
// can't use our last two subpasses
|
||||
using_subpass_transparent = false;
|
||||
using_subpass_post_process = false;
|
||||
@ -576,13 +718,13 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_TWO_SUBPASSES);
|
||||
}
|
||||
} else if (p_render_data->reflection_probe.is_valid()) {
|
||||
uint32_t resolution = reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
|
||||
uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
|
||||
screen_size.x = resolution;
|
||||
screen_size.y = resolution;
|
||||
|
||||
framebuffer = reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
|
||||
framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
|
||||
|
||||
if (RendererRD::LightStorage::get_singleton()->reflection_probe_is_interior(reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
|
||||
if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
|
||||
p_render_data->environment = RID(); //no environment on interiors
|
||||
}
|
||||
|
||||
@ -713,8 +855,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
|
||||
}
|
||||
|
||||
RID nullrids[RendererSceneRender::MAX_RENDER_VIEWS];
|
||||
_pre_opaque_render(p_render_data, false, false, false, nullrids, RID());
|
||||
_pre_opaque_render(p_render_data);
|
||||
|
||||
uint32_t spec_constant_base_flags = 0;
|
||||
|
||||
@ -758,8 +899,8 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
|
||||
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, p_render_data, radiance_texture, true);
|
||||
|
||||
bool can_continue_color = !using_subpass_transparent && !scene_state.used_screen_texture && !using_ssr && !using_sss;
|
||||
bool can_continue_depth = !using_subpass_transparent && !scene_state.used_depth_texture && !using_ssr && !using_sss;
|
||||
bool can_continue_color = !using_subpass_transparent && !scene_state.used_screen_texture;
|
||||
bool can_continue_depth = !using_subpass_transparent && !scene_state.used_depth_texture;
|
||||
|
||||
{
|
||||
// regular forward for now
|
||||
@ -917,10 +1058,190 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
|
||||
if (rb_data.is_valid()) {
|
||||
_disable_clear_request(p_render_data);
|
||||
}
|
||||
|
||||
if (rb.is_valid()) {
|
||||
_render_buffers_debug_draw(rb, p_render_data->shadow_atlas, p_render_data->occluder_debug_tex);
|
||||
}
|
||||
}
|
||||
|
||||
/* these are being called from RendererSceneRenderRD::_pre_opaque_render */
|
||||
|
||||
void RenderForwardMobile::_render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_mesh_lod_threshold, bool p_open_pass, bool p_close_pass, bool p_clear_region, RenderingMethod::RenderInfo *p_render_info) {
|
||||
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
|
||||
|
||||
ERR_FAIL_COND(!light_storage->owns_light_instance(p_light));
|
||||
|
||||
RID base = light_storage->light_instance_get_base_light(p_light);
|
||||
|
||||
Rect2i atlas_rect;
|
||||
uint32_t atlas_size = 1;
|
||||
RID atlas_fb;
|
||||
|
||||
bool using_dual_paraboloid = false;
|
||||
bool using_dual_paraboloid_flip = false;
|
||||
Vector2i dual_paraboloid_offset;
|
||||
RID render_fb;
|
||||
RID render_texture;
|
||||
float zfar;
|
||||
|
||||
bool use_pancake = false;
|
||||
bool render_cubemap = false;
|
||||
bool finalize_cubemap = false;
|
||||
|
||||
bool flip_y = false;
|
||||
|
||||
Projection light_projection;
|
||||
Transform3D light_transform;
|
||||
|
||||
if (light_storage->light_get_type(base) == RS::LIGHT_DIRECTIONAL) {
|
||||
//set pssm stuff
|
||||
uint64_t last_scene_shadow_pass = light_storage->light_instance_get_shadow_pass(p_light);
|
||||
if (last_scene_shadow_pass != get_scene_pass()) {
|
||||
light_storage->light_instance_set_directional_rect(p_light, light_storage->get_directional_shadow_rect());
|
||||
light_storage->directional_shadow_increase_current_light();
|
||||
light_storage->light_instance_set_shadow_pass(p_light, get_scene_pass());
|
||||
}
|
||||
|
||||
use_pancake = light_storage->light_get_param(base, RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE) > 0;
|
||||
light_projection = light_storage->light_instance_get_shadow_camera(p_light, p_pass);
|
||||
light_transform = light_storage->light_instance_get_shadow_transform(p_light, p_pass);
|
||||
|
||||
atlas_rect = light_storage->light_instance_get_directional_rect(p_light);
|
||||
|
||||
if (light_storage->light_directional_get_shadow_mode(base) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) {
|
||||
atlas_rect.size.width /= 2;
|
||||
atlas_rect.size.height /= 2;
|
||||
|
||||
if (p_pass == 1) {
|
||||
atlas_rect.position.x += atlas_rect.size.width;
|
||||
} else if (p_pass == 2) {
|
||||
atlas_rect.position.y += atlas_rect.size.height;
|
||||
} else if (p_pass == 3) {
|
||||
atlas_rect.position += atlas_rect.size;
|
||||
}
|
||||
} else if (light_storage->light_directional_get_shadow_mode(base) == RS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS) {
|
||||
atlas_rect.size.height /= 2;
|
||||
|
||||
if (p_pass == 0) {
|
||||
} else {
|
||||
atlas_rect.position.y += atlas_rect.size.height;
|
||||
}
|
||||
}
|
||||
|
||||
int directional_shadow_size = light_storage->directional_shadow_get_size();
|
||||
atlas_rect.position /= directional_shadow_size;
|
||||
atlas_rect.size /= directional_shadow_size;
|
||||
|
||||
light_storage->light_instance_set_directional_shadow_atlas_rect(p_light, p_pass, atlas_rect);
|
||||
|
||||
zfar = RSG::light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);
|
||||
|
||||
render_fb = light_storage->direction_shadow_get_fb();
|
||||
render_texture = RID();
|
||||
flip_y = true;
|
||||
|
||||
} else {
|
||||
//set from shadow atlas
|
||||
|
||||
ERR_FAIL_COND(!light_storage->owns_shadow_atlas(p_shadow_atlas));
|
||||
ERR_FAIL_COND(!light_storage->shadow_atlas_owns_light_instance(p_shadow_atlas, p_light));
|
||||
|
||||
RSG::light_storage->shadow_atlas_update(p_shadow_atlas);
|
||||
|
||||
uint32_t key = light_storage->shadow_atlas_get_light_instance_key(p_shadow_atlas, p_light);
|
||||
|
||||
uint32_t quadrant = (key >> RendererRD::LightStorage::QUADRANT_SHIFT) & 0x3;
|
||||
uint32_t shadow = key & RendererRD::LightStorage::SHADOW_INDEX_MASK;
|
||||
uint32_t subdivision = light_storage->shadow_atlas_get_quadrant_subdivision(p_shadow_atlas, quadrant);
|
||||
|
||||
ERR_FAIL_INDEX((int)shadow, light_storage->shadow_atlas_get_quadrant_shadow_size(p_shadow_atlas, quadrant));
|
||||
|
||||
uint32_t shadow_atlas_size = light_storage->shadow_atlas_get_size(p_shadow_atlas);
|
||||
uint32_t quadrant_size = shadow_atlas_size >> 1;
|
||||
|
||||
atlas_rect.position.x = (quadrant & 1) * quadrant_size;
|
||||
atlas_rect.position.y = (quadrant >> 1) * quadrant_size;
|
||||
|
||||
uint32_t shadow_size = (quadrant_size / subdivision);
|
||||
atlas_rect.position.x += (shadow % subdivision) * shadow_size;
|
||||
atlas_rect.position.y += (shadow / subdivision) * shadow_size;
|
||||
|
||||
atlas_rect.size.width = shadow_size;
|
||||
atlas_rect.size.height = shadow_size;
|
||||
|
||||
zfar = light_storage->light_get_param(base, RS::LIGHT_PARAM_RANGE);
|
||||
|
||||
if (light_storage->light_get_type(base) == RS::LIGHT_OMNI) {
|
||||
bool wrap = (shadow + 1) % subdivision == 0;
|
||||
dual_paraboloid_offset = wrap ? Vector2i(1 - subdivision, 1) : Vector2i(1, 0);
|
||||
|
||||
if (light_storage->light_omni_get_shadow_mode(base) == RS::LIGHT_OMNI_SHADOW_CUBE) {
|
||||
render_texture = light_storage->get_cubemap(shadow_size / 2);
|
||||
render_fb = light_storage->get_cubemap_fb(shadow_size / 2, p_pass);
|
||||
|
||||
light_projection = light_storage->light_instance_get_shadow_camera(p_light, p_pass);
|
||||
light_transform = light_storage->light_instance_get_shadow_transform(p_light, p_pass);
|
||||
render_cubemap = true;
|
||||
finalize_cubemap = p_pass == 5;
|
||||
atlas_fb = light_storage->shadow_atlas_get_fb(p_shadow_atlas);
|
||||
|
||||
atlas_size = shadow_atlas_size;
|
||||
|
||||
if (p_pass == 0) {
|
||||
_render_shadow_begin();
|
||||
}
|
||||
|
||||
} else {
|
||||
atlas_rect.position.x += 1;
|
||||
atlas_rect.position.y += 1;
|
||||
atlas_rect.size.x -= 2;
|
||||
atlas_rect.size.y -= 2;
|
||||
|
||||
atlas_rect.position += p_pass * atlas_rect.size * dual_paraboloid_offset;
|
||||
|
||||
light_projection = light_storage->light_instance_get_shadow_camera(p_light, 0);
|
||||
light_transform = light_storage->light_instance_get_shadow_transform(p_light, 0);
|
||||
|
||||
using_dual_paraboloid = true;
|
||||
using_dual_paraboloid_flip = p_pass == 1;
|
||||
render_fb = light_storage->shadow_atlas_get_fb(p_shadow_atlas);
|
||||
flip_y = true;
|
||||
}
|
||||
|
||||
} else if (light_storage->light_get_type(base) == RS::LIGHT_SPOT) {
|
||||
light_projection = light_storage->light_instance_get_shadow_camera(p_light, 0);
|
||||
light_transform = light_storage->light_instance_get_shadow_transform(p_light, 0);
|
||||
|
||||
render_fb = light_storage->shadow_atlas_get_fb(p_shadow_atlas);
|
||||
|
||||
flip_y = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (render_cubemap) {
|
||||
//rendering to cubemap
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, false, false, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, Rect2(), false, true, true, true, p_render_info);
|
||||
if (finalize_cubemap) {
|
||||
_render_shadow_process();
|
||||
_render_shadow_end();
|
||||
//reblit
|
||||
Rect2 atlas_rect_norm = atlas_rect;
|
||||
atlas_rect_norm.position /= float(atlas_size);
|
||||
atlas_rect_norm.size /= float(atlas_size);
|
||||
copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), false);
|
||||
atlas_rect_norm.position += Vector2(dual_paraboloid_offset) * atlas_rect_norm.size;
|
||||
copy_effects->copy_cubemap_to_dp(render_texture, atlas_fb, atlas_rect_norm, atlas_rect.size, light_projection.get_z_near(), light_projection.get_z_far(), true);
|
||||
|
||||
//restore transform so it can be properly used
|
||||
light_storage->light_instance_set_shadow_transform(p_light, Projection(), light_storage->light_instance_get_base_transform(p_light), zfar, 0, 0, 0);
|
||||
}
|
||||
|
||||
} else {
|
||||
//render shadow
|
||||
_render_shadow_append(render_fb, p_instances, light_projection, light_transform, zfar, 0, 0, using_dual_paraboloid, using_dual_paraboloid_flip, use_pancake, p_camera_plane, p_lod_distance_multiplier, p_screen_mesh_lod_threshold, atlas_rect, flip_y, p_clear_region, p_open_pass, p_close_pass, p_render_info);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_render_shadow_begin() {
|
||||
scene_state.shadow_passes.clear();
|
||||
RD::get_singleton()->draw_command_begin_label("Shadow Setup");
|
||||
@ -1146,7 +1467,7 @@ void RenderForwardMobile::_render_uv2(const PagedArray<RenderGeometryInstance *>
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_render_sdfgi(Ref<RenderSceneBuffersRD> p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) {
|
||||
// we don't do GI in low end..
|
||||
// we don't do SDFGI in low end..
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) {
|
||||
@ -1189,7 +1510,7 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const
|
||||
RD::get_singleton()->draw_command_end_label();
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_base_uniforms_changed() {
|
||||
void RenderForwardMobile::base_uniforms_changed() {
|
||||
if (!render_base_uniform_set.is_null() && RD::get_singleton()->uniform_set_is_valid(render_base_uniform_set)) {
|
||||
RD::get_singleton()->free(render_base_uniform_set);
|
||||
}
|
||||
@ -1305,14 +1626,14 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
||||
RD::Uniform u;
|
||||
u.binding = 5;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.append_id(get_omni_light_buffer());
|
||||
u.append_id(RendererRD::LightStorage::get_singleton()->get_omni_light_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 6;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.append_id(get_spot_light_buffer());
|
||||
u.append_id(RendererRD::LightStorage::get_singleton()->get_spot_light_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
@ -1320,14 +1641,14 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
||||
RD::Uniform u;
|
||||
u.binding = 7;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.append_id(get_reflection_probe_buffer());
|
||||
u.append_id(RendererRD::LightStorage::get_singleton()->get_reflection_probe_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
RD::Uniform u;
|
||||
u.binding = 8;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
|
||||
u.append_id(get_directional_light_buffer());
|
||||
u.append_id(RendererRD::LightStorage::get_singleton()->get_directional_light_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
{
|
||||
@ -1364,7 +1685,7 @@ void RenderForwardMobile::_update_render_base_uniform_set() {
|
||||
RD::Uniform u;
|
||||
u.binding = 13;
|
||||
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
|
||||
u.append_id(get_decal_buffer());
|
||||
u.append_id(RendererRD::TextureStorage::get_singleton()->get_decal_buffer());
|
||||
uniforms.push_back(u);
|
||||
}
|
||||
|
||||
@ -1584,7 +1905,7 @@ void RenderForwardMobile::_fill_render_list(RenderListType p_render_list, const
|
||||
void RenderForwardMobile::_setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers, bool p_pancake_shadows, int p_index) {
|
||||
Ref<RenderSceneBuffersRD> rd = p_render_data->render_buffers;
|
||||
RID env = is_environment(p_render_data->environment) ? p_render_data->environment : RID();
|
||||
RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID();
|
||||
RID reflection_probe_instance = p_render_data->reflection_probe.is_valid() ? RendererRD::LightStorage::get_singleton()->reflection_probe_instance_get_probe(p_render_data->reflection_probe) : RID();
|
||||
|
||||
// May do this earlier in RenderSceneRenderRD::render_scene
|
||||
if (p_index >= (int)scene_state.uniform_buffers.size()) {
|
||||
@ -1665,57 +1986,6 @@ void RenderForwardMobile::_render_list_with_threads(RenderListParameters *p_para
|
||||
}
|
||||
}
|
||||
|
||||
void RenderForwardMobile::_fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance) {
|
||||
// first zero out our indices
|
||||
|
||||
p_push_constant->omni_lights[0] = 0xFFFF;
|
||||
p_push_constant->omni_lights[1] = 0xFFFF;
|
||||
|
||||
p_push_constant->spot_lights[0] = 0xFFFF;
|
||||
p_push_constant->spot_lights[1] = 0xFFFF;
|
||||
|
||||
p_push_constant->decals[0] = 0xFFFF;
|
||||
p_push_constant->decals[1] = 0xFFFF;
|
||||
|
||||
p_push_constant->reflection_probes[0] = 0xFFFF;
|
||||
p_push_constant->reflection_probes[1] = 0xFFFF;
|
||||
|
||||
if (p_instance->omni_light_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_OMNI_LIGHTS;
|
||||
}
|
||||
if (p_instance->spot_light_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_SPOT_LIGHTS;
|
||||
}
|
||||
if (p_instance->reflection_probe_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_REFLECTION_PROBES;
|
||||
}
|
||||
if (p_instance->decals_count == 0) {
|
||||
spec_constants |= 1 << SPEC_CONSTANT_DISABLE_DECALS;
|
||||
}
|
||||
|
||||
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 mask = ~(0xFF << shift);
|
||||
if (i < p_instance->omni_light_count) {
|
||||
p_push_constant->omni_lights[ofs] &= mask;
|
||||
p_push_constant->omni_lights[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_OMNI_LIGHT].map[p_instance->omni_lights[i]]) << shift;
|
||||
}
|
||||
if (i < p_instance->spot_light_count) {
|
||||
p_push_constant->spot_lights[ofs] &= mask;
|
||||
p_push_constant->spot_lights[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_SPOT_LIGHT].map[p_instance->spot_lights[i]]) << shift;
|
||||
}
|
||||
if (i < p_instance->decals_count) {
|
||||
p_push_constant->decals[ofs] &= mask;
|
||||
p_push_constant->decals[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_DECAL].map[p_instance->decals[i]]) << shift;
|
||||
}
|
||||
if (i < p_instance->reflection_probe_count) {
|
||||
p_push_constant->reflection_probes[ofs] &= mask;
|
||||
p_push_constant->reflection_probes[ofs] |= uint32_t(forward_id_allocators[FORWARD_ID_TYPE_REFLECTION_PROBE].map[p_instance->reflection_probes[i]]) << shift;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <RenderForwardMobile::PassMode p_pass_mode>
|
||||
void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderListParameters *p_params, uint32_t p_from_element, uint32_t p_to_element) {
|
||||
RendererRD::MeshStorage *mesh_storage = RendererRD::MeshStorage::get_singleton();
|
||||
@ -1797,7 +2067,7 @@ void RenderForwardMobile::_render_list_template(RenderingDevice::DrawListID p_dr
|
||||
if (inst->use_soft_shadow) {
|
||||
base_spec_constants |= 1 << SPEC_CONSTANT_USING_SOFT_SHADOWS;
|
||||
}
|
||||
_fill_push_constant_instance_indices(&push_constant, base_spec_constants, inst);
|
||||
forward_id_storage_mobile->fill_push_constant_instance_indices(&push_constant, base_spec_constants, inst);
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
if (unlikely(get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_LIGHTING)) {
|
||||
@ -1989,17 +2259,17 @@ void RenderForwardMobile::GeometryInstanceForwardMobile::pair_light_instances(co
|
||||
spot_light_count = 0;
|
||||
|
||||
for (uint32_t i = 0; i < p_light_instance_count; i++) {
|
||||
RS::LightType type = RenderForwardMobile::get_singleton()->light_instance_get_type(p_light_instances[i]);
|
||||
RS::LightType type = RendererRD::LightStorage::get_singleton()->light_instance_get_type(p_light_instances[i]);
|
||||
switch (type) {
|
||||
case RS::LIGHT_OMNI: {
|
||||
if (omni_light_count < (uint32_t)MAX_RDL_CULL) {
|
||||
omni_lights[omni_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]);
|
||||
omni_lights[omni_light_count] = RendererRD::LightStorage::get_singleton()->light_instance_get_forward_id(p_light_instances[i]);
|
||||
omni_light_count++;
|
||||
}
|
||||
} break;
|
||||
case RS::LIGHT_SPOT: {
|
||||
if (spot_light_count < (uint32_t)MAX_RDL_CULL) {
|
||||
spot_lights[spot_light_count] = RenderForwardMobile::get_singleton()->light_instance_get_forward_id(p_light_instances[i]);
|
||||
spot_lights[spot_light_count] = RendererRD::LightStorage::get_singleton()->light_instance_get_forward_id(p_light_instances[i]);
|
||||
spot_light_count++;
|
||||
}
|
||||
} break;
|
||||
@ -2012,14 +2282,14 @@ void RenderForwardMobile::GeometryInstanceForwardMobile::pair_light_instances(co
|
||||
void RenderForwardMobile::GeometryInstanceForwardMobile::pair_reflection_probe_instances(const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {
|
||||
reflection_probe_count = p_reflection_probe_instance_count < (uint32_t)MAX_RDL_CULL ? p_reflection_probe_instance_count : (uint32_t)MAX_RDL_CULL;
|
||||
for (uint32_t i = 0; i < reflection_probe_count; i++) {
|
||||
reflection_probes[i] = RenderForwardMobile::get_singleton()->reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]);
|
||||
reflection_probes[i] = RendererRD::LightStorage::get_singleton()->reflection_probe_instance_get_forward_id(p_reflection_probe_instances[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderForwardMobile::GeometryInstanceForwardMobile::pair_decal_instances(const RID *p_decal_instances, uint32_t p_decal_instance_count) {
|
||||
decals_count = p_decal_instance_count < (uint32_t)MAX_RDL_CULL ? p_decal_instance_count : (uint32_t)MAX_RDL_CULL;
|
||||
for (uint32_t i = 0; i < decals_count; i++) {
|
||||
decals[i] = RenderForwardMobile::get_singleton()->decal_instance_get_forward_id(p_decal_instances[i]);
|
||||
decals[i] = RendererRD::TextureStorage::get_singleton()->decal_instance_get_forward_id(p_decal_instances[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2387,10 +2657,6 @@ bool RenderForwardMobile::is_dynamic_gi_supported() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RenderForwardMobile::is_clustered_enabled() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RenderForwardMobile::is_volumetric_supported() const {
|
||||
return false;
|
||||
}
|
||||
@ -2446,7 +2712,7 @@ void RenderForwardMobile::_update_shader_quality_settings() {
|
||||
|
||||
scene_shader.set_default_specialization_constants(spec_constants);
|
||||
|
||||
_base_uniforms_changed(); //also need this
|
||||
base_uniforms_changed(); //also need this
|
||||
}
|
||||
|
||||
RenderForwardMobile::RenderForwardMobile() {
|
||||
@ -2495,7 +2761,7 @@ RenderForwardMobile::RenderForwardMobile() {
|
||||
}
|
||||
|
||||
RenderForwardMobile::~RenderForwardMobile() {
|
||||
directional_shadow_atlas_set_size(0);
|
||||
RSG::light_storage->directional_shadow_atlas_set_size(0);
|
||||
|
||||
//clear base uniform set if still valid
|
||||
for (uint32_t i = 0; i < render_pass_uniform_sets.size(); i++) {
|
||||
|
@ -44,19 +44,12 @@ namespace RendererSceneRenderImplementation {
|
||||
class RenderForwardMobile : public RendererSceneRenderRD {
|
||||
friend SceneShaderForwardMobile;
|
||||
|
||||
struct ForwardIDAllocator {
|
||||
LocalVector<bool> allocations;
|
||||
LocalVector<uint8_t> map;
|
||||
};
|
||||
|
||||
ForwardIDAllocator forward_id_allocators[FORWARD_ID_MAX];
|
||||
|
||||
virtual ForwardID _allocate_forward_id(ForwardIDType p_type) override;
|
||||
virtual void _free_forward_id(ForwardIDType p_type, ForwardID p_id) override;
|
||||
virtual void _map_forward_id(ForwardIDType p_type, ForwardID p_id, uint32_t p_index) override;
|
||||
virtual bool _uses_forward_ids() const override { return true; }
|
||||
|
||||
protected:
|
||||
struct GeometryInstanceSurfaceDataCache;
|
||||
|
||||
private:
|
||||
static RenderForwardMobile *singleton;
|
||||
|
||||
/* Scene Shader */
|
||||
|
||||
enum {
|
||||
@ -157,8 +150,6 @@ protected:
|
||||
// PASS_MODE_SDF,
|
||||
};
|
||||
|
||||
class GeometryInstanceForwardMobile;
|
||||
struct GeometryInstanceSurfaceDataCache;
|
||||
struct RenderElementInfo;
|
||||
|
||||
struct RenderListParameters {
|
||||
@ -201,36 +192,27 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
virtual float _render_buffers_get_luminance_multiplier() override;
|
||||
virtual RD::DataFormat _render_buffers_get_color_format() override;
|
||||
virtual bool _render_buffers_can_be_storage() override;
|
||||
/* Render shadows */
|
||||
|
||||
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
|
||||
void _render_shadow_begin();
|
||||
void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
|
||||
void _render_shadow_process();
|
||||
void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL);
|
||||
|
||||
/* Render Scene */
|
||||
|
||||
RID _setup_render_pass_uniform_set(RenderListType p_render_list, const RenderDataRD *p_render_data, RID p_radiance_texture, bool p_use_directional_shadow_atlas = false, int p_index = 0);
|
||||
virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
|
||||
|
||||
virtual void _render_shadow_begin() override;
|
||||
virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr) override;
|
||||
virtual void _render_shadow_process() override;
|
||||
virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) override;
|
||||
|
||||
virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region, float p_exposure_normalization) override;
|
||||
virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
|
||||
virtual void _render_sdfgi(Ref<RenderSceneBuffersRD> p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) override;
|
||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override;
|
||||
void _pre_opaque_render(RenderDataRD *p_render_data);
|
||||
|
||||
uint64_t lightmap_texture_array_version = 0xFFFFFFFF;
|
||||
|
||||
virtual void _base_uniforms_changed() override;
|
||||
void _update_render_base_uniform_set();
|
||||
virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
|
||||
virtual RID _render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
|
||||
|
||||
void _fill_render_list(RenderListType p_render_list, const RenderDataRD *p_render_data, PassMode p_pass_mode, bool p_append = false);
|
||||
void _fill_element_info(RenderListType p_render_list, uint32_t p_offset = 0, int32_t p_max_elements = -1);
|
||||
// void _update_instance_data_buffer(RenderListType p_render_list);
|
||||
|
||||
static RenderForwardMobile *singleton;
|
||||
|
||||
void _setup_environment(const RenderDataRD *p_render_data, bool p_no_fog, const Size2i &p_screen_size, bool p_flip_y, const Color &p_default_bg_color, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false, int p_index = 0);
|
||||
void _setup_lightmaps(const RenderDataRD *p_render_data, const PagedArray<RID> &p_lightmaps, const Transform3D &p_cam_transform);
|
||||
|
||||
@ -369,8 +351,21 @@ protected:
|
||||
|
||||
RenderList render_list[RENDER_LIST_MAX];
|
||||
|
||||
protected:
|
||||
/* setup */
|
||||
virtual void _update_shader_quality_settings() override;
|
||||
|
||||
virtual float _render_buffers_get_luminance_multiplier() override;
|
||||
virtual RD::DataFormat _render_buffers_get_color_format() override;
|
||||
virtual bool _render_buffers_can_be_storage() override;
|
||||
|
||||
virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
|
||||
virtual RID _render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) override;
|
||||
|
||||
/* Geometry instance */
|
||||
|
||||
class GeometryInstanceForwardMobile;
|
||||
|
||||
// When changing any of these enums, remember to change the corresponding enums in the shader files as well.
|
||||
enum {
|
||||
INSTANCE_DATA_FLAGS_NON_UNIFORM_SCALE = 1 << 4,
|
||||
@ -484,13 +479,13 @@ protected:
|
||||
|
||||
// culled light info
|
||||
uint32_t reflection_probe_count = 0;
|
||||
ForwardID reflection_probes[MAX_RDL_CULL];
|
||||
RendererRD::ForwardID reflection_probes[MAX_RDL_CULL];
|
||||
uint32_t omni_light_count = 0;
|
||||
ForwardID omni_lights[MAX_RDL_CULL];
|
||||
RendererRD::ForwardID omni_lights[MAX_RDL_CULL];
|
||||
uint32_t spot_light_count = 0;
|
||||
ForwardID spot_lights[MAX_RDL_CULL];
|
||||
RendererRD::ForwardID spot_lights[MAX_RDL_CULL];
|
||||
uint32_t decals_count = 0;
|
||||
ForwardID decals[MAX_RDL_CULL];
|
||||
RendererRD::ForwardID decals[MAX_RDL_CULL];
|
||||
|
||||
GeometryInstanceSurfaceDataCache *surface_caches = nullptr;
|
||||
|
||||
@ -513,9 +508,41 @@ protected:
|
||||
virtual void set_softshadow_projector_pairing(bool p_softshadow, bool p_projector) override;
|
||||
};
|
||||
|
||||
_FORCE_INLINE_ void _fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance);
|
||||
/* Rendering */
|
||||
|
||||
void _update_shader_quality_settings() override;
|
||||
virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) override;
|
||||
|
||||
virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region, float p_exposure_normalization) override;
|
||||
virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) override;
|
||||
virtual void _render_sdfgi(Ref<RenderSceneBuffersRD> p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) override;
|
||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) override;
|
||||
|
||||
/* Forward ID */
|
||||
|
||||
class ForwardIDStorageMobile : public RendererRD::ForwardIDStorage {
|
||||
public:
|
||||
struct ForwardIDAllocator {
|
||||
LocalVector<bool> allocations;
|
||||
LocalVector<uint8_t> map;
|
||||
};
|
||||
|
||||
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 bool uses_forward_ids() const override { return true; }
|
||||
|
||||
void fill_push_constant_instance_indices(GeometryInstanceForwardMobile::PushConstant *p_push_constant, uint32_t &spec_constants, const GeometryInstanceForwardMobile *p_instance);
|
||||
};
|
||||
|
||||
ForwardIDStorageMobile *forward_id_storage_mobile = nullptr;
|
||||
|
||||
virtual RendererRD::ForwardIDStorage *create_forward_id_storage() override {
|
||||
forward_id_storage_mobile = memnew(ForwardIDStorageMobile);
|
||||
return forward_id_storage_mobile;
|
||||
}
|
||||
|
||||
public:
|
||||
static RenderForwardMobile *get_singleton() { return singleton; }
|
||||
@ -544,8 +571,9 @@ public:
|
||||
|
||||
virtual bool free(RID p_rid) override;
|
||||
|
||||
virtual void base_uniforms_changed() override;
|
||||
|
||||
virtual bool is_dynamic_gi_supported() const override;
|
||||
virtual bool is_clustered_enabled() const override;
|
||||
virtual bool is_volumetric_supported() const override;
|
||||
virtual uint32_t get_max_elements() const override;
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -38,19 +38,21 @@
|
||||
#include "servers/rendering/renderer_rd/effects/bokeh_dof.h"
|
||||
#include "servers/rendering/renderer_rd/effects/copy_effects.h"
|
||||
#include "servers/rendering/renderer_rd/effects/fsr.h"
|
||||
#include "servers/rendering/renderer_rd/effects/ss_effects.h"
|
||||
#include "servers/rendering/renderer_rd/effects/tone_mapper.h"
|
||||
#include "servers/rendering/renderer_rd/effects/vrs.h"
|
||||
#include "servers/rendering/renderer_rd/environment/fog.h"
|
||||
#include "servers/rendering/renderer_rd/environment/gi.h"
|
||||
#include "servers/rendering/renderer_rd/environment/sky.h"
|
||||
#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/light_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/render_scene_data_rd.h"
|
||||
#include "servers/rendering/renderer_scene_render.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#include "servers/rendering/rendering_method.h"
|
||||
|
||||
// For RenderDataRD, possibly inherited from RefCounted and add proper getters for our implementation classes
|
||||
|
||||
struct RenderDataRD {
|
||||
Ref<RenderSceneBuffersRD> render_buffers;
|
||||
RenderSceneDataRD *scene_data;
|
||||
@ -65,6 +67,7 @@ struct RenderDataRD {
|
||||
RID environment;
|
||||
RID camera_attributes;
|
||||
RID shadow_atlas;
|
||||
RID occluder_debug_tex;
|
||||
RID reflection_atlas;
|
||||
RID reflection_probe;
|
||||
int reflection_probe_pass = 0;
|
||||
@ -77,6 +80,21 @@ struct RenderDataRD {
|
||||
bool directional_light_soft_shadows = false;
|
||||
|
||||
RenderingMethod::RenderInfo *render_info = nullptr;
|
||||
|
||||
/* Shadow data */
|
||||
const RendererSceneRender::RenderShadowData *render_shadows = nullptr;
|
||||
int render_shadow_count = 0;
|
||||
|
||||
LocalVector<int> cube_shadows;
|
||||
LocalVector<int> shadows;
|
||||
LocalVector<int> directional_shadows;
|
||||
|
||||
/* GI info */
|
||||
const RendererSceneRender::RenderSDFGIData *render_sdfgi_regions = nullptr;
|
||||
int render_sdfgi_region_count = 0;
|
||||
const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
|
||||
|
||||
uint32_t voxel_gi_count = 0;
|
||||
};
|
||||
|
||||
class RendererSceneRenderRD : public RendererSceneRender {
|
||||
@ -84,6 +102,7 @@ class RendererSceneRenderRD : public RendererSceneRender {
|
||||
friend RendererRD::GI;
|
||||
|
||||
protected:
|
||||
RendererRD::ForwardIDStorage *forward_id_storage = nullptr;
|
||||
RendererRD::BokehDOF *bokeh_dof = nullptr;
|
||||
RendererRD::CopyEffects *copy_effects = nullptr;
|
||||
RendererRD::ToneMapper *tone_mapper = nullptr;
|
||||
@ -92,288 +111,6 @@ protected:
|
||||
double time = 0.0;
|
||||
double time_step = 0.0;
|
||||
|
||||
virtual void setup_render_buffer_data(Ref<RenderSceneBuffersRD> p_render_buffers) = 0;
|
||||
|
||||
void _setup_lights(RenderDataRD *p_render_data, const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows);
|
||||
void _setup_decals(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform);
|
||||
void _setup_reflections(RenderDataRD *p_render_data, const PagedArray<RID> &p_reflections, const Transform3D &p_camera_inverse_transform, RID p_environment);
|
||||
|
||||
virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0;
|
||||
|
||||
virtual void _render_shadow_begin() = 0;
|
||||
virtual void _render_shadow_append(RID p_framebuffer, const PagedArray<RenderGeometryInstance *> &p_instances, const Projection &p_projection, const Transform3D &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool p_use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, const Rect2i &p_rect = Rect2i(), bool p_flip_y = false, bool p_clear_region = true, bool p_begin = true, bool p_end = true, RenderingMethod::RenderInfo *p_render_info = nullptr) = 0;
|
||||
virtual void _render_shadow_process() = 0;
|
||||
virtual void _render_shadow_end(uint32_t p_barrier = RD::BARRIER_MASK_ALL) = 0;
|
||||
|
||||
virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region, float p_exposure_normalization) = 0;
|
||||
virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void _render_sdfgi(Ref<RenderSceneBuffersRD> p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) = 0;
|
||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) = 0;
|
||||
|
||||
void _debug_sdfgi_probes(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth);
|
||||
void _debug_draw_cluster(Ref<RenderSceneBuffersRD> p_render_buffers);
|
||||
|
||||
virtual void _base_uniforms_changed() = 0;
|
||||
virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) = 0;
|
||||
virtual RID _render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) = 0;
|
||||
|
||||
void _process_ssao(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection);
|
||||
void _process_ssr(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_dest_framebuffer, const RID *p_normal_buffer_slices, RID p_specular_buffer, const RID *p_metallic_slices, RID p_environment, const Projection *p_projections, const Vector3 *p_eye_offsets, bool p_use_additive);
|
||||
void _process_sss(Ref<RenderSceneBuffersRD> p_render_buffers, const Projection &p_camera);
|
||||
void _process_ssil(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, RID p_normal_buffer, const Projection &p_projection, const Transform3D &p_transform);
|
||||
|
||||
void _copy_framebuffer_to_ssil(Ref<RenderSceneBuffersRD> p_render_buffers);
|
||||
|
||||
bool _needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
|
||||
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
|
||||
void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi);
|
||||
|
||||
void _pre_opaque_render(RenderDataRD *p_render_data, bool p_use_ssao, bool p_use_ssil, bool p_use_gi, const RID *p_normal_roughness_slices, RID p_voxel_gi_buffer);
|
||||
|
||||
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
|
||||
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
|
||||
void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data);
|
||||
void _post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data);
|
||||
void _disable_clear_request(const RenderDataRD *p_render_data);
|
||||
|
||||
// needed for a single argument calls (material and uv2)
|
||||
PagedArrayPool<RenderGeometryInstance *> cull_argument_pool;
|
||||
PagedArray<RenderGeometryInstance *> cull_argument; //need this to exist
|
||||
|
||||
RendererRD::SSEffects *ss_effects = nullptr;
|
||||
RendererRD::GI gi;
|
||||
RendererRD::SkyRD sky;
|
||||
|
||||
//used for mobile renderer mostly
|
||||
|
||||
typedef int32_t ForwardID;
|
||||
|
||||
enum ForwardIDType {
|
||||
FORWARD_ID_TYPE_OMNI_LIGHT,
|
||||
FORWARD_ID_TYPE_SPOT_LIGHT,
|
||||
FORWARD_ID_TYPE_REFLECTION_PROBE,
|
||||
FORWARD_ID_TYPE_DECAL,
|
||||
FORWARD_ID_MAX,
|
||||
};
|
||||
|
||||
virtual ForwardID _allocate_forward_id(ForwardIDType p_type) { return -1; }
|
||||
virtual void _free_forward_id(ForwardIDType p_type, ForwardID p_id) {}
|
||||
virtual void _map_forward_id(ForwardIDType p_type, ForwardID p_id, uint32_t p_index) {}
|
||||
virtual bool _uses_forward_ids() const { return false; }
|
||||
|
||||
virtual void _update_shader_quality_settings() {}
|
||||
|
||||
private:
|
||||
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
|
||||
static RendererSceneRenderRD *singleton;
|
||||
|
||||
/* REFLECTION ATLAS */
|
||||
|
||||
struct ReflectionAtlas {
|
||||
int count = 0;
|
||||
int size = 0;
|
||||
|
||||
RID reflection;
|
||||
RID depth_buffer;
|
||||
RID depth_fb;
|
||||
|
||||
struct Reflection {
|
||||
RID owner;
|
||||
RendererRD::SkyRD::ReflectionData data;
|
||||
RID fbs[6];
|
||||
};
|
||||
|
||||
Vector<Reflection> reflections;
|
||||
|
||||
ClusterBuilderRD *cluster_builder = nullptr;
|
||||
};
|
||||
|
||||
mutable RID_Owner<ReflectionAtlas> reflection_atlas_owner;
|
||||
|
||||
/* REFLECTION PROBE INSTANCE */
|
||||
|
||||
struct ReflectionProbeInstance {
|
||||
RID probe;
|
||||
int atlas_index = -1;
|
||||
RID atlas;
|
||||
|
||||
bool dirty = true;
|
||||
bool rendering = false;
|
||||
int processing_layer = 1;
|
||||
int processing_side = 0;
|
||||
|
||||
uint32_t render_step = 0;
|
||||
uint64_t last_pass = 0;
|
||||
uint32_t cull_mask = 0;
|
||||
|
||||
ForwardID forward_id = -1;
|
||||
|
||||
Transform3D transform;
|
||||
};
|
||||
|
||||
mutable RID_Owner<ReflectionProbeInstance> reflection_probe_instance_owner;
|
||||
|
||||
/* DECAL INSTANCE */
|
||||
|
||||
struct DecalInstance {
|
||||
RID decal;
|
||||
Transform3D transform;
|
||||
uint32_t cull_mask = 0;
|
||||
ForwardID forward_id = -1;
|
||||
};
|
||||
|
||||
mutable RID_Owner<DecalInstance> decal_instance_owner;
|
||||
|
||||
/* LIGHTMAP INSTANCE */
|
||||
|
||||
struct LightmapInstance {
|
||||
RID lightmap;
|
||||
Transform3D transform;
|
||||
};
|
||||
|
||||
mutable RID_Owner<LightmapInstance> lightmap_instance_owner;
|
||||
|
||||
/* SHADOW ATLAS */
|
||||
|
||||
struct ShadowShrinkStage {
|
||||
RID texture;
|
||||
RID filter_texture;
|
||||
uint32_t size = 0;
|
||||
};
|
||||
|
||||
struct ShadowAtlas {
|
||||
enum {
|
||||
QUADRANT_SHIFT = 27,
|
||||
OMNI_LIGHT_FLAG = 1 << 26,
|
||||
SHADOW_INDEX_MASK = OMNI_LIGHT_FLAG - 1,
|
||||
SHADOW_INVALID = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
struct Quadrant {
|
||||
uint32_t subdivision = 0;
|
||||
|
||||
struct Shadow {
|
||||
RID owner;
|
||||
uint64_t version = 0;
|
||||
uint64_t fog_version = 0; // used for fog
|
||||
uint64_t alloc_tick = 0;
|
||||
|
||||
Shadow() {}
|
||||
};
|
||||
|
||||
Vector<Shadow> shadows;
|
||||
|
||||
Quadrant() {}
|
||||
} quadrants[4];
|
||||
|
||||
int size_order[4] = { 0, 1, 2, 3 };
|
||||
uint32_t smallest_subdiv = 0;
|
||||
|
||||
int size = 0;
|
||||
bool use_16_bits = true;
|
||||
|
||||
RID depth;
|
||||
RID fb; //for copying
|
||||
|
||||
HashMap<RID, uint32_t> shadow_owners;
|
||||
};
|
||||
|
||||
RID_Owner<ShadowAtlas> shadow_atlas_owner;
|
||||
|
||||
void _update_shadow_atlas(ShadowAtlas *shadow_atlas);
|
||||
|
||||
void _shadow_atlas_invalidate_shadow(RendererSceneRenderRD::ShadowAtlas::Quadrant::Shadow *p_shadow, RID p_atlas, RendererSceneRenderRD::ShadowAtlas *p_shadow_atlas, uint32_t p_quadrant, uint32_t p_shadow_idx);
|
||||
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
|
||||
bool _shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
|
||||
|
||||
RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set
|
||||
RS::ShadowQuality directional_shadow_quality = RS::SHADOW_QUALITY_MAX;
|
||||
float shadows_quality_radius = 1.0;
|
||||
float directional_shadow_quality_radius = 1.0;
|
||||
|
||||
float *directional_penumbra_shadow_kernel = nullptr;
|
||||
float *directional_soft_shadow_kernel = nullptr;
|
||||
float *penumbra_shadow_kernel = nullptr;
|
||||
float *soft_shadow_kernel = nullptr;
|
||||
int directional_penumbra_shadow_samples = 0;
|
||||
int directional_soft_shadow_samples = 0;
|
||||
int penumbra_shadow_samples = 0;
|
||||
int soft_shadow_samples = 0;
|
||||
RS::DecalFilter decals_filter = RS::DECAL_FILTER_LINEAR_MIPMAPS;
|
||||
RS::LightProjectorFilter light_projectors_filter = RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS;
|
||||
|
||||
/* DIRECTIONAL SHADOW */
|
||||
|
||||
struct DirectionalShadow {
|
||||
RID depth;
|
||||
RID fb; //when renderign direct
|
||||
|
||||
int light_count = 0;
|
||||
int size = 0;
|
||||
bool use_16_bits = true;
|
||||
int current_light = 0;
|
||||
} directional_shadow;
|
||||
|
||||
void _update_directional_shadow_atlas();
|
||||
|
||||
/* SHADOW CUBEMAPS */
|
||||
|
||||
struct ShadowCubemap {
|
||||
RID cubemap;
|
||||
RID side_fb[6];
|
||||
};
|
||||
|
||||
HashMap<int, ShadowCubemap> shadow_cubemaps;
|
||||
ShadowCubemap *_get_shadow_cubemap(int p_size);
|
||||
|
||||
void _create_shadow_cubemaps();
|
||||
|
||||
/* LIGHT INSTANCE */
|
||||
|
||||
struct LightInstance {
|
||||
struct ShadowTransform {
|
||||
Projection camera;
|
||||
Transform3D transform;
|
||||
float farplane;
|
||||
float split;
|
||||
float bias_scale;
|
||||
float shadow_texel_size;
|
||||
float range_begin;
|
||||
Rect2 atlas_rect;
|
||||
Vector2 uv_scale;
|
||||
};
|
||||
|
||||
RS::LightType light_type = RS::LIGHT_DIRECTIONAL;
|
||||
|
||||
ShadowTransform shadow_transform[6];
|
||||
|
||||
AABB aabb;
|
||||
RID self;
|
||||
RID light;
|
||||
Transform3D transform;
|
||||
|
||||
Vector3 light_vector;
|
||||
Vector3 spot_vector;
|
||||
float linear_att = 0.0;
|
||||
|
||||
uint64_t shadow_pass = 0;
|
||||
uint64_t last_scene_pass = 0;
|
||||
uint64_t last_scene_shadow_pass = 0;
|
||||
uint64_t last_pass = 0;
|
||||
uint32_t cull_mask = 0;
|
||||
uint32_t light_directional_index = 0;
|
||||
|
||||
Rect2 directional_rect;
|
||||
|
||||
HashSet<RID> shadow_atlases; //shadow atlases where this light is registered
|
||||
|
||||
ForwardID forward_id = -1;
|
||||
|
||||
LightInstance() {}
|
||||
};
|
||||
|
||||
mutable RID_Owner<LightInstance> light_instance_owner;
|
||||
|
||||
/* ENVIRONMENT */
|
||||
|
||||
RS::EnvironmentSSAOQuality ssao_quality = RS::ENV_SSAO_QUALITY_MEDIUM;
|
||||
@ -401,200 +138,97 @@ private:
|
||||
|
||||
bool use_physical_light_units = false;
|
||||
|
||||
/* Cluster builder */
|
||||
////////////////////////////////
|
||||
|
||||
ClusterBuilderSharedDataRD cluster_builder_shared;
|
||||
ClusterBuilderRD *current_cluster_builder = nullptr;
|
||||
virtual RendererRD::ForwardIDStorage *create_forward_id_storage() { return memnew(RendererRD::ForwardIDStorage); };
|
||||
|
||||
void _update_vrs(Ref<RenderSceneBuffersRD> p_render_buffers);
|
||||
|
||||
virtual void setup_render_buffer_data(Ref<RenderSceneBuffersRD> p_render_buffers) = 0;
|
||||
|
||||
virtual void _render_scene(RenderDataRD *p_render_data, const Color &p_default_color) = 0;
|
||||
virtual void _render_buffers_debug_draw(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer);
|
||||
|
||||
virtual void _render_material(const Transform3D &p_cam_transform, const Projection &p_cam_projection, bool p_cam_orthogonal, const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region, float p_exposure_normalization) = 0;
|
||||
virtual void _render_uv2(const PagedArray<RenderGeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
|
||||
virtual void _render_sdfgi(Ref<RenderSceneBuffersRD> p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<RenderGeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture, float p_exposure_normalization) = 0;
|
||||
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform3D &p_cam_transform, const Projection &p_cam_projection, const PagedArray<RenderGeometryInstance *> &p_instances) = 0;
|
||||
|
||||
void _debug_sdfgi_probes(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_framebuffer, uint32_t p_view_count, const Projection *p_camera_with_transforms, bool p_will_continue_color, bool p_will_continue_depth);
|
||||
|
||||
virtual RID _render_buffers_get_normal_texture(Ref<RenderSceneBuffersRD> p_render_buffers) = 0;
|
||||
virtual RID _render_buffers_get_velocity_texture(Ref<RenderSceneBuffersRD> p_render_buffers) = 0;
|
||||
|
||||
bool _needs_post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
|
||||
void _post_prepass_render(RenderDataRD *p_render_data, bool p_use_gi);
|
||||
void _pre_resolve_render(RenderDataRD *p_render_data, bool p_use_gi);
|
||||
|
||||
void _render_buffers_copy_screen_texture(const RenderDataRD *p_render_data);
|
||||
void _render_buffers_copy_depth_texture(const RenderDataRD *p_render_data);
|
||||
void _render_buffers_post_process_and_tonemap(const RenderDataRD *p_render_data);
|
||||
void _post_process_subpass(RID p_source_texture, RID p_framebuffer, const RenderDataRD *p_render_data);
|
||||
void _disable_clear_request(const RenderDataRD *p_render_data);
|
||||
|
||||
// needed for a single argument calls (material and uv2)
|
||||
PagedArrayPool<RenderGeometryInstance *> cull_argument_pool;
|
||||
PagedArray<RenderGeometryInstance *> cull_argument; //need this to exist
|
||||
|
||||
RendererRD::SkyRD sky;
|
||||
RendererRD::GI gi;
|
||||
|
||||
virtual void _update_shader_quality_settings() {}
|
||||
|
||||
private:
|
||||
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
|
||||
static RendererSceneRenderRD *singleton;
|
||||
|
||||
/* Shadow atlas */
|
||||
RS::ShadowQuality shadows_quality = RS::SHADOW_QUALITY_MAX; //So it always updates when first set
|
||||
RS::ShadowQuality directional_shadow_quality = RS::SHADOW_QUALITY_MAX;
|
||||
float shadows_quality_radius = 1.0;
|
||||
float directional_shadow_quality_radius = 1.0;
|
||||
|
||||
float *directional_penumbra_shadow_kernel = nullptr;
|
||||
float *directional_soft_shadow_kernel = nullptr;
|
||||
float *penumbra_shadow_kernel = nullptr;
|
||||
float *soft_shadow_kernel = nullptr;
|
||||
int directional_penumbra_shadow_samples = 0;
|
||||
int directional_soft_shadow_samples = 0;
|
||||
int penumbra_shadow_samples = 0;
|
||||
int soft_shadow_samples = 0;
|
||||
RS::DecalFilter decals_filter = RS::DECAL_FILTER_LINEAR_MIPMAPS;
|
||||
RS::LightProjectorFilter light_projectors_filter = RS::LIGHT_PROJECTOR_FILTER_LINEAR_MIPMAPS;
|
||||
|
||||
/* RENDER BUFFERS */
|
||||
|
||||
// TODO move into effects/luminance.h/cpp
|
||||
void _allocate_luminance_textures(Ref<RenderSceneBuffersRD> rb);
|
||||
|
||||
void _render_buffers_debug_draw(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_shadow_atlas, RID p_occlusion_buffer);
|
||||
|
||||
/* GI */
|
||||
bool screen_space_roughness_limiter = false;
|
||||
float screen_space_roughness_limiter_amount = 0.25;
|
||||
float screen_space_roughness_limiter_limit = 0.18;
|
||||
|
||||
/* Cluster */
|
||||
|
||||
struct Cluster {
|
||||
/* Scene State UBO */
|
||||
|
||||
// !BAS! Most data here is not just used by our clustering logic but also by other lighting implementations. Maybe rename this struct to something more appropriate
|
||||
|
||||
enum {
|
||||
REFLECTION_AMBIENT_DISABLED = 0,
|
||||
REFLECTION_AMBIENT_ENVIRONMENT = 1,
|
||||
REFLECTION_AMBIENT_COLOR = 2,
|
||||
};
|
||||
|
||||
struct ReflectionData {
|
||||
float box_extents[3];
|
||||
float index;
|
||||
float box_offset[3];
|
||||
uint32_t mask;
|
||||
float ambient[3]; // ambient color,
|
||||
float intensity;
|
||||
uint32_t exterior;
|
||||
uint32_t box_project;
|
||||
uint32_t ambient_mode;
|
||||
float exposure_normalization;
|
||||
float local_matrix[16]; // up to here for spot and omni, rest is for directional
|
||||
};
|
||||
|
||||
struct LightData {
|
||||
float position[3];
|
||||
float inv_radius;
|
||||
float direction[3]; // in omni, x and y are used for dual paraboloid offset
|
||||
float size;
|
||||
|
||||
float color[3];
|
||||
float attenuation;
|
||||
|
||||
float inv_spot_attenuation;
|
||||
float cos_spot_angle;
|
||||
float specular_amount;
|
||||
float shadow_opacity;
|
||||
|
||||
float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv
|
||||
float shadow_matrix[16];
|
||||
float shadow_bias;
|
||||
float shadow_normal_bias;
|
||||
float transmittance_bias;
|
||||
float soft_shadow_size;
|
||||
float soft_shadow_scale;
|
||||
uint32_t mask;
|
||||
float volumetric_fog_energy;
|
||||
uint32_t bake_mode;
|
||||
float projector_rect[4];
|
||||
};
|
||||
|
||||
struct DirectionalLightData {
|
||||
float direction[3];
|
||||
float energy;
|
||||
float color[3];
|
||||
float size;
|
||||
float specular;
|
||||
uint32_t mask;
|
||||
float softshadow_angle;
|
||||
float soft_shadow_scale;
|
||||
uint32_t blend_splits;
|
||||
float shadow_opacity;
|
||||
float fade_from;
|
||||
float fade_to;
|
||||
uint32_t pad[2];
|
||||
uint32_t bake_mode;
|
||||
float volumetric_fog_energy;
|
||||
float shadow_bias[4];
|
||||
float shadow_normal_bias[4];
|
||||
float shadow_transmittance_bias[4];
|
||||
float shadow_z_range[4];
|
||||
float shadow_range_begin[4];
|
||||
float shadow_split_offsets[4];
|
||||
float shadow_matrices[4][16];
|
||||
float uv_scale1[2];
|
||||
float uv_scale2[2];
|
||||
float uv_scale3[2];
|
||||
float uv_scale4[2];
|
||||
};
|
||||
|
||||
struct DecalData {
|
||||
float xform[16];
|
||||
float inv_extents[3];
|
||||
float albedo_mix;
|
||||
float albedo_rect[4];
|
||||
float normal_rect[4];
|
||||
float orm_rect[4];
|
||||
float emission_rect[4];
|
||||
float modulate[4];
|
||||
float emission_energy;
|
||||
uint32_t mask;
|
||||
float upper_fade;
|
||||
float lower_fade;
|
||||
float normal_xform[12];
|
||||
float normal[3];
|
||||
float normal_fade;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct InstanceSort {
|
||||
float depth;
|
||||
T *instance = nullptr;
|
||||
bool operator<(const InstanceSort &p_sort) const {
|
||||
return depth < p_sort.depth;
|
||||
}
|
||||
};
|
||||
|
||||
ReflectionData *reflections = nullptr;
|
||||
InstanceSort<ReflectionProbeInstance> *reflection_sort;
|
||||
uint32_t max_reflections;
|
||||
RID reflection_buffer;
|
||||
uint32_t max_reflection_probes_per_instance;
|
||||
uint32_t reflection_count = 0;
|
||||
|
||||
DecalData *decals = nullptr;
|
||||
InstanceSort<DecalInstance> *decal_sort;
|
||||
uint32_t max_decals;
|
||||
RID decal_buffer;
|
||||
uint32_t decal_count;
|
||||
|
||||
LightData *omni_lights = nullptr;
|
||||
LightData *spot_lights = nullptr;
|
||||
|
||||
InstanceSort<LightInstance> *omni_light_sort;
|
||||
InstanceSort<LightInstance> *spot_light_sort;
|
||||
uint32_t max_lights;
|
||||
RID omni_light_buffer;
|
||||
RID spot_light_buffer;
|
||||
uint32_t omni_light_count = 0;
|
||||
uint32_t spot_light_count = 0;
|
||||
|
||||
DirectionalLightData *directional_lights = nullptr;
|
||||
uint32_t max_directional_lights;
|
||||
RID directional_light_buffer;
|
||||
|
||||
} cluster;
|
||||
|
||||
struct RenderState {
|
||||
const RendererSceneRender::RenderShadowData *render_shadows = nullptr;
|
||||
int render_shadow_count = 0;
|
||||
const RendererSceneRender::RenderSDFGIData *render_sdfgi_regions = nullptr;
|
||||
int render_sdfgi_region_count = 0;
|
||||
const RendererSceneRender::RenderSDFGIUpdateData *sdfgi_update_data = nullptr;
|
||||
|
||||
uint32_t voxel_gi_count = 0;
|
||||
|
||||
LocalVector<int> cube_shadows;
|
||||
LocalVector<int> shadows;
|
||||
LocalVector<int> directional_shadows;
|
||||
|
||||
bool depth_prepass_used; // this does not seem used anywhere...
|
||||
} render_state;
|
||||
|
||||
RID shadow_sampler;
|
||||
/* Light data */
|
||||
|
||||
uint64_t scene_pass = 0;
|
||||
uint64_t shadow_atlas_realloc_tolerance_msec = 500;
|
||||
|
||||
uint32_t max_cluster_elements = 512;
|
||||
|
||||
void _render_shadow_pass(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<RenderGeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_mesh_lod_threshold = 0.0, bool p_open_pass = true, bool p_close_pass = true, bool p_clear_region = true, RenderingMethod::RenderInfo *p_render_info = nullptr);
|
||||
|
||||
/* Volumetric Fog */
|
||||
|
||||
uint32_t volumetric_fog_size = 128;
|
||||
uint32_t volumetric_fog_depth = 128;
|
||||
bool volumetric_fog_filter_active = true;
|
||||
|
||||
void _update_volumetric_fog(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_environment, const Projection &p_cam_projection, const Transform3D &p_cam_transform, const Transform3D &p_prev_cam_inv_transform, RID p_shadow_atlas, int p_directional_light_count, bool p_use_directional_shadows, int p_positional_light_count, int p_voxel_gi_count, const PagedArray<RID> &p_fog_volumes);
|
||||
|
||||
public:
|
||||
static RendererSceneRenderRD *get_singleton() { return singleton; }
|
||||
|
||||
/* Cluster builder */
|
||||
ClusterBuilderSharedDataRD *get_cluster_builder_shared() { return &cluster_builder_shared; }
|
||||
/* LIGHTING */
|
||||
|
||||
virtual void setup_added_reflection_probe(const Transform3D &p_transform, const Vector3 &p_half_extents){};
|
||||
virtual void setup_added_light(const RS::LightType p_type, const Transform3D &p_transform, float p_radius, float p_spot_aperture){};
|
||||
virtual void setup_added_decal(const Transform3D &p_transform, const Vector3 &p_half_extents){};
|
||||
|
||||
/* GI */
|
||||
|
||||
@ -604,42 +238,6 @@ public:
|
||||
|
||||
RendererRD::SkyRD *get_sky() { return &sky; }
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
virtual RID shadow_atlas_create() override;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override;
|
||||
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_instance, float p_coverage, uint64_t p_light_version) override;
|
||||
_FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, false);
|
||||
return atlas->shadow_owners.has(p_light_intance);
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID shadow_atlas_get_texture(RID p_atlas) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, RID());
|
||||
return atlas->depth;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Size2i shadow_atlas_get_size(RID p_atlas) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, Size2i());
|
||||
return Size2(atlas->size, atlas->size);
|
||||
}
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override;
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance) override;
|
||||
virtual void set_directional_shadow_count(int p_count) override;
|
||||
|
||||
_FORCE_INLINE_ RID directional_shadow_get_texture() {
|
||||
return directional_shadow.depth;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Size2i directional_shadow_get_size() {
|
||||
return Size2i(directional_shadow.size, directional_shadow.size);
|
||||
}
|
||||
|
||||
/* SDFGI UPDATE */
|
||||
|
||||
virtual void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) override;
|
||||
@ -683,249 +281,22 @@ public:
|
||||
return use_physical_light_units;
|
||||
}
|
||||
|
||||
/* LIGHT INSTANCE API */
|
||||
/* REFLECTION PROBE */
|
||||
|
||||
virtual RID light_instance_create(RID p_light) override;
|
||||
virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override;
|
||||
virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override;
|
||||
virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override;
|
||||
virtual void light_instance_mark_visible(RID p_light_instance) override;
|
||||
|
||||
_FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->light;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Transform3D light_instance_get_base_transform(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->transform;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2 light_instance_get_shadow_atlas_rect(RID p_light_instance, RID p_shadow_atlas, Vector2i &r_omni_offset) {
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas);
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
uint32_t key = shadow_atlas->shadow_owners[li->self];
|
||||
|
||||
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
|
||||
uint32_t shadow = key & ShadowAtlas::SHADOW_INDEX_MASK;
|
||||
|
||||
ERR_FAIL_COND_V(shadow >= (uint32_t)shadow_atlas->quadrants[quadrant].shadows.size(), Rect2());
|
||||
|
||||
uint32_t atlas_size = shadow_atlas->size;
|
||||
uint32_t quadrant_size = atlas_size >> 1;
|
||||
|
||||
uint32_t x = (quadrant & 1) * quadrant_size;
|
||||
uint32_t y = (quadrant >> 1) * quadrant_size;
|
||||
|
||||
uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision);
|
||||
x += (shadow % shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
|
||||
y += (shadow / shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
|
||||
|
||||
if (key & ShadowAtlas::OMNI_LIGHT_FLAG) {
|
||||
if (((shadow + 1) % shadow_atlas->quadrants[quadrant].subdivision) == 0) {
|
||||
r_omni_offset.x = 1 - int(shadow_atlas->quadrants[quadrant].subdivision);
|
||||
r_omni_offset.y = 1;
|
||||
} else {
|
||||
r_omni_offset.x = 1;
|
||||
r_omni_offset.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t width = shadow_size;
|
||||
uint32_t height = shadow_size;
|
||||
|
||||
return Rect2(x / float(shadow_atlas->size), y / float(shadow_atlas->size), width / float(shadow_atlas->size), height / float(shadow_atlas->size));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Projection light_instance_get_shadow_camera(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].camera;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float light_instance_get_shadow_texel_size(RID p_light_instance, RID p_shadow_atlas) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
ERR_FAIL_COND_V(!li->shadow_atlases.has(p_shadow_atlas), 0);
|
||||
#endif
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas);
|
||||
ERR_FAIL_COND_V(!shadow_atlas, 0);
|
||||
#ifdef DEBUG_ENABLED
|
||||
ERR_FAIL_COND_V(!shadow_atlas->shadow_owners.has(p_light_instance), 0);
|
||||
#endif
|
||||
uint32_t key = shadow_atlas->shadow_owners[p_light_instance];
|
||||
|
||||
uint32_t quadrant = (key >> ShadowAtlas::QUADRANT_SHIFT) & 0x3;
|
||||
|
||||
uint32_t quadrant_size = shadow_atlas->size >> 1;
|
||||
|
||||
uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision);
|
||||
|
||||
return float(1.0) / shadow_size;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Transform3D
|
||||
light_instance_get_shadow_transform(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].transform;
|
||||
}
|
||||
_FORCE_INLINE_ float light_instance_get_shadow_bias_scale(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].bias_scale;
|
||||
}
|
||||
_FORCE_INLINE_ float light_instance_get_shadow_range(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].farplane;
|
||||
}
|
||||
_FORCE_INLINE_ float light_instance_get_shadow_range_begin(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].range_begin;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Vector2 light_instance_get_shadow_uv_scale(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].uv_scale;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2 light_instance_get_directional_shadow_atlas_rect(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].atlas_rect;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float light_instance_get_directional_shadow_split(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].split;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float light_instance_get_directional_shadow_texel_size(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].shadow_texel_size;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void light_instance_set_render_pass(RID p_light_instance, uint64_t p_pass) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
li->last_pass = p_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint64_t light_instance_get_render_pass(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->last_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ ForwardID light_instance_get_forward_id(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->forward_id;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->light_type;
|
||||
}
|
||||
virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth);
|
||||
|
||||
/* FOG VOLUMES */
|
||||
|
||||
uint32_t get_volumetric_fog_size() const { return volumetric_fog_size; }
|
||||
uint32_t get_volumetric_fog_depth() const { return volumetric_fog_depth; }
|
||||
bool get_volumetric_fog_filter_active() const { return volumetric_fog_filter_active; }
|
||||
|
||||
virtual RID fog_volume_instance_create(RID p_fog_volume) override;
|
||||
virtual void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) override;
|
||||
virtual void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) override;
|
||||
virtual RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const override;
|
||||
virtual Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const override;
|
||||
|
||||
virtual RID reflection_atlas_create() override;
|
||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override;
|
||||
virtual int reflection_atlas_get_size(RID p_ref_atlas) const override;
|
||||
|
||||
_FORCE_INLINE_ RID reflection_atlas_get_texture(RID p_ref_atlas) {
|
||||
ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_ref_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, RID());
|
||||
return atlas->reflection;
|
||||
}
|
||||
|
||||
virtual RID reflection_probe_instance_create(RID p_probe) override;
|
||||
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override;
|
||||
virtual void reflection_probe_release_atlas_index(RID p_instance) override;
|
||||
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override;
|
||||
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override;
|
||||
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override;
|
||||
virtual RID reflection_probe_create_framebuffer(RID p_color, RID p_depth);
|
||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override;
|
||||
|
||||
uint32_t reflection_probe_instance_get_resolution(RID p_instance);
|
||||
RID reflection_probe_instance_get_framebuffer(RID p_instance, int p_index);
|
||||
RID reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index);
|
||||
|
||||
_FORCE_INLINE_ RID reflection_probe_instance_get_probe(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, RID());
|
||||
|
||||
return rpi->probe;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ ForwardID reflection_probe_instance_get_forward_id(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, 0);
|
||||
|
||||
return rpi->forward_id;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void reflection_probe_instance_set_render_pass(RID p_instance, uint32_t p_render_pass) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND(!rpi);
|
||||
rpi->last_pass = p_render_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t reflection_probe_instance_get_render_pass(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, 0);
|
||||
|
||||
return rpi->last_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Transform3D reflection_probe_instance_get_transform(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, Transform3D());
|
||||
|
||||
return rpi->transform;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int reflection_probe_instance_get_atlas_index(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, -1);
|
||||
|
||||
return rpi->atlas_index;
|
||||
}
|
||||
|
||||
virtual RID decal_instance_create(RID p_decal) override;
|
||||
virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) override;
|
||||
|
||||
_FORCE_INLINE_ RID decal_instance_get_base(RID p_decal) const {
|
||||
DecalInstance *decal = decal_instance_owner.get_or_null(p_decal);
|
||||
return decal->decal;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ ForwardID decal_instance_get_forward_id(RID p_decal) const {
|
||||
DecalInstance *decal = decal_instance_owner.get_or_null(p_decal);
|
||||
return decal->forward_id;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Transform3D decal_instance_get_transform(RID p_decal) const {
|
||||
DecalInstance *decal = decal_instance_owner.get_or_null(p_decal);
|
||||
return decal->transform;
|
||||
}
|
||||
|
||||
virtual RID lightmap_instance_create(RID p_lightmap) override;
|
||||
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override;
|
||||
_FORCE_INLINE_ bool lightmap_instance_is_valid(RID p_lightmap_instance) {
|
||||
return lightmap_instance_owner.get_or_null(p_lightmap_instance) != nullptr;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID lightmap_instance_get_lightmap(RID p_lightmap_instance) {
|
||||
LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap_instance);
|
||||
return li->lightmap;
|
||||
}
|
||||
_FORCE_INLINE_ Transform3D lightmap_instance_get_transform(RID p_lightmap_instance) {
|
||||
LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap_instance);
|
||||
return li->transform;
|
||||
}
|
||||
|
||||
/* gi light probes */
|
||||
|
||||
virtual RID voxel_gi_instance_create(RID p_base) override;
|
||||
@ -944,6 +315,7 @@ public:
|
||||
|
||||
RID render_buffers_get_default_voxel_gi_buffer();
|
||||
|
||||
virtual void base_uniforms_changed() = 0;
|
||||
virtual void update_uniform_sets(){};
|
||||
|
||||
virtual void render_scene(const Ref<RenderSceneBuffers> &p_render_buffers, const CameraData *p_camera_data, const CameraData *p_prev_camera_data, const PagedArray<RenderGeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_voxel_gi_instances, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, const PagedArray<RID> &p_fog_volumes, RID p_environment, RID p_camera_attributes, RID p_shadow_atlas, RID p_occluder_debug_tex, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_mesh_lod_threshold, const RenderShadowData *p_render_shadows, int p_render_shadow_count, const RenderSDFGIData *p_render_sdfgi_regions, int p_render_sdfgi_region_count, const RenderSDFGIUpdateData *p_sdfgi_update_data = nullptr, RenderingMethod::RenderInfo *r_render_info = nullptr) override;
|
||||
@ -1036,18 +408,10 @@ public:
|
||||
|
||||
virtual void set_time(double p_time, double p_step) override;
|
||||
|
||||
RID get_reflection_probe_buffer();
|
||||
RID get_omni_light_buffer();
|
||||
RID get_spot_light_buffer();
|
||||
RID get_directional_light_buffer();
|
||||
RID get_decal_buffer();
|
||||
int get_max_directional_lights() const;
|
||||
|
||||
virtual void sdfgi_set_debug_probe_select(const Vector3 &p_position, const Vector3 &p_dir) override;
|
||||
|
||||
virtual bool is_vrs_supported() const;
|
||||
virtual bool is_dynamic_gi_supported() const;
|
||||
virtual bool is_clustered_enabled() const;
|
||||
virtual bool is_volumetric_supported() const;
|
||||
virtual uint32_t get_max_elements() const;
|
||||
|
||||
|
@ -0,0 +1,43 @@
|
||||
/*************************************************************************/
|
||||
/* forward_id_storage.cpp */
|
||||
/*************************************************************************/
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#include "forward_id_storage.h"
|
||||
|
||||
using namespace RendererRD;
|
||||
|
||||
ForwardIDStorage *ForwardIDStorage::singleton = nullptr;
|
||||
|
||||
ForwardIDStorage::ForwardIDStorage() {
|
||||
singleton = this;
|
||||
}
|
||||
|
||||
ForwardIDStorage::~ForwardIDStorage() {
|
||||
singleton = nullptr;
|
||||
}
|
@ -0,0 +1,68 @@
|
||||
/*************************************************************************/
|
||||
/* forward_id_storage.h */
|
||||
/*************************************************************************/
|
||||
/* 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. */
|
||||
/*************************************************************************/
|
||||
|
||||
#ifndef FORWARD_ID_STORAGE_H
|
||||
#define FORWARD_ID_STORAGE_H
|
||||
|
||||
#include "servers/rendering/storage/utilities.h"
|
||||
|
||||
class RendererSceneRenderRD;
|
||||
|
||||
namespace RendererRD {
|
||||
|
||||
typedef int32_t ForwardID;
|
||||
|
||||
enum ForwardIDType {
|
||||
FORWARD_ID_TYPE_OMNI_LIGHT,
|
||||
FORWARD_ID_TYPE_SPOT_LIGHT,
|
||||
FORWARD_ID_TYPE_REFLECTION_PROBE,
|
||||
FORWARD_ID_TYPE_DECAL,
|
||||
FORWARD_ID_MAX,
|
||||
};
|
||||
|
||||
class ForwardIDStorage {
|
||||
private:
|
||||
static ForwardIDStorage *singleton;
|
||||
|
||||
public:
|
||||
static ForwardIDStorage *get_singleton() { return singleton; }
|
||||
|
||||
ForwardIDStorage();
|
||||
virtual ~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 bool uses_forward_ids() const { return false; }
|
||||
};
|
||||
|
||||
} // namespace RendererRD
|
||||
|
||||
#endif // FORWARD_ID_STORAGE_H
|
File diff suppressed because it is too large
Load Diff
@ -32,17 +32,32 @@
|
||||
#define LIGHT_STORAGE_RD_H
|
||||
|
||||
#include "core/templates/local_vector.h"
|
||||
#include "core/templates/paged_array.h"
|
||||
#include "core/templates/rid_owner.h"
|
||||
#include "core/templates/self_list.h"
|
||||
#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
|
||||
#include "servers/rendering/renderer_rd/environment/sky.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/forward_id_storage.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
|
||||
#include "servers/rendering/storage/light_storage.h"
|
||||
#include "servers/rendering/storage/utilities.h"
|
||||
|
||||
struct RenderDataRD;
|
||||
|
||||
namespace RendererRD {
|
||||
|
||||
class LightStorage : public RendererLightStorage {
|
||||
public:
|
||||
enum ShadowAtlastQuadrant {
|
||||
QUADRANT_SHIFT = 27,
|
||||
OMNI_LIGHT_FLAG = 1 << 26,
|
||||
SHADOW_INDEX_MASK = OMNI_LIGHT_FLAG - 1,
|
||||
SHADOW_INVALID = 0xFFFFFFFF
|
||||
};
|
||||
|
||||
private:
|
||||
static LightStorage *singleton;
|
||||
uint32_t max_cluster_elements = 512;
|
||||
|
||||
/* LIGHT */
|
||||
struct Light {
|
||||
@ -71,6 +86,135 @@ private:
|
||||
|
||||
mutable RID_Owner<Light, true> light_owner;
|
||||
|
||||
/* LIGHT INSTANCE */
|
||||
|
||||
struct LightInstance {
|
||||
struct ShadowTransform {
|
||||
Projection camera;
|
||||
Transform3D transform;
|
||||
float farplane;
|
||||
float split;
|
||||
float bias_scale;
|
||||
float shadow_texel_size;
|
||||
float range_begin;
|
||||
Rect2 atlas_rect;
|
||||
Vector2 uv_scale;
|
||||
};
|
||||
|
||||
RS::LightType light_type = RS::LIGHT_DIRECTIONAL;
|
||||
|
||||
ShadowTransform shadow_transform[6];
|
||||
|
||||
AABB aabb;
|
||||
RID self;
|
||||
RID light;
|
||||
Transform3D transform;
|
||||
|
||||
Vector3 light_vector;
|
||||
Vector3 spot_vector;
|
||||
float linear_att = 0.0;
|
||||
|
||||
uint64_t shadow_pass = 0;
|
||||
uint64_t last_scene_pass = 0;
|
||||
uint64_t last_scene_shadow_pass = 0;
|
||||
uint64_t last_pass = 0;
|
||||
uint32_t cull_mask = 0;
|
||||
uint32_t light_directional_index = 0;
|
||||
|
||||
Rect2 directional_rect;
|
||||
|
||||
HashSet<RID> shadow_atlases; //shadow atlases where this light is registered
|
||||
|
||||
ForwardID forward_id = -1;
|
||||
|
||||
LightInstance() {}
|
||||
};
|
||||
|
||||
mutable RID_Owner<LightInstance> light_instance_owner;
|
||||
|
||||
/* OMNI/SPOT LIGHT DATA */
|
||||
|
||||
struct LightData {
|
||||
float position[3];
|
||||
float inv_radius;
|
||||
float direction[3]; // in omni, x and y are used for dual paraboloid offset
|
||||
float size;
|
||||
|
||||
float color[3];
|
||||
float attenuation;
|
||||
|
||||
float inv_spot_attenuation;
|
||||
float cos_spot_angle;
|
||||
float specular_amount;
|
||||
float shadow_opacity;
|
||||
|
||||
float atlas_rect[4]; // in omni, used for atlas uv, in spot, used for projector uv
|
||||
float shadow_matrix[16];
|
||||
float shadow_bias;
|
||||
float shadow_normal_bias;
|
||||
float transmittance_bias;
|
||||
float soft_shadow_size;
|
||||
float soft_shadow_scale;
|
||||
uint32_t mask;
|
||||
float volumetric_fog_energy;
|
||||
uint32_t bake_mode;
|
||||
float projector_rect[4];
|
||||
};
|
||||
|
||||
struct LightInstanceDepthSort {
|
||||
float depth;
|
||||
LightInstance *light_instance;
|
||||
Light *light;
|
||||
bool operator<(const LightInstanceDepthSort &p_sort) const {
|
||||
return depth < p_sort.depth;
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t max_lights;
|
||||
uint32_t omni_light_count = 0;
|
||||
uint32_t spot_light_count = 0;
|
||||
LightData *omni_lights = nullptr;
|
||||
LightData *spot_lights = nullptr;
|
||||
LightInstanceDepthSort *omni_light_sort = nullptr;
|
||||
LightInstanceDepthSort *spot_light_sort = nullptr;
|
||||
RID omni_light_buffer;
|
||||
RID spot_light_buffer;
|
||||
|
||||
/* DIRECTIONAL LIGHT DATA */
|
||||
|
||||
struct DirectionalLightData {
|
||||
float direction[3];
|
||||
float energy;
|
||||
float color[3];
|
||||
float size;
|
||||
float specular;
|
||||
uint32_t mask;
|
||||
float softshadow_angle;
|
||||
float soft_shadow_scale;
|
||||
uint32_t blend_splits;
|
||||
float shadow_opacity;
|
||||
float fade_from;
|
||||
float fade_to;
|
||||
uint32_t pad[2];
|
||||
uint32_t bake_mode;
|
||||
float volumetric_fog_energy;
|
||||
float shadow_bias[4];
|
||||
float shadow_normal_bias[4];
|
||||
float shadow_transmittance_bias[4];
|
||||
float shadow_z_range[4];
|
||||
float shadow_range_begin[4];
|
||||
float shadow_split_offsets[4];
|
||||
float shadow_matrices[4][16];
|
||||
float uv_scale1[2];
|
||||
float uv_scale2[2];
|
||||
float uv_scale3[2];
|
||||
float uv_scale4[2];
|
||||
};
|
||||
|
||||
uint32_t max_directional_lights;
|
||||
DirectionalLightData *directional_lights = nullptr;
|
||||
RID directional_light_buffer;
|
||||
|
||||
/* REFLECTION PROBE */
|
||||
|
||||
struct ReflectionProbe {
|
||||
@ -94,6 +238,89 @@ private:
|
||||
};
|
||||
mutable RID_Owner<ReflectionProbe, true> reflection_probe_owner;
|
||||
|
||||
/* REFLECTION ATLAS */
|
||||
|
||||
struct ReflectionAtlas {
|
||||
int count = 0;
|
||||
int size = 0;
|
||||
|
||||
RID reflection;
|
||||
RID depth_buffer;
|
||||
RID depth_fb;
|
||||
|
||||
struct Reflection {
|
||||
RID owner;
|
||||
RendererRD::SkyRD::ReflectionData data;
|
||||
RID fbs[6];
|
||||
};
|
||||
|
||||
Vector<Reflection> reflections;
|
||||
|
||||
ClusterBuilderRD *cluster_builder = nullptr; // only used if cluster builder is supported by the renderer.
|
||||
};
|
||||
|
||||
mutable RID_Owner<ReflectionAtlas> reflection_atlas_owner;
|
||||
|
||||
/* REFLECTION PROBE INSTANCE */
|
||||
|
||||
struct ReflectionProbeInstance {
|
||||
RID probe;
|
||||
int atlas_index = -1;
|
||||
RID atlas;
|
||||
|
||||
bool dirty = true;
|
||||
bool rendering = false;
|
||||
int processing_layer = 1;
|
||||
int processing_side = 0;
|
||||
|
||||
uint32_t render_step = 0;
|
||||
uint64_t last_pass = 0;
|
||||
uint32_t cull_mask = 0;
|
||||
|
||||
RendererRD::ForwardID forward_id = -1;
|
||||
|
||||
Transform3D transform;
|
||||
};
|
||||
|
||||
mutable RID_Owner<ReflectionProbeInstance> reflection_probe_instance_owner;
|
||||
|
||||
/* REFLECTION DATA */
|
||||
|
||||
enum {
|
||||
REFLECTION_AMBIENT_DISABLED = 0,
|
||||
REFLECTION_AMBIENT_ENVIRONMENT = 1,
|
||||
REFLECTION_AMBIENT_COLOR = 2,
|
||||
};
|
||||
|
||||
struct ReflectionData {
|
||||
float box_extents[3];
|
||||
float index;
|
||||
float box_offset[3];
|
||||
uint32_t mask;
|
||||
float ambient[3]; // ambient color,
|
||||
float intensity;
|
||||
uint32_t exterior;
|
||||
uint32_t box_project;
|
||||
uint32_t ambient_mode;
|
||||
float exposure_normalization;
|
||||
float local_matrix[16]; // up to here for spot and omni, rest is for directional
|
||||
};
|
||||
|
||||
struct ReflectionProbeInstanceSort {
|
||||
float depth;
|
||||
ReflectionProbeInstance *probe_instance;
|
||||
bool operator<(const ReflectionProbeInstanceSort &p_sort) const {
|
||||
return depth < p_sort.depth;
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t max_reflections;
|
||||
uint32_t reflection_count = 0;
|
||||
// uint32_t max_reflection_probes_per_instance = 0; // seems unused
|
||||
ReflectionData *reflections = nullptr;
|
||||
ReflectionProbeInstanceSort *reflection_sort = nullptr;
|
||||
RID reflection_buffer;
|
||||
|
||||
/* LIGHTMAP */
|
||||
|
||||
struct Lightmap {
|
||||
@ -124,12 +351,101 @@ private:
|
||||
|
||||
mutable RID_Owner<Lightmap, true> lightmap_owner;
|
||||
|
||||
/* LIGHTMAP INSTANCE */
|
||||
|
||||
struct LightmapInstance {
|
||||
RID lightmap;
|
||||
Transform3D transform;
|
||||
};
|
||||
|
||||
mutable RID_Owner<LightmapInstance> lightmap_instance_owner;
|
||||
|
||||
/* SHADOW ATLAS */
|
||||
|
||||
uint64_t shadow_atlas_realloc_tolerance_msec = 500;
|
||||
|
||||
struct ShadowShrinkStage {
|
||||
RID texture;
|
||||
RID filter_texture;
|
||||
uint32_t size = 0;
|
||||
};
|
||||
|
||||
struct ShadowAtlas {
|
||||
struct Quadrant {
|
||||
uint32_t subdivision = 0;
|
||||
|
||||
struct Shadow {
|
||||
RID owner;
|
||||
uint64_t version = 0;
|
||||
uint64_t fog_version = 0; // used for fog
|
||||
uint64_t alloc_tick = 0;
|
||||
|
||||
Shadow() {}
|
||||
};
|
||||
|
||||
Vector<Shadow> shadows;
|
||||
|
||||
Quadrant() {}
|
||||
} quadrants[4];
|
||||
|
||||
int size_order[4] = { 0, 1, 2, 3 };
|
||||
uint32_t smallest_subdiv = 0;
|
||||
|
||||
int size = 0;
|
||||
bool use_16_bits = true;
|
||||
|
||||
RID depth;
|
||||
RID fb; //for copying
|
||||
|
||||
HashMap<RID, uint32_t> shadow_owners;
|
||||
};
|
||||
|
||||
RID_Owner<ShadowAtlas> shadow_atlas_owner;
|
||||
|
||||
void _update_shadow_atlas(ShadowAtlas *shadow_atlas);
|
||||
|
||||
void _shadow_atlas_invalidate_shadow(ShadowAtlas::Quadrant::Shadow *p_shadow, RID p_atlas, ShadowAtlas *p_shadow_atlas, uint32_t p_quadrant, uint32_t p_shadow_idx);
|
||||
bool _shadow_atlas_find_shadow(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
|
||||
bool _shadow_atlas_find_omni_shadows(ShadowAtlas *shadow_atlas, int *p_in_quadrants, int p_quadrant_count, int p_current_subdiv, uint64_t p_tick, int &r_quadrant, int &r_shadow);
|
||||
|
||||
/* DIRECTIONAL SHADOW */
|
||||
|
||||
struct DirectionalShadow {
|
||||
RID depth;
|
||||
RID fb; //when renderign direct
|
||||
|
||||
int light_count = 0;
|
||||
int size = 0;
|
||||
bool use_16_bits = true;
|
||||
int current_light = 0;
|
||||
} directional_shadow;
|
||||
|
||||
/* SHADOW CUBEMAPS */
|
||||
|
||||
struct ShadowCubemap {
|
||||
RID cubemap;
|
||||
RID side_fb[6];
|
||||
};
|
||||
|
||||
HashMap<int, ShadowCubemap> shadow_cubemaps;
|
||||
ShadowCubemap *_get_shadow_cubemap(int p_size);
|
||||
|
||||
public:
|
||||
static LightStorage *get_singleton();
|
||||
|
||||
LightStorage();
|
||||
virtual ~LightStorage();
|
||||
|
||||
bool free(RID p_rid);
|
||||
|
||||
/* Settings */
|
||||
void set_max_cluster_elements(const uint32_t p_max_cluster_elements) {
|
||||
max_cluster_elements = p_max_cluster_elements;
|
||||
set_max_reflection_probes(p_max_cluster_elements);
|
||||
set_max_lights(p_max_cluster_elements);
|
||||
}
|
||||
uint32_t get_max_cluster_elements() const { return max_cluster_elements; }
|
||||
|
||||
/* LIGHT */
|
||||
|
||||
bool owns_light(RID p_rid) { return light_owner.owns(p_rid); };
|
||||
@ -259,6 +575,205 @@ public:
|
||||
|
||||
Dependency *light_get_dependency(RID p_light) const;
|
||||
|
||||
/* LIGHT INSTANCE API */
|
||||
|
||||
bool owns_light_instance(RID p_rid) { return light_instance_owner.owns(p_rid); };
|
||||
|
||||
virtual RID light_instance_create(RID p_light) override;
|
||||
virtual void light_instance_free(RID p_light) override;
|
||||
virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) override;
|
||||
virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) override;
|
||||
virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) override;
|
||||
virtual void light_instance_mark_visible(RID p_light_instance) override;
|
||||
|
||||
_FORCE_INLINE_ RID light_instance_get_base_light(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->light;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Transform3D light_instance_get_base_transform(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->transform;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ AABB light_instance_get_base_aabb(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->aabb;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void light_instance_set_cull_mask(RID p_light_instance, uint32_t p_cull_mask) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
li->cull_mask = p_cull_mask;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t light_instance_get_cull_mask(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->cull_mask;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2 light_instance_get_shadow_atlas_rect(RID p_light_instance, RID p_shadow_atlas, Vector2i &r_omni_offset) {
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas);
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
uint32_t key = shadow_atlas->shadow_owners[li->self];
|
||||
|
||||
uint32_t quadrant = (key >> QUADRANT_SHIFT) & 0x3;
|
||||
uint32_t shadow = key & SHADOW_INDEX_MASK;
|
||||
|
||||
ERR_FAIL_COND_V(shadow >= (uint32_t)shadow_atlas->quadrants[quadrant].shadows.size(), Rect2());
|
||||
|
||||
uint32_t atlas_size = shadow_atlas->size;
|
||||
uint32_t quadrant_size = atlas_size >> 1;
|
||||
|
||||
uint32_t x = (quadrant & 1) * quadrant_size;
|
||||
uint32_t y = (quadrant >> 1) * quadrant_size;
|
||||
|
||||
uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision);
|
||||
x += (shadow % shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
|
||||
y += (shadow / shadow_atlas->quadrants[quadrant].subdivision) * shadow_size;
|
||||
|
||||
if (key & OMNI_LIGHT_FLAG) {
|
||||
if (((shadow + 1) % shadow_atlas->quadrants[quadrant].subdivision) == 0) {
|
||||
r_omni_offset.x = 1 - int(shadow_atlas->quadrants[quadrant].subdivision);
|
||||
r_omni_offset.y = 1;
|
||||
} else {
|
||||
r_omni_offset.x = 1;
|
||||
r_omni_offset.y = 0;
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t width = shadow_size;
|
||||
uint32_t height = shadow_size;
|
||||
|
||||
return Rect2(x / float(shadow_atlas->size), y / float(shadow_atlas->size), width / float(shadow_atlas->size), height / float(shadow_atlas->size));
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float light_instance_get_shadow_texel_size(RID p_light_instance, RID p_shadow_atlas) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
ERR_FAIL_COND_V(!li->shadow_atlases.has(p_shadow_atlas), 0);
|
||||
#endif
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.get_or_null(p_shadow_atlas);
|
||||
ERR_FAIL_COND_V(!shadow_atlas, 0);
|
||||
#ifdef DEBUG_ENABLED
|
||||
ERR_FAIL_COND_V(!shadow_atlas->shadow_owners.has(p_light_instance), 0);
|
||||
#endif
|
||||
uint32_t key = shadow_atlas->shadow_owners[p_light_instance];
|
||||
|
||||
uint32_t quadrant = (key >> QUADRANT_SHIFT) & 0x3;
|
||||
|
||||
uint32_t quadrant_size = shadow_atlas->size >> 1;
|
||||
|
||||
uint32_t shadow_size = (quadrant_size / shadow_atlas->quadrants[quadrant].subdivision);
|
||||
|
||||
return float(1.0) / shadow_size;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Projection light_instance_get_shadow_camera(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].camera;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Transform3D
|
||||
light_instance_get_shadow_transform(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].transform;
|
||||
}
|
||||
_FORCE_INLINE_ float light_instance_get_shadow_bias_scale(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].bias_scale;
|
||||
}
|
||||
_FORCE_INLINE_ float light_instance_get_shadow_range(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].farplane;
|
||||
}
|
||||
_FORCE_INLINE_ float light_instance_get_shadow_range_begin(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].range_begin;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Vector2 light_instance_get_shadow_uv_scale(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].uv_scale;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void light_instance_set_directional_shadow_atlas_rect(RID p_light_instance, int p_index, const Rect2 p_atlas_rect) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
li->shadow_transform[p_index].atlas_rect = p_atlas_rect;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2 light_instance_get_directional_shadow_atlas_rect(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].atlas_rect;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float light_instance_get_directional_shadow_split(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].split;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ float light_instance_get_directional_shadow_texel_size(RID p_light_instance, int p_index) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->shadow_transform[p_index].shadow_texel_size;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void light_instance_set_render_pass(RID p_light_instance, uint64_t p_pass) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
li->last_pass = p_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint64_t light_instance_get_render_pass(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->last_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void light_instance_set_shadow_pass(RID p_light_instance, uint64_t p_pass) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
li->last_scene_shadow_pass = p_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint64_t light_instance_get_shadow_pass(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->last_scene_shadow_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ ForwardID light_instance_get_forward_id(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->forward_id;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RS::LightType light_instance_get_type(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->light_type;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void light_instance_set_directional_rect(RID p_light_instance, const Rect2 &p_directional_rect) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
li->directional_rect = p_directional_rect;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Rect2 light_instance_get_directional_rect(RID p_light_instance) {
|
||||
LightInstance *li = light_instance_owner.get_or_null(p_light_instance);
|
||||
return li->directional_rect;
|
||||
}
|
||||
|
||||
/* LIGHT DATA */
|
||||
|
||||
void free_light_data();
|
||||
void set_max_lights(const uint32_t p_max_lights);
|
||||
RID get_omni_light_buffer() { return omni_light_buffer; }
|
||||
RID get_spot_light_buffer() { return spot_light_buffer; }
|
||||
RID get_directional_light_buffer() { return directional_light_buffer; }
|
||||
uint32_t get_max_directional_lights() { return max_directional_lights; }
|
||||
bool has_directional_shadows(const uint32_t p_directional_light_count) {
|
||||
for (uint32_t i = 0; i < p_directional_light_count; i++) {
|
||||
if (directional_lights[i].shadow_opacity > 0.001) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
void update_light_buffers(RenderDataRD *p_render_data, const PagedArray<RID> &p_lights, const Transform3D &p_camera_transform, RID p_shadow_atlas, bool p_using_shadows, uint32_t &r_directional_light_count, uint32_t &r_positional_light_count, bool &r_directional_light_soft_shadows);
|
||||
|
||||
/* REFLECTION PROBE */
|
||||
|
||||
bool owns_reflection_probe(RID p_rid) { return reflection_probe_owner.owns(p_rid); };
|
||||
@ -305,6 +820,94 @@ public:
|
||||
|
||||
Dependency *reflection_probe_get_dependency(RID p_probe) const;
|
||||
|
||||
/* REFLECTION ATLAS */
|
||||
|
||||
bool owns_reflection_atlas(RID p_rid) { return reflection_atlas_owner.owns(p_rid); }
|
||||
|
||||
virtual RID reflection_atlas_create() override;
|
||||
virtual void reflection_atlas_free(RID p_ref_atlas) override;
|
||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) override;
|
||||
virtual int reflection_atlas_get_size(RID p_ref_atlas) const override;
|
||||
|
||||
_FORCE_INLINE_ RID reflection_atlas_get_texture(RID p_ref_atlas) {
|
||||
ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_ref_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, RID());
|
||||
return atlas->reflection;
|
||||
}
|
||||
|
||||
/* REFLECTION PROBE INSTANCE */
|
||||
|
||||
bool owns_reflection_probe_instance(RID p_rid) { return reflection_probe_instance_owner.owns(p_rid); }
|
||||
|
||||
virtual RID reflection_probe_instance_create(RID p_probe) override;
|
||||
virtual void reflection_probe_instance_free(RID p_instance) override;
|
||||
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) override;
|
||||
virtual void reflection_probe_release_atlas_index(RID p_instance) override;
|
||||
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override;
|
||||
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override;
|
||||
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override;
|
||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override;
|
||||
|
||||
uint32_t reflection_probe_instance_get_resolution(RID p_instance);
|
||||
RID reflection_probe_instance_get_framebuffer(RID p_instance, int p_index);
|
||||
RID reflection_probe_instance_get_depth_framebuffer(RID p_instance, int p_index);
|
||||
|
||||
_FORCE_INLINE_ RID reflection_probe_instance_get_probe(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, RID());
|
||||
|
||||
return rpi->probe;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RendererRD::ForwardID reflection_probe_instance_get_forward_id(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, 0);
|
||||
|
||||
return rpi->forward_id;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void reflection_probe_instance_set_cull_mask(RID p_instance, uint32_t p_render_pass) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND(!rpi);
|
||||
rpi->cull_mask = p_render_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void reflection_probe_instance_set_render_pass(RID p_instance, uint32_t p_render_pass) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND(!rpi);
|
||||
rpi->last_pass = p_render_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t reflection_probe_instance_get_render_pass(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, 0);
|
||||
|
||||
return rpi->last_pass;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Transform3D reflection_probe_instance_get_transform(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, Transform3D());
|
||||
|
||||
return rpi->transform;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int reflection_probe_instance_get_atlas_index(RID p_instance) {
|
||||
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
|
||||
ERR_FAIL_COND_V(!rpi, -1);
|
||||
|
||||
return rpi->atlas_index;
|
||||
}
|
||||
|
||||
ClusterBuilderRD *reflection_probe_instance_get_cluster_builder(RID p_instance, ClusterBuilderSharedDataRD *p_cluster_builder_shared);
|
||||
|
||||
/* REFLECTION DATA */
|
||||
|
||||
void free_reflection_data();
|
||||
void set_max_reflection_probes(const uint32_t p_max_reflection_probes);
|
||||
RID get_reflection_probe_buffer() { return reflection_buffer; }
|
||||
void update_reflection_probe_buffer(RenderDataRD *p_render_data, const PagedArray<RID> &p_reflections, const Transform3D &p_camera_inverse_transform, RID p_environment);
|
||||
|
||||
/* LIGHTMAP */
|
||||
|
||||
bool owns_lightmap(RID p_rid) { return lightmap_owner.owns(p_rid); };
|
||||
@ -366,6 +969,111 @@ public:
|
||||
ERR_FAIL_COND_V(!using_lightmap_array, lightmap_textures); //only for arrays
|
||||
return lightmap_textures;
|
||||
}
|
||||
|
||||
/* LIGHTMAP INSTANCE */
|
||||
|
||||
bool owns_lightmap_instance(RID p_rid) { return lightmap_instance_owner.owns(p_rid); };
|
||||
|
||||
virtual RID lightmap_instance_create(RID p_lightmap) override;
|
||||
virtual void lightmap_instance_free(RID p_lightmap) override;
|
||||
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) override;
|
||||
_FORCE_INLINE_ bool lightmap_instance_is_valid(RID p_lightmap_instance) {
|
||||
return lightmap_instance_owner.get_or_null(p_lightmap_instance) != nullptr;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID lightmap_instance_get_lightmap(RID p_lightmap_instance) {
|
||||
LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap_instance);
|
||||
return li->lightmap;
|
||||
}
|
||||
_FORCE_INLINE_ Transform3D lightmap_instance_get_transform(RID p_lightmap_instance) {
|
||||
LightmapInstance *li = lightmap_instance_owner.get_or_null(p_lightmap_instance);
|
||||
return li->transform;
|
||||
}
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
bool owns_shadow_atlas(RID p_rid) { return shadow_atlas_owner.owns(p_rid); };
|
||||
|
||||
virtual RID shadow_atlas_create() override;
|
||||
virtual void shadow_atlas_free(RID p_atlas) override;
|
||||
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) override;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) override;
|
||||
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_instance, float p_coverage, uint64_t p_light_version) override;
|
||||
_FORCE_INLINE_ bool shadow_atlas_owns_light_instance(RID p_atlas, RID p_light_intance) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, false);
|
||||
return atlas->shadow_owners.has(p_light_intance);
|
||||
}
|
||||
_FORCE_INLINE_ uint32_t shadow_atlas_get_light_instance_key(RID p_atlas, RID p_light_intance) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, -1);
|
||||
return atlas->shadow_owners[p_light_intance];
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID shadow_atlas_get_texture(RID p_atlas) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, RID());
|
||||
return atlas->depth;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int shadow_atlas_get_size(RID p_atlas) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, 0);
|
||||
return atlas->size;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int shadow_atlas_get_quadrant_shadow_size(RID p_atlas, uint32_t p_quadrant) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, 0);
|
||||
ERR_FAIL_UNSIGNED_INDEX_V(p_quadrant, 4, 0);
|
||||
return atlas->quadrants[p_quadrant].shadows.size();
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ uint32_t shadow_atlas_get_quadrant_subdivision(RID p_atlas, uint32_t p_quadrant) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, 0);
|
||||
ERR_FAIL_UNSIGNED_INDEX_V(p_quadrant, 4, 0);
|
||||
return atlas->quadrants[p_quadrant].subdivision;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID shadow_atlas_get_fb(RID p_atlas) {
|
||||
ShadowAtlas *atlas = shadow_atlas_owner.get_or_null(p_atlas);
|
||||
ERR_FAIL_COND_V(!atlas, RID());
|
||||
return atlas->fb;
|
||||
}
|
||||
|
||||
virtual void shadow_atlas_update(RID p_atlas) override;
|
||||
|
||||
/* DIRECTIONAL SHADOW */
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) override;
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance) override;
|
||||
virtual void set_directional_shadow_count(int p_count) override;
|
||||
|
||||
Rect2i get_directional_shadow_rect();
|
||||
void update_directional_shadow_atlas();
|
||||
|
||||
_FORCE_INLINE_ RID directional_shadow_get_texture() {
|
||||
return directional_shadow.depth;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ int directional_shadow_get_size() {
|
||||
return directional_shadow.size;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RID direction_shadow_get_fb() {
|
||||
return directional_shadow.fb;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void directional_shadow_increase_current_light() {
|
||||
directional_shadow.current_light++;
|
||||
}
|
||||
|
||||
/* SHADOW CUBEMAPS */
|
||||
|
||||
RID get_cubemap(int p_size);
|
||||
RID get_cubemap_fb(int p_size, int p_pass);
|
||||
};
|
||||
|
||||
} // namespace RendererRD
|
||||
|
@ -1528,6 +1528,18 @@ MaterialStorage::~MaterialStorage() {
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
bool MaterialStorage::free(RID p_rid) {
|
||||
if (owns_shader(p_rid)) {
|
||||
shader_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_material(p_rid)) {
|
||||
material_free(p_rid);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Samplers */
|
||||
|
||||
void MaterialStorage::sampler_rd_configure_custom(float p_mipmap_bias) {
|
||||
|
@ -231,6 +231,8 @@ public:
|
||||
MaterialStorage();
|
||||
virtual ~MaterialStorage();
|
||||
|
||||
bool free(RID p_rid);
|
||||
|
||||
/* Helpers */
|
||||
|
||||
static _FORCE_INLINE_ void store_transform(const Transform3D &p_mtx, float *p_array) {
|
||||
|
@ -197,6 +197,24 @@ MeshStorage::~MeshStorage() {
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
bool MeshStorage::free(RID p_rid) {
|
||||
if (owns_mesh(p_rid)) {
|
||||
mesh_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_mesh_instance(p_rid)) {
|
||||
mesh_instance_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_multimesh(p_rid)) {
|
||||
multimesh_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_skeleton(p_rid)) {
|
||||
skeleton_free(p_rid);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* MESH API */
|
||||
|
||||
RID MeshStorage::mesh_allocate() {
|
||||
|
@ -308,6 +308,8 @@ public:
|
||||
MeshStorage();
|
||||
virtual ~MeshStorage();
|
||||
|
||||
bool free(RID p_rid);
|
||||
|
||||
RID get_default_rd_storage_buffer() const { return default_rd_storage_buffer; }
|
||||
|
||||
/* MESH API */
|
||||
|
@ -208,6 +208,21 @@ ParticlesStorage::~ParticlesStorage() {
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
bool ParticlesStorage::free(RID p_rid) {
|
||||
if (owns_particles(p_rid)) {
|
||||
particles_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_particles_collision(p_rid)) {
|
||||
particles_collision_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_particles_collision_instance(p_rid)) {
|
||||
particles_collision_instance_free(p_rid);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* PARTICLES */
|
||||
|
||||
RID ParticlesStorage::particles_allocate() {
|
||||
|
@ -405,6 +405,8 @@ public:
|
||||
ParticlesStorage();
|
||||
virtual ~ParticlesStorage();
|
||||
|
||||
bool free(RID p_rid);
|
||||
|
||||
/* PARTICLES */
|
||||
|
||||
bool owns_particles(RID p_rid) { return particles_owner.owns(p_rid); }
|
||||
|
@ -40,11 +40,6 @@ RenderSceneBuffersRD::~RenderSceneBuffersRD() {
|
||||
cleanup();
|
||||
|
||||
data_buffers.clear();
|
||||
|
||||
// need to investigate if we can remove these things.
|
||||
if (cluster_builder) {
|
||||
memdelete(cluster_builder);
|
||||
}
|
||||
}
|
||||
|
||||
void RenderSceneBuffersRD::_bind_methods() {
|
||||
@ -121,21 +116,6 @@ void RenderSceneBuffersRD::cleanup() {
|
||||
RD::get_singleton()->free(luminance.current);
|
||||
luminance.current = RID();
|
||||
}
|
||||
|
||||
if (ss_effects.linear_depth.is_valid()) {
|
||||
RD::get_singleton()->free(ss_effects.linear_depth);
|
||||
ss_effects.linear_depth = RID();
|
||||
ss_effects.linear_depth_slices.clear();
|
||||
}
|
||||
|
||||
if (ss_effects.downsample_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(ss_effects.downsample_uniform_set)) {
|
||||
RD::get_singleton()->free(ss_effects.downsample_uniform_set);
|
||||
ss_effects.downsample_uniform_set = RID();
|
||||
}
|
||||
|
||||
sse->ssao_free(ss_effects.ssao);
|
||||
sse->ssil_free(ss_effects.ssil);
|
||||
sse->ssr_free(ssr);
|
||||
}
|
||||
|
||||
void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) {
|
||||
@ -179,14 +159,6 @@ void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_interna
|
||||
use_debanding = p_use_debanding;
|
||||
view_count = p_view_count;
|
||||
|
||||
/* may move this into our clustered renderer data object */
|
||||
if (can_be_storage) {
|
||||
if (cluster_builder == nullptr) {
|
||||
cluster_builder = memnew(ClusterBuilderRD);
|
||||
}
|
||||
cluster_builder->set_shared(RendererSceneRenderRD::get_singleton()->get_cluster_builder_shared());
|
||||
}
|
||||
|
||||
// cleanout any old buffers we had.
|
||||
cleanup();
|
||||
|
||||
@ -233,11 +205,6 @@ void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_interna
|
||||
for (KeyValue<StringName, Ref<RenderBufferCustomDataRD>> &E : data_buffers) {
|
||||
E.value->configure(this);
|
||||
}
|
||||
|
||||
if (cluster_builder) {
|
||||
RID sampler = RendererRD::MaterialStorage::get_singleton()->sampler_rd_get_default(RS::CANVAS_ITEM_TEXTURE_FILTER_NEAREST, RS::CANVAS_ITEM_TEXTURE_REPEAT_DISABLED);
|
||||
cluster_builder->setup(internal_size, max_cluster_elements, get_depth_texture(), sampler, get_internal_texture());
|
||||
}
|
||||
}
|
||||
|
||||
void RenderSceneBuffersRD::set_fsr_sharpness(float p_fsr_sharpness) {
|
||||
|
@ -31,19 +31,14 @@
|
||||
#ifndef RENDER_SCENE_BUFFERS_RD_H
|
||||
#define RENDER_SCENE_BUFFERS_RD_H
|
||||
|
||||
#include "../effects/vrs.h"
|
||||
#include "../framebuffer_cache_rd.h"
|
||||
#include "core/templates/hash_map.h"
|
||||
#include "servers/rendering/renderer_rd/effects/vrs.h"
|
||||
#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/render_buffer_custom_data_rd.h"
|
||||
#include "render_buffer_custom_data_rd.h"
|
||||
#include "servers/rendering/rendering_device.h"
|
||||
#include "servers/rendering/rendering_method.h"
|
||||
#include "servers/rendering/storage/render_scene_buffers.h"
|
||||
|
||||
// These can be retired in due time
|
||||
#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
|
||||
#include "servers/rendering/renderer_rd/effects/ss_effects.h"
|
||||
#include "servers/rendering/renderer_rd/environment/fog.h"
|
||||
|
||||
#define RB_SCOPE_BUFFERS SNAME("render_buffers")
|
||||
#define RB_SCOPE_VRS SNAME("VRS")
|
||||
|
||||
@ -68,7 +63,6 @@ private:
|
||||
bool can_be_storage = true;
|
||||
uint32_t max_cluster_elements = 512;
|
||||
RD::DataFormat base_data_format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
|
||||
RendererRD::SSEffects *sse = nullptr;
|
||||
RendererRD::VRS *vrs = nullptr;
|
||||
uint64_t auto_exposure_version = 1;
|
||||
|
||||
@ -139,9 +133,9 @@ public:
|
||||
// info from our renderer
|
||||
void set_can_be_storage(const bool p_can_be_storage) { can_be_storage = p_can_be_storage; }
|
||||
void set_max_cluster_elements(const uint32_t p_max_elements) { max_cluster_elements = p_max_elements; }
|
||||
uint32_t get_max_cluster_elements() { return max_cluster_elements; }
|
||||
void set_base_data_format(const RD::DataFormat p_base_data_format) { base_data_format = p_base_data_format; }
|
||||
RD::DataFormat get_base_data_format() const { return base_data_format; }
|
||||
void set_sseffects(RendererRD::SSEffects *p_ss_effects) { sse = p_ss_effects; }
|
||||
void set_vrs(RendererRD::VRS *p_vrs) { vrs = p_vrs; }
|
||||
|
||||
void cleanup();
|
||||
@ -215,8 +209,6 @@ public:
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Everything after this needs to be re-evaluated, this is all old implementation
|
||||
|
||||
ClusterBuilderRD *cluster_builder = nullptr;
|
||||
|
||||
struct WeightBuffers {
|
||||
RID weight;
|
||||
RID fb; // FB with both texture and weight writing into one level lower
|
||||
@ -233,24 +225,6 @@ public:
|
||||
Vector<RID> fb;
|
||||
RID current_fb;
|
||||
} luminance;
|
||||
|
||||
struct SSEffects {
|
||||
RID linear_depth;
|
||||
Vector<RID> linear_depth_slices;
|
||||
|
||||
RID downsample_uniform_set;
|
||||
|
||||
Projection last_frame_projection;
|
||||
Transform3D last_frame_transform;
|
||||
|
||||
RendererRD::SSEffects::SSAORenderBuffers ssao;
|
||||
RendererRD::SSEffects::SSILRenderBuffers ssil;
|
||||
} ss_effects;
|
||||
|
||||
RendererRD::SSEffects::SSRRenderBuffers ssr;
|
||||
|
||||
RID get_ao_texture() const { return ss_effects.ssao.ao_final; }
|
||||
RID get_ssil_texture() const { return ss_effects.ssil.ssil_final; }
|
||||
};
|
||||
|
||||
#endif // RENDER_SCENE_BUFFERS_RD_H
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "texture_storage.h"
|
||||
#include "../effects/copy_effects.h"
|
||||
#include "material_storage.h"
|
||||
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
|
||||
|
||||
using namespace RendererRD;
|
||||
|
||||
@ -457,6 +458,8 @@ TextureStorage::TextureStorage() {
|
||||
TextureStorage::~TextureStorage() {
|
||||
rt_sdf.shader.version_free(rt_sdf.shader_version);
|
||||
|
||||
free_decal_data();
|
||||
|
||||
if (decal_atlas.textures.size()) {
|
||||
ERR_PRINT("Decal Atlas: " + itos(decal_atlas.textures.size()) + " textures were not removed from the atlas.");
|
||||
}
|
||||
@ -475,6 +478,27 @@ TextureStorage::~TextureStorage() {
|
||||
singleton = nullptr;
|
||||
}
|
||||
|
||||
bool TextureStorage::free(RID p_rid) {
|
||||
if (owns_texture(p_rid)) {
|
||||
texture_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_canvas_texture(p_rid)) {
|
||||
canvas_texture_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_decal(p_rid)) {
|
||||
decal_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_decal_instance(p_rid)) {
|
||||
decal_instance_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_render_target(p_rid)) {
|
||||
render_target_free(p_rid);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool TextureStorage::can_create_resources_async() const {
|
||||
return true;
|
||||
}
|
||||
@ -1888,7 +1912,7 @@ Dependency *TextureStorage::decal_get_dependency(RID p_decal) {
|
||||
}
|
||||
|
||||
void TextureStorage::update_decal_atlas() {
|
||||
RendererRD::CopyEffects *copy_effects = RendererRD::CopyEffects::get_singleton();
|
||||
CopyEffects *copy_effects = CopyEffects::get_singleton();
|
||||
ERR_FAIL_NULL(copy_effects);
|
||||
|
||||
if (!decal_atlas.dirty) {
|
||||
@ -2112,6 +2136,227 @@ void TextureStorage::texture_remove_from_decal_atlas(RID p_texture, bool p_panor
|
||||
}
|
||||
}
|
||||
|
||||
/* DECAL INSTANCE API */
|
||||
|
||||
RID TextureStorage::decal_instance_create(RID p_decal) {
|
||||
DecalInstance di;
|
||||
di.decal = p_decal;
|
||||
di.forward_id = ForwardIDStorage::get_singleton()->allocate_forward_id(FORWARD_ID_TYPE_DECAL);
|
||||
return decal_instance_owner.make_rid(di);
|
||||
}
|
||||
|
||||
void TextureStorage::decal_instance_free(RID p_decal_instance) {
|
||||
DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
|
||||
ForwardIDStorage::get_singleton()->free_forward_id(FORWARD_ID_TYPE_DECAL, di->forward_id);
|
||||
decal_instance_owner.free(p_decal_instance);
|
||||
}
|
||||
|
||||
void TextureStorage::decal_instance_set_transform(RID p_decal_instance, const Transform3D &p_transform) {
|
||||
DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
|
||||
ERR_FAIL_COND(!di);
|
||||
di->transform = p_transform;
|
||||
}
|
||||
|
||||
/* DECAL DATA API */
|
||||
|
||||
void TextureStorage::free_decal_data() {
|
||||
if (decal_buffer.is_valid()) {
|
||||
RD::get_singleton()->free(decal_buffer);
|
||||
decal_buffer = RID();
|
||||
}
|
||||
|
||||
if (decals != nullptr) {
|
||||
memdelete_arr(decals);
|
||||
decals = nullptr;
|
||||
}
|
||||
|
||||
if (decal_sort != nullptr) {
|
||||
memdelete_arr(decal_sort);
|
||||
decal_sort = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void TextureStorage::set_max_decals(const uint32_t p_max_decals) {
|
||||
max_decals = p_max_decals;
|
||||
uint32_t decal_buffer_size = max_decals * sizeof(DecalData);
|
||||
decals = memnew_arr(DecalData, max_decals);
|
||||
decal_sort = memnew_arr(DecalInstanceSort, max_decals);
|
||||
decal_buffer = RD::get_singleton()->storage_buffer_create(decal_buffer_size);
|
||||
}
|
||||
|
||||
void TextureStorage::update_decal_buffer(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform) {
|
||||
ForwardIDStorage *forward_id_storage = ForwardIDStorage::get_singleton();
|
||||
|
||||
Transform3D uv_xform;
|
||||
uv_xform.basis.scale(Vector3(2.0, 1.0, 2.0));
|
||||
uv_xform.origin = Vector3(-1.0, 0.0, -1.0);
|
||||
|
||||
uint32_t decals_size = p_decals.size();
|
||||
|
||||
decal_count = 0;
|
||||
|
||||
for (uint32_t i = 0; i < decals_size; i++) {
|
||||
if (decal_count == max_decals) {
|
||||
break;
|
||||
}
|
||||
|
||||
DecalInstance *decal_instance = decal_instance_owner.get_or_null(p_decals[i]);
|
||||
if (!decal_instance) {
|
||||
continue;
|
||||
}
|
||||
Decal *decal = decal_owner.get_or_null(decal_instance->decal);
|
||||
|
||||
Transform3D xform = decal_instance->transform;
|
||||
|
||||
real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
|
||||
|
||||
if (decal->distance_fade) {
|
||||
float fade_begin = decal->distance_fade_begin;
|
||||
float fade_length = decal->distance_fade_length;
|
||||
|
||||
if (distance > fade_begin) {
|
||||
if (distance > fade_begin + fade_length) {
|
||||
continue; // do not use this decal, its invisible
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decal_sort[decal_count].decal_instance = decal_instance;
|
||||
decal_sort[decal_count].decal = decal;
|
||||
decal_sort[decal_count].depth = distance;
|
||||
decal_count++;
|
||||
}
|
||||
|
||||
if (decal_count > 0) {
|
||||
SortArray<DecalInstanceSort> sort_array;
|
||||
sort_array.sort(decal_sort, decal_count);
|
||||
}
|
||||
|
||||
bool using_forward_ids = forward_id_storage->uses_forward_ids();
|
||||
for (uint32_t i = 0; i < decal_count; i++) {
|
||||
DecalInstance *decal_instance = decal_sort[i].decal_instance;
|
||||
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);
|
||||
}
|
||||
|
||||
decal_instance->cull_mask = decal->cull_mask;
|
||||
|
||||
Transform3D xform = decal_instance->transform;
|
||||
float fade = 1.0;
|
||||
|
||||
if (decal->distance_fade) {
|
||||
const real_t distance = -p_camera_inverse_xform.xform(xform.origin).z;
|
||||
const float fade_begin = decal->distance_fade_begin;
|
||||
const float fade_length = decal->distance_fade_length;
|
||||
|
||||
if (distance > fade_begin) {
|
||||
// Use `smoothstep()` to make opacity changes more gradual and less noticeable to the player.
|
||||
fade = Math::smoothstep(0.0f, 1.0f, 1.0f - float(distance - fade_begin) / fade_length);
|
||||
}
|
||||
}
|
||||
|
||||
DecalData &dd = decals[i];
|
||||
|
||||
Vector3 decal_extents = decal->extents;
|
||||
|
||||
Transform3D scale_xform;
|
||||
scale_xform.basis.scale(decal_extents);
|
||||
Transform3D to_decal_xform = (p_camera_inverse_xform * xform * scale_xform * uv_xform).affine_inverse();
|
||||
MaterialStorage::store_transform(to_decal_xform, dd.xform);
|
||||
|
||||
Vector3 normal = xform.basis.get_column(Vector3::AXIS_Y).normalized();
|
||||
normal = p_camera_inverse_xform.basis.xform(normal); //camera is normalized, so fine
|
||||
|
||||
dd.normal[0] = normal.x;
|
||||
dd.normal[1] = normal.y;
|
||||
dd.normal[2] = normal.z;
|
||||
dd.normal_fade = decal->normal_fade;
|
||||
|
||||
RID albedo_tex = decal->textures[RS::DECAL_TEXTURE_ALBEDO];
|
||||
RID emission_tex = decal->textures[RS::DECAL_TEXTURE_EMISSION];
|
||||
if (albedo_tex.is_valid()) {
|
||||
Rect2 rect = decal_atlas_get_texture_rect(albedo_tex);
|
||||
dd.albedo_rect[0] = rect.position.x;
|
||||
dd.albedo_rect[1] = rect.position.y;
|
||||
dd.albedo_rect[2] = rect.size.x;
|
||||
dd.albedo_rect[3] = rect.size.y;
|
||||
} else {
|
||||
if (!emission_tex.is_valid()) {
|
||||
continue; //no albedo, no emission, no decal.
|
||||
}
|
||||
dd.albedo_rect[0] = 0;
|
||||
dd.albedo_rect[1] = 0;
|
||||
dd.albedo_rect[2] = 0;
|
||||
dd.albedo_rect[3] = 0;
|
||||
}
|
||||
|
||||
RID normal_tex = decal->textures[RS::DECAL_TEXTURE_NORMAL];
|
||||
|
||||
if (normal_tex.is_valid()) {
|
||||
Rect2 rect = decal_atlas_get_texture_rect(normal_tex);
|
||||
dd.normal_rect[0] = rect.position.x;
|
||||
dd.normal_rect[1] = rect.position.y;
|
||||
dd.normal_rect[2] = rect.size.x;
|
||||
dd.normal_rect[3] = rect.size.y;
|
||||
|
||||
Basis normal_xform = p_camera_inverse_xform.basis * xform.basis.orthonormalized();
|
||||
MaterialStorage::store_basis_3x4(normal_xform, dd.normal_xform);
|
||||
} else {
|
||||
dd.normal_rect[0] = 0;
|
||||
dd.normal_rect[1] = 0;
|
||||
dd.normal_rect[2] = 0;
|
||||
dd.normal_rect[3] = 0;
|
||||
}
|
||||
|
||||
RID orm_tex = decal->textures[RS::DECAL_TEXTURE_ORM];
|
||||
if (orm_tex.is_valid()) {
|
||||
Rect2 rect = decal_atlas_get_texture_rect(orm_tex);
|
||||
dd.orm_rect[0] = rect.position.x;
|
||||
dd.orm_rect[1] = rect.position.y;
|
||||
dd.orm_rect[2] = rect.size.x;
|
||||
dd.orm_rect[3] = rect.size.y;
|
||||
} else {
|
||||
dd.orm_rect[0] = 0;
|
||||
dd.orm_rect[1] = 0;
|
||||
dd.orm_rect[2] = 0;
|
||||
dd.orm_rect[3] = 0;
|
||||
}
|
||||
|
||||
if (emission_tex.is_valid()) {
|
||||
Rect2 rect = decal_atlas_get_texture_rect(emission_tex);
|
||||
dd.emission_rect[0] = rect.position.x;
|
||||
dd.emission_rect[1] = rect.position.y;
|
||||
dd.emission_rect[2] = rect.size.x;
|
||||
dd.emission_rect[3] = rect.size.y;
|
||||
} else {
|
||||
dd.emission_rect[0] = 0;
|
||||
dd.emission_rect[1] = 0;
|
||||
dd.emission_rect[2] = 0;
|
||||
dd.emission_rect[3] = 0;
|
||||
}
|
||||
|
||||
Color modulate = decal->modulate;
|
||||
dd.modulate[0] = modulate.r;
|
||||
dd.modulate[1] = modulate.g;
|
||||
dd.modulate[2] = modulate.b;
|
||||
dd.modulate[3] = modulate.a * fade;
|
||||
dd.emission_energy = decal->emission_energy * fade;
|
||||
dd.albedo_mix = decal->albedo_mix;
|
||||
dd.mask = decal->cull_mask;
|
||||
dd.upper_fade = decal->upper_fade;
|
||||
dd.lower_fade = decal->lower_fade;
|
||||
|
||||
// hook for subclass to do further processing.
|
||||
RendererSceneRenderRD::get_singleton()->setup_added_decal(xform, decal_extents);
|
||||
}
|
||||
|
||||
if (decal_count > 0) {
|
||||
RD::get_singleton()->buffer_update(decal_buffer, 0, sizeof(DecalData) * decal_count, decals, RD::BARRIER_MASK_RASTER | RD::BARRIER_MASK_COMPUTE);
|
||||
}
|
||||
}
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
void TextureStorage::_clear_render_target(RenderTarget *rt) {
|
||||
|
@ -31,8 +31,12 @@
|
||||
#ifndef TEXTURE_STORAGE_RD_H
|
||||
#define TEXTURE_STORAGE_RD_H
|
||||
|
||||
#include "core/templates/local_vector.h"
|
||||
#include "core/templates/paged_array.h"
|
||||
#include "core/templates/rid_owner.h"
|
||||
#include "servers/rendering/renderer_rd/shaders/canvas_sdf.glsl.gen.h"
|
||||
#include "servers/rendering/renderer_rd/storage_rd/forward_id_storage.h"
|
||||
#include "servers/rendering/rendering_server_default.h"
|
||||
#include "servers/rendering/storage/texture_storage.h"
|
||||
#include "servers/rendering/storage/utilities.h"
|
||||
|
||||
@ -245,7 +249,52 @@ private:
|
||||
};
|
||||
|
||||
mutable RID_Owner<Decal, true> decal_owner;
|
||||
Decal *get_decal(RID p_rid) const { return decal_owner.get_or_null(p_rid); };
|
||||
|
||||
/* DECAL INSTANCE */
|
||||
|
||||
struct DecalInstance {
|
||||
RID decal;
|
||||
Transform3D transform;
|
||||
uint32_t cull_mask = 0;
|
||||
RendererRD::ForwardID forward_id = -1;
|
||||
};
|
||||
|
||||
mutable RID_Owner<DecalInstance> decal_instance_owner;
|
||||
|
||||
/* DECAL DATA (UBO) */
|
||||
|
||||
struct DecalData {
|
||||
float xform[16];
|
||||
float inv_extents[3];
|
||||
float albedo_mix;
|
||||
float albedo_rect[4];
|
||||
float normal_rect[4];
|
||||
float orm_rect[4];
|
||||
float emission_rect[4];
|
||||
float modulate[4];
|
||||
float emission_energy;
|
||||
uint32_t mask;
|
||||
float upper_fade;
|
||||
float lower_fade;
|
||||
float normal_xform[12];
|
||||
float normal[3];
|
||||
float normal_fade;
|
||||
};
|
||||
|
||||
struct DecalInstanceSort {
|
||||
float depth;
|
||||
DecalInstance *decal_instance;
|
||||
Decal *decal;
|
||||
bool operator<(const DecalInstanceSort &p_sort) const {
|
||||
return depth < p_sort.depth;
|
||||
}
|
||||
};
|
||||
|
||||
uint32_t max_decals = 0;
|
||||
uint32_t decal_count = 0;
|
||||
DecalData *decals = nullptr;
|
||||
DecalInstanceSort *decal_sort = nullptr;
|
||||
RID decal_buffer;
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
@ -343,6 +392,8 @@ public:
|
||||
TextureStorage();
|
||||
virtual ~TextureStorage();
|
||||
|
||||
bool free(RID p_rid);
|
||||
|
||||
/* Canvas Texture API */
|
||||
|
||||
bool owns_canvas_texture(RID p_rid) { return canvas_texture_owner.owns(p_rid); };
|
||||
@ -545,6 +596,46 @@ public:
|
||||
virtual AABB decal_get_aabb(RID p_decal) const override;
|
||||
Dependency *decal_get_dependency(RID p_decal);
|
||||
|
||||
/* DECAL INSTANCE API */
|
||||
|
||||
bool owns_decal_instance(RID p_rid) const { return decal_instance_owner.owns(p_rid); }
|
||||
|
||||
virtual RID decal_instance_create(RID p_decal) override;
|
||||
virtual void decal_instance_free(RID p_decal_instance) override;
|
||||
virtual void decal_instance_set_transform(RID p_decal_instance, const Transform3D &p_transform) override;
|
||||
|
||||
_FORCE_INLINE_ RID decal_instance_get_base(RID p_decal_instance) const {
|
||||
DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
|
||||
return di->decal;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ RendererRD::ForwardID decal_instance_get_forward_id(RID p_decal_instance) const {
|
||||
DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
|
||||
return di->forward_id;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ Transform3D decal_instance_get_transform(RID p_decal_instance) const {
|
||||
DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
|
||||
return di->transform;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ ForwardID decal_instance_get_forward_id(RID p_decal_instance) {
|
||||
DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
|
||||
return di->forward_id;
|
||||
}
|
||||
|
||||
_FORCE_INLINE_ void decal_instance_set_cullmask(RID p_decal_instance, uint32_t p_cull_mask) const {
|
||||
DecalInstance *di = decal_instance_owner.get_or_null(p_decal_instance);
|
||||
di->cull_mask = p_cull_mask;
|
||||
}
|
||||
|
||||
/* DECAL DATA API */
|
||||
|
||||
void free_decal_data();
|
||||
void set_max_decals(const uint32_t p_max_decals);
|
||||
RID get_decal_buffer() { return decal_buffer; }
|
||||
void update_decal_buffer(const PagedArray<RID> &p_decals, const Transform3D &p_camera_inverse_xform);
|
||||
|
||||
/* RENDER TARGET API */
|
||||
|
||||
bool owns_render_target(RID p_rid) const { return render_target_owner.owns(p_rid); };
|
||||
|
@ -89,49 +89,28 @@ RS::InstanceType Utilities::get_base_type(RID p_rid) const {
|
||||
}
|
||||
|
||||
bool Utilities::free(RID p_rid) {
|
||||
if (RendererRD::TextureStorage::get_singleton()->owns_texture(p_rid)) {
|
||||
RendererRD::TextureStorage::get_singleton()->texture_free(p_rid);
|
||||
} else if (RendererRD::TextureStorage::get_singleton()->owns_canvas_texture(p_rid)) {
|
||||
RendererRD::TextureStorage::get_singleton()->canvas_texture_free(p_rid);
|
||||
} else if (RendererRD::MaterialStorage::get_singleton()->owns_shader(p_rid)) {
|
||||
RendererRD::MaterialStorage::get_singleton()->shader_free(p_rid);
|
||||
} else if (RendererRD::MaterialStorage::get_singleton()->owns_material(p_rid)) {
|
||||
RendererRD::MaterialStorage::get_singleton()->material_free(p_rid);
|
||||
} else if (RendererRD::MeshStorage::get_singleton()->owns_mesh(p_rid)) {
|
||||
RendererRD::MeshStorage::get_singleton()->mesh_free(p_rid);
|
||||
} else if (RendererRD::MeshStorage::get_singleton()->owns_mesh_instance(p_rid)) {
|
||||
RendererRD::MeshStorage::get_singleton()->mesh_instance_free(p_rid);
|
||||
} else if (RendererRD::MeshStorage::get_singleton()->owns_multimesh(p_rid)) {
|
||||
RendererRD::MeshStorage::get_singleton()->multimesh_free(p_rid);
|
||||
} else if (RendererRD::MeshStorage::get_singleton()->owns_skeleton(p_rid)) {
|
||||
RendererRD::MeshStorage::get_singleton()->skeleton_free(p_rid);
|
||||
} else if (RendererRD::LightStorage::get_singleton()->owns_reflection_probe(p_rid)) {
|
||||
RendererRD::LightStorage::get_singleton()->reflection_probe_free(p_rid);
|
||||
} else if (RendererRD::TextureStorage::get_singleton()->owns_decal(p_rid)) {
|
||||
RendererRD::TextureStorage::get_singleton()->decal_free(p_rid);
|
||||
if (RendererRD::LightStorage::get_singleton()->free(p_rid)) {
|
||||
return true;
|
||||
} else if (RendererRD::MaterialStorage::get_singleton()->free(p_rid)) {
|
||||
return true;
|
||||
} else if (RendererRD::MeshStorage::get_singleton()->free(p_rid)) {
|
||||
return true;
|
||||
} else if (RendererRD::ParticlesStorage::get_singleton()->free(p_rid)) {
|
||||
return true;
|
||||
} else if (RendererRD::TextureStorage::get_singleton()->free(p_rid)) {
|
||||
return true;
|
||||
} else if (RendererRD::GI::get_singleton()->owns_voxel_gi(p_rid)) {
|
||||
RendererRD::GI::get_singleton()->voxel_gi_free(p_rid);
|
||||
} else if (RendererRD::LightStorage::get_singleton()->owns_lightmap(p_rid)) {
|
||||
RendererRD::LightStorage::get_singleton()->lightmap_free(p_rid);
|
||||
} else if (RendererRD::LightStorage::get_singleton()->owns_light(p_rid)) {
|
||||
RendererRD::LightStorage::get_singleton()->light_free(p_rid);
|
||||
} else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles(p_rid)) {
|
||||
RendererRD::ParticlesStorage::get_singleton()->particles_free(p_rid);
|
||||
} else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision(p_rid)) {
|
||||
RendererRD::ParticlesStorage::get_singleton()->particles_collision_free(p_rid);
|
||||
return true;
|
||||
} else if (RendererRD::Fog::get_singleton()->owns_fog_volume(p_rid)) {
|
||||
RendererRD::Fog::get_singleton()->fog_volume_free(p_rid);
|
||||
return true;
|
||||
} else if (owns_visibility_notifier(p_rid)) {
|
||||
visibility_notifier_free(p_rid);
|
||||
} else if (RendererRD::ParticlesStorage::get_singleton()->owns_particles_collision_instance(p_rid)) {
|
||||
RendererRD::ParticlesStorage::get_singleton()->particles_collision_instance_free(p_rid);
|
||||
} else if (RendererRD::Fog::get_singleton()->owns_fog_volume(p_rid)) {
|
||||
RendererRD::Fog::get_singleton()->fog_free(p_rid);
|
||||
} else if (RendererRD::TextureStorage::get_singleton()->owns_render_target(p_rid)) {
|
||||
RendererRD::TextureStorage::get_singleton()->render_target_free(p_rid);
|
||||
} else {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* DEPENDENCIES */
|
||||
@ -170,8 +149,8 @@ void Utilities::base_update_dependency(RID p_base, DependencyTracker *p_instance
|
||||
Dependency *dependency = ParticlesStorage::get_singleton()->particles_collision_get_dependency(p_base);
|
||||
p_instance->update_dependency(dependency);
|
||||
} else if (Fog::get_singleton()->owns_fog_volume(p_base)) {
|
||||
Fog::FogVolume *fv = Fog::get_singleton()->get_fog_volume(p_base);
|
||||
p_instance->update_dependency(&fv->dependency);
|
||||
Dependency *dependency = Fog::get_singleton()->fog_volume_get_dependency(p_base);
|
||||
p_instance->update_dependency(dependency);
|
||||
} else if (owns_visibility_notifier(p_base)) {
|
||||
VisibilityNotifier *vn = get_visibility_notifier(p_base);
|
||||
p_instance->update_dependency(&vn->dependency);
|
||||
|
@ -357,13 +357,14 @@ void RendererSceneCull::scenario_initialize(RID p_rid) {
|
||||
Scenario *scenario = scenario_owner.get_or_null(p_rid);
|
||||
scenario->self = p_rid;
|
||||
|
||||
scenario->reflection_probe_shadow_atlas = scene_render->shadow_atlas_create();
|
||||
scene_render->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest
|
||||
scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 0, 4);
|
||||
scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 1, 4);
|
||||
scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 2, 4);
|
||||
scene_render->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 3, 8);
|
||||
scenario->reflection_atlas = scene_render->reflection_atlas_create();
|
||||
scenario->reflection_probe_shadow_atlas = RSG::light_storage->shadow_atlas_create();
|
||||
RSG::light_storage->shadow_atlas_set_size(scenario->reflection_probe_shadow_atlas, 1024); //make enough shadows for close distance, don't bother with rest
|
||||
RSG::light_storage->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 0, 4);
|
||||
RSG::light_storage->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 1, 4);
|
||||
RSG::light_storage->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 2, 4);
|
||||
RSG::light_storage->shadow_atlas_set_quadrant_subdivision(scenario->reflection_probe_shadow_atlas, 3, 8);
|
||||
|
||||
scenario->reflection_atlas = RSG::light_storage->reflection_atlas_create();
|
||||
|
||||
scenario->instance_aabbs.set_page_pool(&instance_aabb_page_pool);
|
||||
scenario->instance_data.set_page_pool(&instance_data_page_pool);
|
||||
@ -393,7 +394,7 @@ void RendererSceneCull::scenario_set_fallback_environment(RID p_scenario, RID p_
|
||||
void RendererSceneCull::scenario_set_reflection_atlas_size(RID p_scenario, int p_reflection_size, int p_reflection_count) {
|
||||
Scenario *scenario = scenario_owner.get_or_null(p_scenario);
|
||||
ERR_FAIL_COND(!scenario);
|
||||
scene_render->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count);
|
||||
RSG::light_storage->reflection_atlas_set_size(scenario->reflection_atlas, p_reflection_size, p_reflection_count);
|
||||
}
|
||||
|
||||
bool RendererSceneCull::is_scenario(RID p_scenario) const {
|
||||
@ -534,7 +535,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
||||
scenario->directional_lights.erase(light->D);
|
||||
light->D = nullptr;
|
||||
}
|
||||
scene_render->free(light->instance);
|
||||
RSG::light_storage->light_instance_free(light->instance);
|
||||
} break;
|
||||
case RS::INSTANCE_PARTICLES_COLLISION: {
|
||||
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
|
||||
@ -549,14 +550,14 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
||||
} break;
|
||||
case RS::INSTANCE_REFLECTION_PROBE: {
|
||||
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
|
||||
scene_render->free(reflection_probe->instance);
|
||||
RSG::light_storage->reflection_probe_instance_free(reflection_probe->instance);
|
||||
if (reflection_probe->update_list.in_list()) {
|
||||
reflection_probe_render_list.remove(&reflection_probe->update_list);
|
||||
}
|
||||
} break;
|
||||
case RS::INSTANCE_DECAL: {
|
||||
InstanceDecalData *decal = static_cast<InstanceDecalData *>(instance->base_data);
|
||||
scene_render->free(decal->instance);
|
||||
RSG::texture_storage->decal_instance_free(decal->instance);
|
||||
|
||||
} break;
|
||||
case RS::INSTANCE_LIGHTMAP: {
|
||||
@ -565,7 +566,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
||||
while (lightmap_data->users.begin()) {
|
||||
instance_geometry_set_lightmap((*lightmap_data->users.begin())->self, RID(), Rect2(), 0);
|
||||
}
|
||||
scene_render->free(lightmap_data->instance);
|
||||
RSG::light_storage->lightmap_instance_free(lightmap_data->instance);
|
||||
} break;
|
||||
case RS::INSTANCE_VOXEL_GI: {
|
||||
InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(instance->base_data);
|
||||
@ -626,7 +627,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
||||
light->D = scenario->directional_lights.push_back(instance);
|
||||
}
|
||||
|
||||
light->instance = scene_render->light_instance_create(p_base);
|
||||
light->instance = RSG::light_storage->light_instance_create(p_base);
|
||||
|
||||
instance->base_data = light;
|
||||
} break;
|
||||
@ -684,19 +685,19 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
|
||||
reflection_probe->owner = instance;
|
||||
instance->base_data = reflection_probe;
|
||||
|
||||
reflection_probe->instance = scene_render->reflection_probe_instance_create(p_base);
|
||||
reflection_probe->instance = RSG::light_storage->reflection_probe_instance_create(p_base);
|
||||
} break;
|
||||
case RS::INSTANCE_DECAL: {
|
||||
InstanceDecalData *decal = memnew(InstanceDecalData);
|
||||
decal->owner = instance;
|
||||
instance->base_data = decal;
|
||||
|
||||
decal->instance = scene_render->decal_instance_create(p_base);
|
||||
decal->instance = RSG::texture_storage->decal_instance_create(p_base);
|
||||
} break;
|
||||
case RS::INSTANCE_LIGHTMAP: {
|
||||
InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData);
|
||||
instance->base_data = lightmap_data;
|
||||
lightmap_data->instance = scene_render->lightmap_instance_create(p_base);
|
||||
lightmap_data->instance = RSG::light_storage->lightmap_instance_create(p_base);
|
||||
} break;
|
||||
case RS::INSTANCE_VOXEL_GI: {
|
||||
InstanceVoxelGIData *voxel_gi = memnew(InstanceVoxelGIData);
|
||||
@ -758,7 +759,7 @@ void RendererSceneCull::instance_set_scenario(RID p_instance, RID p_scenario) {
|
||||
} break;
|
||||
case RS::INSTANCE_REFLECTION_PROBE: {
|
||||
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
|
||||
scene_render->reflection_probe_release_atlas_index(reflection_probe->instance);
|
||||
RSG::light_storage->reflection_probe_release_atlas_index(reflection_probe->instance);
|
||||
|
||||
} break;
|
||||
case RS::INSTANCE_PARTICLES_COLLISION: {
|
||||
@ -1502,8 +1503,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
|
||||
if (p_instance->base_type == RS::INSTANCE_LIGHT) {
|
||||
InstanceLightData *light = static_cast<InstanceLightData *>(p_instance->base_data);
|
||||
|
||||
scene_render->light_instance_set_transform(light->instance, p_instance->transform);
|
||||
scene_render->light_instance_set_aabb(light->instance, p_instance->transform.xform(p_instance->aabb));
|
||||
RSG::light_storage->light_instance_set_transform(light->instance, p_instance->transform);
|
||||
RSG::light_storage->light_instance_set_aabb(light->instance, p_instance->transform.xform(p_instance->aabb));
|
||||
light->shadow_dirty = true;
|
||||
|
||||
RS::LightBakeMode bake_mode = RSG::light_storage->light_get_bake_mode(p_instance->base);
|
||||
@ -1526,7 +1527,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
|
||||
} else if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
|
||||
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(p_instance->base_data);
|
||||
|
||||
scene_render->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform);
|
||||
RSG::light_storage->reflection_probe_instance_set_transform(reflection_probe->instance, p_instance->transform);
|
||||
|
||||
if (p_instance->scenario && p_instance->array_index >= 0) {
|
||||
InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
|
||||
@ -1535,11 +1536,11 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
|
||||
} else if (p_instance->base_type == RS::INSTANCE_DECAL) {
|
||||
InstanceDecalData *decal = static_cast<InstanceDecalData *>(p_instance->base_data);
|
||||
|
||||
scene_render->decal_instance_set_transform(decal->instance, p_instance->transform);
|
||||
RSG::texture_storage->decal_instance_set_transform(decal->instance, p_instance->transform);
|
||||
} else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
|
||||
InstanceLightmapData *lightmap = static_cast<InstanceLightmapData *>(p_instance->base_data);
|
||||
|
||||
scene_render->lightmap_instance_set_transform(lightmap->instance, p_instance->transform);
|
||||
RSG::light_storage->lightmap_instance_set_transform(lightmap->instance, p_instance->transform);
|
||||
} else if (p_instance->base_type == RS::INSTANCE_VOXEL_GI) {
|
||||
InstanceVoxelGIData *voxel_gi = static_cast<InstanceVoxelGIData *>(p_instance->base_data);
|
||||
|
||||
@ -2050,7 +2051,7 @@ void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_in
|
||||
|
||||
distances[splits] = max_distance;
|
||||
|
||||
real_t texture_size = scene_render->get_directional_light_shadow_size(light->instance);
|
||||
real_t texture_size = RSG::light_storage->get_directional_light_shadow_size(light->instance);
|
||||
|
||||
bool overlap = RSG::light_storage->light_directional_get_blend_splits(p_instance->base);
|
||||
|
||||
@ -2241,7 +2242,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||
case RS::LIGHT_OMNI: {
|
||||
RS::LightOmniShadowMode shadow_mode = RSG::light_storage->light_omni_get_shadow_mode(p_instance->base);
|
||||
|
||||
if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !scene_render->light_instances_can_render_shadow_cube()) {
|
||||
if (shadow_mode == RS::LIGHT_OMNI_SHADOW_DUAL_PARABOLOID || !RSG::light_storage->light_instances_can_render_shadow_cube()) {
|
||||
if (max_shadows_used + 2 > MAX_UPDATE_SHADOWS) {
|
||||
return true;
|
||||
}
|
||||
@ -2300,7 +2301,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||
|
||||
RSG::mesh_storage->update_mesh_instances();
|
||||
|
||||
scene_render->light_instance_set_shadow_transform(light->instance, Projection(), light_transform, radius, 0, i, 0);
|
||||
RSG::light_storage->light_instance_set_shadow_transform(light->instance, Projection(), light_transform, radius, 0, i, 0);
|
||||
shadow_data.light = light->instance;
|
||||
shadow_data.pass = i;
|
||||
}
|
||||
@ -2376,14 +2377,14 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||
}
|
||||
|
||||
RSG::mesh_storage->update_mesh_instances();
|
||||
scene_render->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0);
|
||||
RSG::light_storage->light_instance_set_shadow_transform(light->instance, cm, xform, radius, 0, i, 0);
|
||||
|
||||
shadow_data.light = light->instance;
|
||||
shadow_data.pass = i;
|
||||
}
|
||||
|
||||
//restore the regular DP matrix
|
||||
//scene_render->light_instance_set_shadow_transform(light->instance, Projection(), light_transform, radius, 0, 0, 0);
|
||||
//RSG::light_storage->light_instance_set_shadow_transform(light->instance, Projection(), light_transform, radius, 0, 0, 0);
|
||||
}
|
||||
|
||||
} break;
|
||||
@ -2440,7 +2441,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
|
||||
|
||||
RSG::mesh_storage->update_mesh_instances();
|
||||
|
||||
scene_render->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0);
|
||||
RSG::light_storage->light_instance_set_shadow_transform(light->instance, cm, light_transform, radius, 0, 0, 0);
|
||||
shadow_data.light = light->instance;
|
||||
shadow_data.pass = 0;
|
||||
|
||||
@ -2680,14 +2681,14 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
|
||||
cull_result.lights.push_back(idata.instance);
|
||||
cull_result.light_instances.push_back(RID::from_uint64(idata.instance_data_rid));
|
||||
if (cull_data.shadow_atlas.is_valid() && RSG::light_storage->light_has_shadow(idata.base_rid)) {
|
||||
scene_render->light_instance_mark_visible(RID::from_uint64(idata.instance_data_rid)); //mark it visible for shadow allocation later
|
||||
RSG::light_storage->light_instance_mark_visible(RID::from_uint64(idata.instance_data_rid)); //mark it visible for shadow allocation later
|
||||
}
|
||||
|
||||
} else if (base_type == RS::INSTANCE_REFLECTION_PROBE) {
|
||||
if (cull_data.render_reflection_probe != idata.instance) {
|
||||
//avoid entering The Matrix
|
||||
|
||||
if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || scene_render->reflection_probe_instance_needs_redraw(RID::from_uint64(idata.instance_data_rid))) {
|
||||
if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || RSG::light_storage->reflection_probe_instance_needs_redraw(RID::from_uint64(idata.instance_data_rid))) {
|
||||
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(idata.instance->base_data);
|
||||
cull_data.cull->lock.lock();
|
||||
if (!reflection_probe->update_list.in_list()) {
|
||||
@ -2699,7 +2700,7 @@ void RendererSceneCull::_scene_cull(CullData &cull_data, InstanceCullResult &cul
|
||||
idata.flags &= ~uint32_t(InstanceData::FLAG_REFLECTION_PROBE_DIRTY);
|
||||
}
|
||||
|
||||
if (scene_render->reflection_probe_instance_has_reflection(RID::from_uint64(idata.instance_data_rid))) {
|
||||
if (RSG::light_storage->reflection_probe_instance_has_reflection(RID::from_uint64(idata.instance_data_rid))) {
|
||||
cull_result.reflections.push_back(RID::from_uint64(idata.instance_data_rid));
|
||||
}
|
||||
}
|
||||
@ -2991,7 +2992,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
|
||||
}
|
||||
}
|
||||
|
||||
scene_render->set_directional_shadow_count(lights_with_shadow.size());
|
||||
RSG::light_storage->set_directional_shadow_count(lights_with_shadow.size());
|
||||
|
||||
for (int i = 0; i < lights_with_shadow.size(); i++) {
|
||||
_light_instance_setup_directional_shadow(i, lights_with_shadow[i], p_camera_data->main_transform, p_camera_data->main_projection, p_camera_data->is_orthogonal, p_camera_data->vaspect);
|
||||
@ -3091,7 +3092,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
|
||||
for (uint32_t j = 0; j < cull.shadows[i].cascade_count; j++) {
|
||||
const Cull::Shadow::Cascade &c = cull.shadows[i].cascades[j];
|
||||
// print_line("shadow " + itos(i) + " cascade " + itos(j) + " elements: " + itos(c.cull_result.size()));
|
||||
scene_render->light_instance_set_shadow_transform(cull.shadows[i].light_instance, c.projection, c.transform, c.zfar, c.split, j, c.shadow_texel_size, c.bias_scale, c.range_begin, c.uv_scale);
|
||||
RSG::light_storage->light_instance_set_shadow_transform(cull.shadows[i].light_instance, c.projection, c.transform, c.zfar, c.split, j, c.shadow_texel_size, c.bias_scale, c.range_begin, c.uv_scale);
|
||||
if (max_shadows_used == MAX_UPDATE_SHADOWS) {
|
||||
continue;
|
||||
}
|
||||
@ -3187,7 +3188,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
|
||||
light->shadow_dirty = false;
|
||||
}
|
||||
|
||||
bool redraw = scene_render->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version);
|
||||
bool redraw = RSG::light_storage->shadow_atlas_update_light(p_shadow_atlas, light->instance, coverage, light->last_version);
|
||||
|
||||
if (redraw && max_shadows_used < MAX_UPDATE_SHADOWS) {
|
||||
//must redraw!
|
||||
@ -3320,7 +3321,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
|
||||
RenderingServerDefault::redraw_request(); //update, so it updates in editor
|
||||
|
||||
if (p_step == 0) {
|
||||
if (!scene_render->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) {
|
||||
if (!RSG::light_storage->reflection_probe_instance_begin_render(reflection_probe->instance, scenario->reflection_atlas)) {
|
||||
return true; //all full
|
||||
}
|
||||
}
|
||||
@ -3346,7 +3347,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
|
||||
Vector3 extents = RSG::light_storage->reflection_probe_get_extents(p_instance->base);
|
||||
Vector3 origin_offset = RSG::light_storage->reflection_probe_get_origin_offset(p_instance->base);
|
||||
float max_distance = RSG::light_storage->reflection_probe_get_origin_max_distance(p_instance->base);
|
||||
float size = scene_render->reflection_atlas_get_size(scenario->reflection_atlas);
|
||||
float size = RSG::light_storage->reflection_atlas_get_size(scenario->reflection_atlas);
|
||||
float mesh_lod_threshold = RSG::light_storage->reflection_probe_get_mesh_lod_threshold(p_instance->base) / size;
|
||||
|
||||
Vector3 edge = view_normals[p_step] * extents;
|
||||
@ -3387,7 +3388,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
|
||||
} else {
|
||||
//do roughness postprocess step until it believes it's done
|
||||
RENDER_TIMESTAMP("Post-Process ReflectionProbe, Step " + itos(p_step));
|
||||
return scene_render->reflection_probe_instance_postprocess_step(reflection_probe->instance);
|
||||
return RSG::light_storage->reflection_probe_instance_postprocess_step(reflection_probe->instance);
|
||||
}
|
||||
|
||||
return false;
|
||||
@ -3967,8 +3968,8 @@ bool RendererSceneCull::free(RID p_rid) {
|
||||
scenario->instance_data.reset();
|
||||
scenario->instance_visibility.reset();
|
||||
|
||||
scene_render->free(scenario->reflection_probe_shadow_atlas);
|
||||
scene_render->free(scenario->reflection_atlas);
|
||||
RSG::light_storage->shadow_atlas_free(scenario->reflection_probe_shadow_atlas);
|
||||
RSG::light_storage->reflection_atlas_free(scenario->reflection_atlas);
|
||||
scenario_owner.free(p_rid);
|
||||
RendererSceneOcclusionCull::get_singleton()->remove_scenario(p_rid);
|
||||
|
||||
|
@ -1076,7 +1076,6 @@ public:
|
||||
|
||||
#define PASSBASE scene_render
|
||||
|
||||
PASS2(directional_shadow_atlas_set_size, int, bool)
|
||||
PASS1(voxel_gi_set_quality, RS::VoxelGIQuality)
|
||||
|
||||
/* SKY API */
|
||||
@ -1258,11 +1257,7 @@ public:
|
||||
PASS0R(Ref<RenderSceneBuffers>, render_buffers_create)
|
||||
PASS1(gi_set_use_half_resolution, bool)
|
||||
|
||||
/* Shadow Atlas */
|
||||
PASS0R(RID, shadow_atlas_create)
|
||||
PASS3(shadow_atlas_set_size, RID, int, bool)
|
||||
PASS3(shadow_atlas_set_quadrant_subdivision, RID, int, int)
|
||||
|
||||
/* Misc */
|
||||
PASS1(set_debug_draw_mode, RS::ViewportDebugDraw)
|
||||
|
||||
PASS1(decals_set_filter, RS::DecalFilter)
|
||||
|
@ -56,17 +56,6 @@ public:
|
||||
virtual void geometry_instance_free(RenderGeometryInstance *p_geometry_instance) = 0;
|
||||
virtual uint32_t geometry_instance_get_pair_mask() = 0;
|
||||
|
||||
/* SHADOW ATLAS API */
|
||||
|
||||
virtual RID shadow_atlas_create() = 0;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_16_bits = true) = 0;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
|
||||
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0;
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
|
||||
virtual void set_directional_shadow_count(int p_count) = 0;
|
||||
|
||||
/* SDFGI UPDATE */
|
||||
|
||||
virtual void sdfgi_update(const Ref<RenderSceneBuffers> &p_render_buffers, RID p_environment, const Vector3 &p_world_position) = 0;
|
||||
@ -240,39 +229,12 @@ public:
|
||||
virtual void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) = 0;
|
||||
virtual void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) = 0;
|
||||
|
||||
virtual RID light_instance_create(RID p_light) = 0;
|
||||
virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) = 0;
|
||||
virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0;
|
||||
virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0;
|
||||
virtual void light_instance_mark_visible(RID p_light_instance) = 0;
|
||||
virtual bool light_instances_can_render_shadow_cube() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual RID fog_volume_instance_create(RID p_fog_volume) = 0;
|
||||
virtual void fog_volume_instance_set_transform(RID p_fog_volume_instance, const Transform3D &p_transform) = 0;
|
||||
virtual void fog_volume_instance_set_active(RID p_fog_volume_instance, bool p_active) = 0;
|
||||
virtual RID fog_volume_instance_get_volume(RID p_fog_volume_instance) const = 0;
|
||||
virtual Vector3 fog_volume_instance_get_position(RID p_fog_volume_instance) const = 0;
|
||||
|
||||
virtual RID reflection_atlas_create() = 0;
|
||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) = 0;
|
||||
virtual int reflection_atlas_get_size(RID p_ref_atlas) const = 0;
|
||||
|
||||
virtual RID reflection_probe_instance_create(RID p_probe) = 0;
|
||||
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) = 0;
|
||||
virtual void reflection_probe_release_atlas_index(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_has_reflection(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) = 0;
|
||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0;
|
||||
|
||||
virtual RID decal_instance_create(RID p_decal) = 0;
|
||||
virtual void decal_instance_set_transform(RID p_decal, const Transform3D &p_transform) = 0;
|
||||
|
||||
virtual RID lightmap_instance_create(RID p_lightmap) = 0;
|
||||
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) = 0;
|
||||
|
||||
virtual RID voxel_gi_instance_create(RID p_voxel_gi) = 0;
|
||||
virtual void voxel_gi_instance_set_transform_to_data(RID p_probe, const Transform3D &p_xform) = 0;
|
||||
virtual bool voxel_gi_needs_update(RID p_probe) const = 0;
|
||||
|
@ -760,7 +760,7 @@ void RendererViewport::viewport_initialize(RID p_rid) {
|
||||
Viewport *viewport = viewport_owner.get_or_null(p_rid);
|
||||
viewport->self = p_rid;
|
||||
viewport->render_target = RSG::texture_storage->render_target_create();
|
||||
viewport->shadow_atlas = RSG::scene->shadow_atlas_create();
|
||||
viewport->shadow_atlas = RSG::light_storage->shadow_atlas_create();
|
||||
viewport->viewport_render_direct_to_screen = false;
|
||||
|
||||
viewport->fsr_enabled = !RSG::rasterizer->is_low_end() && !viewport->disable_3d;
|
||||
@ -1076,14 +1076,14 @@ void RendererViewport::viewport_set_positional_shadow_atlas_size(RID p_viewport,
|
||||
viewport->shadow_atlas_size = p_size;
|
||||
viewport->shadow_atlas_16_bits = p_16_bits;
|
||||
|
||||
RSG::scene->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size, viewport->shadow_atlas_16_bits);
|
||||
RSG::light_storage->shadow_atlas_set_size(viewport->shadow_atlas, viewport->shadow_atlas_size, viewport->shadow_atlas_16_bits);
|
||||
}
|
||||
|
||||
void RendererViewport::viewport_set_positional_shadow_atlas_quadrant_subdivision(RID p_viewport, int p_quadrant, int p_subdiv) {
|
||||
Viewport *viewport = viewport_owner.get_or_null(p_viewport);
|
||||
ERR_FAIL_COND(!viewport);
|
||||
|
||||
RSG::scene->shadow_atlas_set_quadrant_subdivision(viewport->shadow_atlas, p_quadrant, p_subdiv);
|
||||
RSG::light_storage->shadow_atlas_set_quadrant_subdivision(viewport->shadow_atlas, p_quadrant, p_subdiv);
|
||||
}
|
||||
|
||||
void RendererViewport::viewport_set_msaa_2d(RID p_viewport, RS::ViewportMSAA p_msaa) {
|
||||
@ -1294,7 +1294,7 @@ bool RendererViewport::free(RID p_rid) {
|
||||
Viewport *viewport = viewport_owner.get_or_null(p_rid);
|
||||
|
||||
RSG::texture_storage->render_target_free(viewport->render_target);
|
||||
RSG::scene->free(viewport->shadow_atlas);
|
||||
RSG::light_storage->shadow_atlas_free(viewport->shadow_atlas);
|
||||
if (viewport->render_buffers.is_valid()) {
|
||||
viewport->render_buffers.unref();
|
||||
}
|
||||
|
@ -106,8 +106,6 @@ public:
|
||||
virtual Variant instance_geometry_get_shader_parameter(RID p_instance, const StringName &p_parameter) const = 0;
|
||||
virtual Variant instance_geometry_get_shader_parameter_default_value(RID p_instance, const StringName &p_parameter) const = 0;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0;
|
||||
|
||||
/* SKY API */
|
||||
|
||||
virtual RID sky_allocate() = 0;
|
||||
@ -284,10 +282,6 @@ public:
|
||||
virtual void positional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) = 0;
|
||||
virtual void directional_soft_shadow_filter_set_quality(RS::ShadowQuality p_quality) = 0;
|
||||
|
||||
virtual RID shadow_atlas_create() = 0;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = true) = 0;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
|
||||
|
||||
/* Render Buffers */
|
||||
|
||||
virtual Ref<RenderSceneBuffers> render_buffers_create() = 0;
|
||||
|
@ -410,6 +410,13 @@ public:
|
||||
FUNC1RC(PackedInt32Array, lightmap_get_probe_capture_bsp_tree, RID)
|
||||
FUNC1(lightmap_set_probe_capture_update_speed, float)
|
||||
|
||||
/* Shadow Atlas */
|
||||
FUNC0R(RID, shadow_atlas_create)
|
||||
FUNC3(shadow_atlas_set_size, RID, int, bool)
|
||||
FUNC3(shadow_atlas_set_quadrant_subdivision, RID, int, int)
|
||||
|
||||
FUNC2(directional_shadow_atlas_set_size, int, bool)
|
||||
|
||||
/* DECAL API */
|
||||
|
||||
#undef ServerName
|
||||
@ -652,7 +659,6 @@ public:
|
||||
#define ServerName RenderingMethod
|
||||
#define server_name RSG::scene
|
||||
|
||||
FUNC2(directional_shadow_atlas_set_size, int, bool)
|
||||
FUNC1(voxel_gi_set_quality, VoxelGIQuality)
|
||||
|
||||
/* SKY API */
|
||||
|
@ -84,6 +84,18 @@ public:
|
||||
virtual uint32_t light_get_max_sdfgi_cascade(RID p_light) = 0;
|
||||
virtual uint64_t light_get_version(RID p_light) const = 0;
|
||||
|
||||
/* LIGHT INSTANCE API */
|
||||
|
||||
virtual RID light_instance_create(RID p_light) = 0;
|
||||
virtual void light_instance_free(RID p_light_instance) = 0;
|
||||
virtual void light_instance_set_transform(RID p_light_instance, const Transform3D &p_transform) = 0;
|
||||
virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0;
|
||||
virtual void light_instance_set_shadow_transform(RID p_light_instance, const Projection &p_projection, const Transform3D &p_transform, float p_far, float p_split, int p_pass, float p_shadow_texel_size, float p_bias_scale = 1.0, float p_range_begin = 0, const Vector2 &p_uv_scale = Vector2()) = 0;
|
||||
virtual void light_instance_mark_visible(RID p_light_instance) = 0;
|
||||
virtual bool light_instances_can_render_shadow_cube() const {
|
||||
return true;
|
||||
}
|
||||
|
||||
/* PROBE API */
|
||||
|
||||
virtual RID reflection_probe_allocate() = 0;
|
||||
@ -114,6 +126,24 @@ public:
|
||||
virtual bool reflection_probe_renders_shadows(RID p_probe) const = 0;
|
||||
virtual float reflection_probe_get_mesh_lod_threshold(RID p_probe) const = 0;
|
||||
|
||||
/* REFLECTION ATLAS */
|
||||
|
||||
virtual RID reflection_atlas_create() = 0;
|
||||
virtual void reflection_atlas_free(RID p_ref_atlas) = 0;
|
||||
virtual void reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_size, int p_reflection_count) = 0;
|
||||
virtual int reflection_atlas_get_size(RID p_ref_atlas) const = 0;
|
||||
|
||||
/* REFLECTION PROBE INSTANCE */
|
||||
|
||||
virtual RID reflection_probe_instance_create(RID p_probe) = 0;
|
||||
virtual void reflection_probe_instance_free(RID p_instance) = 0;
|
||||
virtual void reflection_probe_instance_set_transform(RID p_instance, const Transform3D &p_transform) = 0;
|
||||
virtual void reflection_probe_release_atlas_index(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_has_reflection(RID p_instance) = 0;
|
||||
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) = 0;
|
||||
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0;
|
||||
|
||||
/* LIGHTMAP */
|
||||
|
||||
virtual RID lightmap_allocate() = 0;
|
||||
@ -134,6 +164,27 @@ public:
|
||||
virtual bool lightmap_is_interior(RID p_lightmap) const = 0;
|
||||
virtual void lightmap_set_probe_capture_update_speed(float p_speed) = 0;
|
||||
virtual float lightmap_get_probe_capture_update_speed() const = 0;
|
||||
|
||||
/* LIGHTMAP INSTANCE */
|
||||
|
||||
virtual RID lightmap_instance_create(RID p_lightmap) = 0;
|
||||
virtual void lightmap_instance_free(RID p_lightmap) = 0;
|
||||
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform3D &p_transform) = 0;
|
||||
|
||||
/* SHADOW ATLAS */
|
||||
|
||||
virtual RID shadow_atlas_create() = 0;
|
||||
virtual void shadow_atlas_free(RID p_atlas) = 0;
|
||||
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = true) = 0;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
|
||||
virtual bool shadow_atlas_update_light(RID p_atlas, RID p_light_intance, float p_coverage, uint64_t p_light_version) = 0;
|
||||
|
||||
virtual void shadow_atlas_update(RID p_atlas) = 0;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0;
|
||||
virtual int get_directional_light_shadow_size(RID p_light_intance) = 0;
|
||||
virtual void set_directional_shadow_count(int p_count) = 0;
|
||||
};
|
||||
|
||||
#endif // LIGHT_STORAGE_H
|
||||
|
@ -120,6 +120,12 @@ public:
|
||||
virtual void texture_add_to_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
virtual void texture_remove_from_decal_atlas(RID p_texture, bool p_panorama_to_dp = false) = 0;
|
||||
|
||||
/* DECAL INSTANCE */
|
||||
|
||||
virtual RID decal_instance_create(RID p_decal) = 0;
|
||||
virtual void decal_instance_free(RID p_decal_instance) = 0;
|
||||
virtual void decal_instance_set_transform(RID p_decal_instance, const Transform3D &p_transform) = 0;
|
||||
|
||||
/* RENDER TARGET */
|
||||
|
||||
virtual RID render_target_create() = 0;
|
||||
|
@ -485,6 +485,12 @@ public:
|
||||
virtual void light_directional_set_blend_splits(RID p_light, bool p_enable) = 0;
|
||||
virtual void light_directional_set_sky_mode(RID p_light, LightDirectionalSkyMode p_mode) = 0;
|
||||
|
||||
// Shadow atlas
|
||||
|
||||
virtual RID shadow_atlas_create() = 0;
|
||||
virtual void shadow_atlas_set_size(RID p_atlas, int p_size, bool p_use_16_bits = true) = 0;
|
||||
virtual void shadow_atlas_set_quadrant_subdivision(RID p_atlas, int p_quadrant, int p_subdivision) = 0;
|
||||
|
||||
virtual void directional_shadow_atlas_set_size(int p_size, bool p_16_bits = true) = 0;
|
||||
|
||||
enum ShadowQuality {
|
||||
|
Loading…
Reference in New Issue
Block a user