Reorganize renderer code.

So it can hopefully be made more cache efficient afterwards.
This commit is contained in:
reduz 2020-12-31 09:42:56 -03:00
parent 8a1c37dc22
commit 9a2f18f8e7
13 changed files with 864 additions and 390 deletions

View file

@ -40,30 +40,35 @@ class RID {
uint64_t _id = 0;
public:
_FORCE_INLINE_ bool operator==(const RID &p_rid) const {
_ALWAYS_INLINE_ bool operator==(const RID &p_rid) const {
return _id == p_rid._id;
}
_FORCE_INLINE_ bool operator<(const RID &p_rid) const {
_ALWAYS_INLINE_ bool operator<(const RID &p_rid) const {
return _id < p_rid._id;
}
_FORCE_INLINE_ bool operator<=(const RID &p_rid) const {
_ALWAYS_INLINE_ bool operator<=(const RID &p_rid) const {
return _id <= p_rid._id;
}
_FORCE_INLINE_ bool operator>(const RID &p_rid) const {
_ALWAYS_INLINE_ bool operator>(const RID &p_rid) const {
return _id > p_rid._id;
}
_FORCE_INLINE_ bool operator>=(const RID &p_rid) const {
_ALWAYS_INLINE_ bool operator>=(const RID &p_rid) const {
return _id >= p_rid._id;
}
_FORCE_INLINE_ bool operator!=(const RID &p_rid) const {
_ALWAYS_INLINE_ bool operator!=(const RID &p_rid) const {
return _id != p_rid._id;
}
_FORCE_INLINE_ bool is_valid() const { return _id != 0; }
_FORCE_INLINE_ bool is_null() const { return _id == 0; }
_ALWAYS_INLINE_ bool is_valid() const { return _id != 0; }
_ALWAYS_INLINE_ bool is_null() const { return _id == 0; }
_FORCE_INLINE_ uint64_t get_id() const { return _id; }
static _ALWAYS_INLINE_ RID from_uint64(uint64_t p_id) {
RID _rid;
_rid._id = p_id;
return _rid;
}
_ALWAYS_INLINE_ uint64_t get_id() const { return _id; }
_FORCE_INLINE_ RID() {}
_ALWAYS_INLINE_ RID() {}
};
#endif // RID_H

View file

@ -815,7 +815,7 @@ void RendererSceneRenderForward::_fill_instances(RenderList::Element **p_element
bool store_transform = true;
id.flags = 0;
id.mask = e->instance->layer_mask;
id.instance_uniforms_ofs = e->instance->instance_allocated_shader_parameters_offset >= 0 ? e->instance->instance_allocated_shader_parameters_offset : 0;
id.instance_uniforms_ofs = e->instance->shader_parameters_offset >= 0 ? e->instance->shader_parameters_offset : 0;
if (e->instance->base_type == RS::INSTANCE_MULTIMESH) {
id.flags |= INSTANCE_DATA_FLAG_MULTIMESH;
@ -877,26 +877,32 @@ void RendererSceneRenderForward::_fill_instances(RenderList::Element **p_element
continue;
}
if (e->instance->lightmap) {
int32_t lightmap_index = storage->lightmap_get_array_index(e->instance->lightmap->base);
if (lightmap_index >= 0) {
id.gi_offset = lightmap_index;
if (e->instance->lightmap_instance.is_valid()) {
int32_t lightmap_cull_index = -1;
for (uint32_t j = 0; j < scene_state.lightmaps_used; j++) {
if (scene_state.lightmap_ids[j] == e->instance->lightmap_instance) {
lightmap_cull_index = j;
break;
}
}
if (lightmap_cull_index >= 0) {
id.gi_offset = 0;
id.gi_offset |= e->instance->lightmap_slice_index << 12;
id.gi_offset |= e->instance->lightmap_cull_index << 20;
id.gi_offset |= lightmap_cull_index << 20;
id.lightmap_uv_scale[0] = e->instance->lightmap_uv_scale.position.x;
id.lightmap_uv_scale[1] = e->instance->lightmap_uv_scale.position.y;
id.lightmap_uv_scale[2] = e->instance->lightmap_uv_scale.size.width;
id.lightmap_uv_scale[3] = e->instance->lightmap_uv_scale.size.height;
id.flags |= INSTANCE_DATA_FLAG_USE_LIGHTMAP;
if (storage->lightmap_uses_spherical_harmonics(e->instance->lightmap->base)) {
if (scene_state.lightmap_has_sh[lightmap_cull_index]) {
id.flags |= INSTANCE_DATA_FLAG_USE_SH_LIGHTMAP;
}
} else {
id.gi_offset = 0xFFFFFFFF;
}
} else if (!e->instance->lightmap_sh.is_empty()) {
} else if (e->instance->lightmap_sh) {
if (lightmap_captures_used < scene_state.max_lightmap_captures) {
const Color *src_capture = e->instance->lightmap_sh.ptr();
const Color *src_capture = e->instance->lightmap_sh;
LightmapCaptureData &lcd = scene_state.lightmap_captures[lightmap_captures_used];
for (int j = 0; j < 9; j++) {
lcd.sh[j * 4 + 0] = src_capture[j].r;
@ -914,9 +920,9 @@ void RendererSceneRenderForward::_fill_instances(RenderList::Element **p_element
id.flags |= INSTANCE_DATA_FLAG_USE_GI_BUFFERS;
}
if (!low_end && !e->instance->gi_probe_instances.is_empty()) {
if (!low_end && e->instance->gi_probe_instance_count > 0) {
uint32_t written = 0;
for (int j = 0; j < e->instance->gi_probe_instances.size(); j++) {
for (uint32_t j = 0; j < e->instance->gi_probe_instance_count; j++) {
RID probe = e->instance->gi_probe_instances[j];
uint32_t index = gi_probe_instance_get_render_index(probe);
@ -937,7 +943,7 @@ void RendererSceneRenderForward::_fill_instances(RenderList::Element **p_element
id.gi_offset |= 0xFFFF0000;
}
} else {
if (p_has_sdfgi && (e->instance->baked_light || e->instance->dynamic_gi)) {
if (p_has_sdfgi && (e->instance->use_baked_light || e->instance->use_dynamic_gi)) {
id.flags |= INSTANCE_DATA_FLAG_USE_SDFGI;
}
id.gi_offset = 0xFFFFFFFF;
@ -984,7 +990,7 @@ void RendererSceneRenderForward::_render_list(RenderingDevice::DrawListID p_draw
//find cull variant
ShaderData::CullVariant cull_variant;
if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL || p_pass_mode == PASS_MODE_SDF || ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED)) {
if (p_pass_mode == PASS_MODE_DEPTH_MATERIAL || p_pass_mode == PASS_MODE_SDF || ((p_pass_mode == PASS_MODE_SHADOW || p_pass_mode == PASS_MODE_SHADOW_DP) && e->instance->cast_double_sided_shaodows)) {
cull_variant = ShaderData::CULL_VARIANT_DOUBLE_SIDED;
} else {
bool mirror = e->instance->mirror;
@ -1413,7 +1419,7 @@ void RendererSceneRenderForward::_setup_environment(RID p_environment, RID p_ren
RD::get_singleton()->buffer_update(scene_state.uniform_buffer, 0, sizeof(SceneState::UBO), &scene_state.ubo, true);
}
void RendererSceneRenderForward::_add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) {
void RendererSceneRenderForward::_add_geometry(GeometryInstanceForward *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) {
RID m_src;
m_src = p_instance->material_override.is_valid() ? p_instance->material_override : p_material;
@ -1453,7 +1459,7 @@ void RendererSceneRenderForward::_add_geometry(InstanceBase *p_instance, uint32_
}
}
void RendererSceneRenderForward::_add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) {
void RendererSceneRenderForward::_add_geometry_with_material(GeometryInstanceForward *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi) {
bool has_read_screen_alpha = p_material->shader_data->uses_screen_texture || p_material->shader_data->uses_depth_texture || p_material->shader_data->uses_normal_texture;
bool has_base_alpha = (p_material->shader_data->uses_alpha || has_read_screen_alpha);
bool has_blend_alpha = p_material->shader_data->uses_blend_alpha;
@ -1476,7 +1482,7 @@ void RendererSceneRenderForward::_add_geometry_with_material(InstanceBase *p_ins
}
if (p_pass_mode != PASS_MODE_COLOR && p_pass_mode != PASS_MODE_COLOR_SPECULAR) {
if (has_blend_alpha || has_read_screen_alpha || (has_base_alpha && !p_material->shader_data->uses_depth_pre_pass) || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED || p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
if (has_blend_alpha || has_read_screen_alpha || (has_base_alpha && !p_material->shader_data->uses_depth_pre_pass) || p_material->shader_data->depth_draw == ShaderData::DEPTH_DRAW_DISABLED || p_material->shader_data->depth_test == ShaderData::DEPTH_TEST_DISABLED) {
//conditions in which no depth pass should be processed
return;
}
@ -1521,8 +1527,8 @@ void RendererSceneRenderForward::_add_geometry_with_material(InstanceBase *p_ins
e->geometry_index = p_geometry_index;
e->material_index = e->material->index;
e->uses_instancing = e->instance->base_type == RS::INSTANCE_MULTIMESH;
e->uses_lightmap = e->instance->lightmap != nullptr || !e->instance->lightmap_sh.is_empty();
e->uses_forward_gi = has_alpha && (e->instance->gi_probe_instances.size() || p_using_sdfgi);
e->uses_lightmap = e->instance->lightmap_instance.is_valid() || e->instance->lightmap_sh != nullptr;
e->uses_forward_gi = has_alpha && (e->instance->gi_probe_instance_count > 0 || p_using_sdfgi);
e->shader_index = e->shader_index;
e->depth_layer = e->instance->depth_layer;
e->priority = p_material->priority;
@ -1532,7 +1538,7 @@ void RendererSceneRenderForward::_add_geometry_with_material(InstanceBase *p_ins
}
}
void RendererSceneRenderForward::_fill_render_list(const PagedArray<InstanceBase *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi) {
void RendererSceneRenderForward::_fill_render_list(const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi) {
scene_state.current_shader_index = 0;
scene_state.current_material_index = 0;
scene_state.used_sss = false;
@ -1549,7 +1555,7 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<InstanceBase
//fill list
for (int i = 0; i < (int)p_instances.size(); i++) {
InstanceBase *inst = p_instances[i];
GeometryInstanceForward *inst = static_cast<GeometryInstanceForward *>(p_instances[i]);
inst->depth = near_plane.distance_to(inst->transform.origin);
inst->depth_layer = CLAMP(int(inst->depth * 16 / z_max), 0, 15);
@ -1565,7 +1571,7 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<InstanceBase
continue; //nothing to do
}
const RID *inst_materials = inst->materials.ptr();
const RID *inst_materials = inst->surface_materials.ptr();
for (uint32_t j = 0; j < surface_count; j++) {
RID material = inst_materials[j].is_valid() ? inst_materials[j] : materials[j];
@ -1642,26 +1648,29 @@ void RendererSceneRenderForward::_fill_render_list(const PagedArray<InstanceBase
}
}
void RendererSceneRenderForward::_setup_lightmaps(const PagedArray<InstanceBase *> &p_lightmaps, const Transform &p_cam_transform) {
uint32_t lightmaps_used = 0;
void RendererSceneRenderForward::_setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform) {
scene_state.lightmaps_used = 0;
for (int i = 0; i < (int)p_lightmaps.size(); i++) {
if (i >= (int)scene_state.max_lightmaps) {
break;
}
InstanceBase *lm = p_lightmaps[i];
Basis to_lm = lm->transform.basis.inverse() * p_cam_transform.basis;
RID lightmap = lightmap_instance_get_lightmap(p_lightmaps[i]);
Basis to_lm = lightmap_instance_get_transform(p_lightmaps[i]).basis.inverse() * p_cam_transform.basis;
to_lm = to_lm.inverse().transposed(); //will transform normals
RendererStorageRD::store_transform_3x3(to_lm, scene_state.lightmaps[i].normal_xform);
lm->lightmap_cull_index = i;
lightmaps_used++;
scene_state.lightmap_ids[i] = p_lightmaps[i];
scene_state.lightmap_has_sh[i] = storage->lightmap_uses_spherical_harmonics(lightmap);
scene_state.lightmaps_used++;
}
if (lightmaps_used > 0) {
RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * lightmaps_used, scene_state.lightmaps, true);
if (scene_state.lightmaps_used > 0) {
RD::get_singleton()->buffer_update(scene_state.lightmap_buffer, 0, sizeof(LightmapData) * scene_state.lightmaps_used, scene_state.lightmaps, true);
}
}
void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_screen_lod_threshold) {
RenderBufferDataForward *render_buffer = nullptr;
if (p_render_buffer.is_valid()) {
render_buffer = (RenderBufferDataForward *)render_buffers_get_data(p_render_buffer);
@ -1885,7 +1894,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
if (depth_pre_pass) { //depth pre pass
RENDER_TIMESTAMP("Render Depth Pre-Pass");
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
_setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
bool finish_depth = using_ssao || using_sdfgi || using_giprobe;
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(depth_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, depth_pass_clear);
@ -1917,7 +1926,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
RENDER_TIMESTAMP("Render Opaque Pass");
RID rp_uniform_set = _setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_gi_probes);
_setup_render_pass_uniform_set(p_render_buffer, radiance_texture, p_shadow_atlas, p_reflection_atlas, p_gi_probes, p_lightmaps);
bool can_continue_color = !scene_state.used_screen_texture && !using_ssr && !using_sss;
bool can_continue_depth = !scene_state.used_depth_texture && !using_ssr && !using_sss;
@ -2036,7 +2045,7 @@ void RendererSceneRenderForward::_render_scene(RID p_render_buffer, const Transf
}
}
void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &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, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &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, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
RENDER_TIMESTAMP("Setup Rendering Shadow");
_update_render_base_uniform_set();
@ -2057,7 +2066,7 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr
_fill_render_list(p_instances, pass_mode, p_projection, p_transform);
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Shadow");
@ -2073,7 +2082,7 @@ void RendererSceneRenderForward::_render_shadow(RID p_framebuffer, const PagedAr
}
}
void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances) {
void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) {
RENDER_TIMESTAMP("Setup Render Collider Heightfield");
_update_render_base_uniform_set();
@ -2090,7 +2099,7 @@ void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb,
_fill_render_list(p_instances, pass_mode, p_cam_projection, p_cam_transform);
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Collider Heightield");
@ -2106,7 +2115,7 @@ void RendererSceneRenderForward::_render_particle_collider_heightfield(RID p_fb,
}
}
void RendererSceneRenderForward::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
void RendererSceneRenderForward::_render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering Material");
_update_render_base_uniform_set();
@ -2123,7 +2132,7 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
_fill_render_list(p_instances, pass_mode, p_cam_projection, p_cam_transform);
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Material");
@ -2145,7 +2154,7 @@ void RendererSceneRenderForward::_render_material(const Transform &p_cam_transfo
}
}
void RendererSceneRenderForward::_render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
void RendererSceneRenderForward::_render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
RENDER_TIMESTAMP("Setup Rendering UV2");
_update_render_base_uniform_set();
@ -2162,7 +2171,7 @@ void RendererSceneRenderForward::_render_uv2(const PagedArray<InstanceBase *> &p
PassMode pass_mode = PASS_MODE_DEPTH_MATERIAL;
_fill_render_list(p_instances, pass_mode, CameraMatrix(), Transform());
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>());
RID rp_uniform_set = _setup_render_pass_uniform_set(RID(), RID(), RID(), RID(), PagedArray<RID>(), PagedArray<RID>());
RENDER_TIMESTAMP("Render Material");
@ -2206,7 +2215,7 @@ void RendererSceneRenderForward::_render_uv2(const PagedArray<InstanceBase *> &p
}
}
void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
void RendererSceneRenderForward::_render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) {
RENDER_TIMESTAMP("Render SDFGI");
_update_render_base_uniform_set();
@ -2380,20 +2389,13 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.binding = 11;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids = storage->lightmap_array_get_textures();
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 12;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(scene_state.lightmap_capture_buffer);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 13;
u.binding = 12;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture();
u.ids.push_back(decal_atlas);
@ -2401,7 +2403,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
}
{
RD::Uniform u;
u.binding = 14;
u.binding = 13;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID decal_atlas = storage->decal_atlas_get_texture_srgb();
u.ids.push_back(decal_atlas);
@ -2409,7 +2411,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
}
{
RD::Uniform u;
u.binding = 15;
u.binding = 14;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(get_decal_buffer());
uniforms.push_back(u);
@ -2417,14 +2419,14 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.binding = 16;
u.binding = 15;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.push_back(get_cluster_builder_texture());
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 17;
u.binding = 16;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.ids.push_back(get_cluster_builder_indices_buffer());
uniforms.push_back(u);
@ -2432,7 +2434,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.binding = 18;
u.binding = 17;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
if (directional_shadow_get_texture().is_valid()) {
u.ids.push_back(directional_shadow_get_texture());
@ -2445,7 +2447,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_STORAGE_BUFFER;
u.binding = 19;
u.binding = 18;
u.ids.push_back(storage->global_variables_get_storage_buffer());
uniforms.push_back(u);
}
@ -2453,7 +2455,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
if (!low_end) {
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.binding = 20;
u.binding = 19;
u.ids.push_back(sdfgi_get_ubo());
uniforms.push_back(u);
}
@ -2462,7 +2464,7 @@ void RendererSceneRenderForward::_update_render_base_uniform_set() {
}
}
RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes) {
RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps) {
if (render_pass_uniform_set.is_valid() && RD::get_singleton()->uniform_set_is_valid(render_pass_uniform_set)) {
RD::get_singleton()->free(render_pass_uniform_set);
}
@ -2517,11 +2519,29 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
u.ids.push_back(texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 3;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.resize(scene_state.max_lightmaps);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
if (i < p_lightmaps.size()) {
RID base = lightmap_instance_get_lightmap(p_lightmaps[i]);
RID texture = storage->lightmap_get_texture(base);
RID rd_texture = storage->texture_get_rd_texture(texture);
u.ids.write[i] = rd_texture;
} else {
u.ids.write[i] = default_tex;
}
}
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 4;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.resize(MAX_GI_PROBES);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
for (int i = 0; i < MAX_GI_PROBES; i++) {
@ -2541,7 +2561,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
{
RD::Uniform u;
u.binding = 4;
u.binding = 5;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = (false && rb && rb->depth.is_valid()) ? rb->depth : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_WHITE);
u.ids.push_back(texture);
@ -2549,7 +2569,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
}
{
RD::Uniform u;
u.binding = 5;
u.binding = 6;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID bbt = rb ? render_buffers_get_back_buffer_texture(p_render_buffers) : RID();
RID texture = bbt.is_valid() ? bbt : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
@ -2559,7 +2579,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
if (!low_end) {
{
RD::Uniform u;
u.binding = 6;
u.binding = 7;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = rb && rb->normal_roughness_buffer.is_valid() ? rb->normal_roughness_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_NORMAL);
u.ids.push_back(texture);
@ -2568,7 +2588,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
{
RD::Uniform u;
u.binding = 7;
u.binding = 8;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID aot = rb ? render_buffers_get_ao_texture(p_render_buffers) : RID();
RID texture = aot.is_valid() ? aot : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
@ -2578,7 +2598,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
{
RD::Uniform u;
u.binding = 8;
u.binding = 9;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = rb && rb->ambient_buffer.is_valid() ? rb->ambient_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
@ -2587,7 +2607,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
{
RD::Uniform u;
u.binding = 9;
u.binding = 10;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID texture = rb && rb->reflection_buffer.is_valid() ? rb->reflection_buffer : storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_BLACK);
u.ids.push_back(texture);
@ -2595,7 +2615,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
}
{
RD::Uniform u;
u.binding = 10;
u.binding = 11;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID t;
if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
@ -2608,7 +2628,7 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
}
{
RD::Uniform u;
u.binding = 11;
u.binding = 12;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
if (rb && render_buffers_is_sdfgi_enabled(p_render_buffers)) {
u.ids.push_back(render_buffers_get_sdfgi_occlusion_texture(p_render_buffers));
@ -2619,14 +2639,14 @@ RID RendererSceneRenderForward::_setup_render_pass_uniform_set(RID p_render_buff
}
{
RD::Uniform u;
u.binding = 12;
u.binding = 13;
u.uniform_type = RD::UNIFORM_TYPE_UNIFORM_BUFFER;
u.ids.push_back(rb ? render_buffers_get_gi_probe_buffer(p_render_buffers) : render_buffers_get_default_gi_probe_buffer());
uniforms.push_back(u);
}
{
RD::Uniform u;
u.binding = 13;
u.binding = 14;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
RID vfog = RID();
if (rb && render_buffers_has_volumetric_fog(p_render_buffers)) {
@ -2684,10 +2704,24 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
}
{
// No GIProbes
// No Lightmaps
RD::Uniform u;
u.binding = 3;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.resize(scene_state.max_lightmaps);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_2D_ARRAY_WHITE);
for (uint32_t i = 0; i < scene_state.max_lightmaps; i++) {
u.ids.write[i] = default_tex;
}
uniforms.push_back(u);
}
{
// No GIProbes
RD::Uniform u;
u.binding = 4;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.ids.resize(MAX_GI_PROBES);
RID default_tex = storage->texture_rd_get_default(RendererStorageRD::DEFAULT_RD_TEXTURE_3D_WHITE);
for (int i = 0; i < MAX_GI_PROBES; i++) {
@ -2701,28 +2735,28 @@ RID RendererSceneRenderForward::_setup_sdfgi_render_pass_uniform_set(RID p_albed
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 4;
u.binding = 5;
u.ids.push_back(p_albedo_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 5;
u.binding = 6;
u.ids.push_back(p_emission_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 6;
u.binding = 7;
u.ids.push_back(p_emission_aniso_texture);
uniforms.push_back(u);
}
{
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_IMAGE;
u.binding = 7;
u.binding = 8;
u.ids.push_back(p_geom_facing_texture);
uniforms.push_back(u);
}
@ -2765,6 +2799,140 @@ void RendererSceneRenderForward::set_time(double p_time, double p_step) {
RendererSceneRenderRD::set_time(p_time, p_step);
}
RendererSceneRender::GeometryInstance *RendererSceneRenderForward::geometry_instance_create(RID p_base) {
RS::InstanceType type = storage->get_base_type(p_base);
ERR_FAIL_COND_V(!((1 << type) & RS::INSTANCE_GEOMETRY_MASK), nullptr);
GeometryInstanceForward *ginstance = geometry_instance_alloc.alloc();
ginstance->base = p_base;
ginstance->base_type = type;
return ginstance;
}
void RendererSceneRenderForward::geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->skeleton = p_skeleton;
}
void RendererSceneRenderForward::geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->material_override = p_override;
}
void RendererSceneRenderForward::geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->surface_materials = p_materials;
}
void RendererSceneRenderForward::geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->mesh_instance = p_mesh_instance;
}
void RendererSceneRenderForward::geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->transform = p_transform;
ginstance->mirror = p_transform.basis.determinant() < 0;
ginstance->aabb = p_aabb;
ginstance->transformed_aabb = p_transformed_aabb;
}
void RendererSceneRenderForward::geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->lod_bias = p_lod_bias;
}
void RendererSceneRenderForward::geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->use_baked_light = p_enable;
}
void RendererSceneRenderForward::geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->use_dynamic_gi = p_enable;
}
void RendererSceneRenderForward::geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->lightmap_instance = p_lightmap_instance;
ginstance->lightmap_uv_scale = p_lightmap_uv_scale;
ginstance->lightmap_slice_index = p_lightmap_slice_index;
}
void RendererSceneRenderForward::geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
if (p_sh9) {
if (ginstance->lightmap_sh == nullptr) {
ginstance->lightmap_sh = (Color *)memalloc(sizeof(Color) * 9);
}
copymem(ginstance->lightmap_sh, p_sh9, sizeof(Color) * 9);
} else {
if (ginstance->lightmap_sh != nullptr) {
memfree(ginstance->lightmap_sh);
ginstance->lightmap_sh = nullptr;
}
}
}
void RendererSceneRenderForward::geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->shader_parameters_offset = p_offset;
}
void RendererSceneRenderForward::geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->cast_double_sided_shaodows = p_enable;
}
void RendererSceneRenderForward::geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->layer_mask = p_layer_mask;
}
void RendererSceneRenderForward::geometry_instance_free(GeometryInstance *p_geometry_instance) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
if (ginstance->lightmap_sh != nullptr) {
memfree(ginstance->lightmap_sh);
}
geometry_instance_alloc.free(ginstance);
}
uint32_t RendererSceneRenderForward::geometry_instance_get_pair_mask() {
return (1 << RS::INSTANCE_GI_PROBE);
}
void RendererSceneRenderForward::geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) {
}
void RendererSceneRenderForward::geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) {
}
void RendererSceneRenderForward::geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) {
}
Transform RendererSceneRenderForward::geometry_instance_get_transform(GeometryInstance *p_instance) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance);
ERR_FAIL_COND_V(!ginstance, Transform());
return ginstance->transform;
}
AABB RendererSceneRenderForward::geometry_instance_get_aabb(GeometryInstance *p_instance) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_instance);
ERR_FAIL_COND_V(!ginstance, AABB());
return ginstance->aabb;
}
void RendererSceneRenderForward::geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) {
GeometryInstanceForward *ginstance = static_cast<GeometryInstanceForward *>(p_geometry_instance);
ERR_FAIL_COND(!ginstance);
ginstance->gi_probe_instance_count = MIN(p_gi_probe_instance_count, MAX_GI_PROBES);
for (uint32_t i = 0; i < ginstance->gi_probe_instance_count; i++) {
ginstance->gi_probe_instances[i] = p_gi_probe_instances[i];
}
}
RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_storage) :
RendererSceneRenderRD(p_storage) {
singleton = this;
@ -2788,11 +2956,10 @@ RendererSceneRenderForward::RendererSceneRenderForward(RendererStorageRD *p_stor
{
//lightmaps
scene_state.max_lightmaps = storage->lightmap_array_get_size();
scene_state.max_lightmaps = low_end ? 2 : MAX_LIGHTMAPS;
defines += "\n#define MAX_LIGHTMAP_TEXTURES " + itos(scene_state.max_lightmaps) + "\n";
defines += "\n#define MAX_LIGHTMAPS " + itos(scene_state.max_lightmaps) + "\n";
scene_state.lightmaps = memnew_arr(LightmapData, scene_state.max_lightmaps);
scene_state.lightmap_buffer = RD::get_singleton()->storage_buffer_create(sizeof(LightmapData) * scene_state.max_lightmaps);
}
{
@ -3099,7 +3266,6 @@ RendererSceneRenderForward::~RendererSceneRenderForward() {
RD::get_singleton()->free(scene_state.lightmap_buffer);
RD::get_singleton()->free(scene_state.lightmap_capture_buffer);
memdelete_arr(scene_state.instances);
memdelete_arr(scene_state.lightmaps);
memdelete_arr(scene_state.lightmap_captures);
}

View file

@ -31,6 +31,7 @@
#ifndef RENDERING_SERVER_SCENE_RENDER_FORWARD_H
#define RENDERING_SERVER_SCENE_RENDER_FORWARD_H
#include "core/templates/paged_allocator.h"
#include "servers/rendering/renderer_rd/pipeline_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/renderer_storage_rd.h"
@ -46,7 +47,8 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
enum {
SDFGI_MAX_CASCADES = 8,
MAX_GI_PROBES = 8
MAX_GI_PROBES = 8,
MAX_LIGHTMAPS = 8
};
/* Scene Shader */
@ -266,7 +268,7 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
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);
RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes);
RID _setup_render_pass_uniform_set(RID p_render_buffers, RID p_radiance_texture, RID p_shadow_atlas, RID p_reflection_atlas, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps);
struct LightmapData {
float normal_xform[12];
@ -385,7 +387,10 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
RID uniform_buffer;
LightmapData *lightmaps;
LightmapData lightmaps[MAX_LIGHTMAPS];
RID lightmap_ids[MAX_LIGHTMAPS];
bool lightmap_has_sh[MAX_LIGHTMAPS];
uint32_t lightmaps_used = 0;
uint32_t max_lightmaps;
RID lightmap_buffer;
@ -408,11 +413,13 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
/* Render List */
struct GeometryInstanceForward;
struct RenderList {
int max_elements;
struct Element {
RendererSceneRender::InstanceBase *instance;
GeometryInstanceForward *instance;
MaterialData *material;
union {
struct {
@ -567,28 +574,89 @@ class RendererSceneRenderForward : public RendererSceneRenderRD {
};
void _setup_environment(RID p_environment, RID p_render_buffers, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, RID p_reflection_probe, bool p_no_fog, const Size2 &p_screen_pixel_size, RID p_shadow_atlas, bool p_flip_y, const Color &p_default_bg_color, float p_znear, float p_zfar, bool p_opaque_render_buffers = false, bool p_pancake_shadows = false);
void _setup_lightmaps(const PagedArray<InstanceBase *> &p_lightmaps, const Transform &p_cam_transform);
void _setup_lightmaps(const PagedArray<RID> &p_lightmaps, const Transform &p_cam_transform);
void _fill_instances(RenderList::Element **p_elements, int p_element_count, bool p_for_depth, bool p_has_sdfgi = false, bool p_has_opaque_gi = false);
void _render_list(RenderingDevice::DrawListID p_draw_list, RenderingDevice::FramebufferFormatID p_framebuffer_Format, RenderList::Element **p_elements, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0);
_FORCE_INLINE_ void _add_geometry(InstanceBase *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
_FORCE_INLINE_ void _add_geometry_with_material(InstanceBase *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
_FORCE_INLINE_ void _add_geometry(GeometryInstanceForward *p_instance, uint32_t p_surface, RID p_material, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
_FORCE_INLINE_ void _add_geometry_with_material(GeometryInstanceForward *p_instance, uint32_t p_surface, MaterialData *p_material, RID p_material_rid, PassMode p_pass_mode, uint32_t p_geometry_index, bool p_using_sdfgi = false);
void _fill_render_list(const PagedArray<InstanceBase *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false);
void _fill_render_list(const PagedArray<GeometryInstance *> &p_instances, PassMode p_pass_mode, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform, bool p_using_sdfgi = false);
Map<Size2i, RID> sdfgi_framebuffer_size_cache;
struct GeometryInstanceForward : public GeometryInstance {
RID base;
RS::InstanceType base_type;
RID skeleton;
RID mesh_instance;
uint32_t layer_mask = 1;
float depth = 0;
int depth_layer = 0;
RID gi_probe_instances[MAX_GI_PROBES];
uint32_t gi_probe_instance_count = 0;
Vector<RID> surface_materials;
RID material_override;
Transform transform;
AABB aabb;
AABB transformed_aabb;
float lod_bias = 0.0;
int32_t shader_parameters_offset = -1;
bool use_dynamic_gi = false;
bool use_baked_light = false;
bool cast_double_sided_shaodows = false;
bool mirror = false;
RID lightmap_instance;
Rect2 lightmap_uv_scale;
uint32_t lightmap_slice_index = 0;
Color *lightmap_sh = nullptr;
};
PagedAllocator<GeometryInstanceForward> geometry_instance_alloc;
bool low_end = false;
protected:
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
virtual void _render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &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_lod_threshold = 0.0);
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
virtual void _render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances);
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_bg_color, float p_lod_threshold);
virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &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_lod_threshold = 0.0);
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture);
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances);
public:
virtual GeometryInstance *geometry_instance_create(RID p_base);
virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton);
virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override);
virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_materials);
virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance);
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabb);
virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask);
virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias);
virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable);
virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable);
virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index);
virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9);
virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset);
virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable);
virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance);
virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance);
virtual void geometry_instance_free(GeometryInstance *p_geometry_instance);
virtual uint32_t geometry_instance_get_pair_mask();
virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count);
virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count);
virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count);
virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count);
virtual void set_time(double p_time, double p_step);
virtual bool free(RID p_rid);

View file

@ -4035,6 +4035,19 @@ void RendererSceneRenderRD::decal_instance_set_transform(RID p_decal, const Tran
/////////////////////////////////
RID RendererSceneRenderRD::lightmap_instance_create(RID p_lightmap) {
LightmapInstance li;
li.lightmap = p_lightmap;
return lightmap_instance_owner.make_rid(li);
}
void RendererSceneRenderRD::lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) {
LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap);
ERR_FAIL_COND(!li);
li->transform = p_transform;
}
/////////////////////////////////
RID RendererSceneRenderRD::gi_probe_instance_create(RID p_base) {
GIProbeInstance gi_probe;
gi_probe.probe = p_base;
@ -4061,7 +4074,7 @@ bool RendererSceneRenderRD::gi_probe_needs_update(RID p_probe) const {
return gi_probe->last_probe_version != storage->gi_probe_get_version(gi_probe->probe);
}
void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<InstanceBase *> &p_dynamic_objects) {
void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) {
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_probe);
ERR_FAIL_COND(!gi_probe);
@ -4578,13 +4591,10 @@ void RendererSceneRenderRD::gi_probe_update(RID p_probe, bool p_update_light_ins
//this could probably be better parallelized in compute..
for (int i = 0; i < (int)p_dynamic_objects.size(); i++) {
InstanceBase *instance = p_dynamic_objects[i];
//not used, so clear
instance->depth_layer = 0;
instance->depth = 0;
GeometryInstance *instance = p_dynamic_objects[i];
//transform aabb to giprobe
AABB aabb = (to_probe_xform * instance->transform).xform(instance->aabb);
AABB aabb = (to_probe_xform * geometry_instance_get_transform(instance)).xform(geometry_instance_get_aabb(instance));
//this needs to wrap to grid resolution to avoid jitter
//also extend margin a bit just in case
@ -7101,7 +7111,7 @@ void RendererSceneRenderRD::_update_volumetric_fog(RID p_render_buffers, RID p_e
RD::get_singleton()->compute_list_end();
}
void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) {
Color clear_color;
if (p_render_buffers.is_valid()) {
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
@ -7177,7 +7187,7 @@ void RendererSceneRenderRD::render_scene(RID p_render_buffers, const Transform &
}
}
void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane, float p_lod_distance_multiplier, float p_screen_lod_threshold) {
LightInstance *light_instance = light_instance_owner.getornull(p_light);
ERR_FAIL_COND(!light_instance);
@ -7353,11 +7363,11 @@ void RendererSceneRenderRD::render_shadow(RID p_light, RID p_shadow_atlas, int p
}
}
void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
void RendererSceneRenderRD::render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) {
_render_material(p_cam_transform, p_cam_projection, p_cam_ortogonal, p_instances, p_framebuffer, p_region);
}
void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances) {
void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) {
//print_line("rendering region " + itos(p_region));
RenderBuffers *rb = render_buffers_owner.getornull(p_render_buffers);
ERR_FAIL_COND(!rb);
@ -7694,7 +7704,7 @@ void RendererSceneRenderRD::render_sdfgi(RID p_render_buffers, int p_region, con
}
}
void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances) {
void RendererSceneRenderRD::render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) {
ERR_FAIL_COND(!storage->particles_collision_is_heightfield(p_collider));
Vector3 extents = storage->particles_collision_get_extents(p_collider) * p_transform.basis.get_scale();
CameraMatrix cm;
@ -7844,6 +7854,8 @@ bool RendererSceneRenderRD::free(RID p_rid) {
reflection_probe_instance_owner.free(p_rid);
} else if (decal_instance_owner.owns(p_rid)) {
decal_instance_owner.free(p_rid);
} else if (lightmap_instance_owner.owns(p_rid)) {
lightmap_instance_owner.free(p_rid);
} else if (gi_probe_instance_owner.owns(p_rid)) {
GIProbeInstance *gi_probe = gi_probe_instance_owner.getornull(p_rid);
if (gi_probe->texture.is_valid()) {
@ -7979,23 +7991,28 @@ TypedArray<Image> RendererSceneRenderRD::bake_render_uv2(RID p_base, const Vecto
//RID sampled_light;
InstanceBase ins;
GeometryInstance *gi = geometry_instance_create(p_base);
ins.base_type = RSG::storage->get_base_type(p_base);
ins.base = p_base;
ins.materials.resize(RSG::storage->mesh_get_surface_count(p_base));
for (int i = 0; i < ins.materials.size(); i++) {
if (i < p_material_overrides.size()) {
ins.materials.write[i] = p_material_overrides[i];
uint32_t sc = RSG::storage->mesh_get_surface_count(p_base);
Vector<RID> materials;
materials.resize(sc);
for (uint32_t i = 0; i < sc; i++) {
if (i < (uint32_t)p_material_overrides.size()) {
materials.write[i] = p_material_overrides[i];
}
}
geometry_instance_set_surface_materials(gi, materials);
if (cull_argument.size() == 0) {
cull_argument.push_back(nullptr);
}
cull_argument[0] = &ins;
cull_argument[0] = gi;
_render_uv2(cull_argument, fb, Rect2i(0, 0, p_image_size.width, p_image_size.height));
geometry_instance_free(gi);
TypedArray<Image> ret;
{

View file

@ -109,12 +109,12 @@ protected:
void _setup_reflections(const PagedArray<RID> &p_reflections, const Transform &p_camera_inverse_transform, RID p_environment);
void _setup_giprobes(RID p_render_buffers, const Transform &p_transform, const PagedArray<RID> &p_gi_probes, uint32_t &r_gi_probes_used);
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
virtual void _render_shadow(RID p_framebuffer, const PagedArray<InstanceBase *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void _render_uv2(const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<InstanceBase *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<InstanceBase *> &p_instances) = 0;
virtual void _render_scene(RID p_render_buffer, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, int p_directional_light_count, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, const Color &p_default_color, float p_screen_lod_threshold) = 0;
virtual void _render_shadow(RID p_framebuffer, const PagedArray<GeometryInstance *> &p_instances, const CameraMatrix &p_projection, const Transform &p_transform, float p_zfar, float p_bias, float p_normal_bias, bool p_use_dp, bool use_dp_flip, bool p_use_pancake, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_lod_threshold = 0.0) = 0;
virtual void _render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void _render_uv2(const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void _render_sdfgi(RID p_render_buffers, const Vector3i &p_from, const Vector3i &p_size, const AABB &p_bounds, const PagedArray<GeometryInstance *> &p_instances, const RID &p_albedo_texture, const RID &p_emission_texture, const RID &p_emission_aniso_texture, const RID &p_geom_facing_texture) = 0;
virtual void _render_particle_collider_heightfield(RID p_fb, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, const PagedArray<GeometryInstance *> &p_instances) = 0;
virtual void _debug_giprobe(RID p_gi_probe, RenderingDevice::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform, bool p_lighting, bool p_emission, float p_alpha);
void _debug_sdfgi_probes(RID p_render_buffers, RD::DrawListID p_draw_list, RID p_framebuffer, const CameraMatrix &p_camera_with_transform);
@ -137,8 +137,8 @@ protected:
void _process_gi(RID p_render_buffers, RID p_normal_roughness_buffer, RID p_ambient_buffer, RID p_reflection_buffer, RID p_gi_probe_buffer, RID p_environment, const CameraMatrix &p_projection, const Transform &p_transform, const PagedArray<RID> &p_gi_probes);
// needed for a single argument calls (material and uv2)
PagedArrayPool<InstanceBase *> cull_argument_pool;
PagedArray<InstanceBase *> cull_argument; //need this to exist
PagedArrayPool<GeometryInstance *> cull_argument_pool;
PagedArray<GeometryInstance *> cull_argument; //need this to exist
private:
RS::ViewportDebugDraw debug_draw = RS::VIEWPORT_DEBUG_DRAW_DISABLED;
double time_step = 0;
@ -374,6 +374,15 @@ private:
mutable RID_Owner<DecalInstance> decal_instance_owner;
/* LIGHTMAP INSTANCE */
struct LightmapInstance {
RID lightmap;
Transform transform;
};
mutable RID_Owner<LightmapInstance> lightmap_instance_owner;
/* GIPROBE INSTANCE */
struct GIProbeLight {
@ -1473,6 +1482,9 @@ private:
bool low_end = false;
public:
virtual Transform geometry_instance_get_transform(GeometryInstance *p_instance) = 0;
virtual AABB geometry_instance_get_aabb(GeometryInstance *p_instance) = 0;
/* SHADOW ATLAS API */
RID shadow_atlas_create();
@ -1822,10 +1834,21 @@ public:
return decal->transform;
}
virtual RID lightmap_instance_create(RID p_lightmap);
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform);
_FORCE_INLINE_ RID lightmap_instance_get_lightmap(RID p_lightmap_instance) {
LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
return li->lightmap;
}
_FORCE_INLINE_ Transform lightmap_instance_get_transform(RID p_lightmap_instance) {
LightmapInstance *li = lightmap_instance_owner.getornull(p_lightmap_instance);
return li->transform;
}
RID gi_probe_instance_create(RID p_base);
void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform);
bool gi_probe_needs_update(RID p_probe) const;
void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects);
void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::GeometryInstance *> &p_dynamic_objects);
void gi_probe_set_quality(RS::GIProbeQuality p_quality) { gi_probe_quality = p_quality; }
@ -1900,16 +1923,16 @@ public:
float render_buffers_get_volumetric_fog_end(RID p_render_buffers);
float render_buffers_get_volumetric_fog_detail_spread(RID p_render_buffers);
void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold);
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0);
void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0);
void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region);
void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances);
void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances);
void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_light_cull_result);
void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances);
void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances);
virtual void set_scene_pass(uint64_t p_pass) {
scene_pass = p_pass;

View file

@ -4155,24 +4155,18 @@ RID RendererStorageRD::particles_get_draw_pass_mesh(RID p_particles, int p_pass)
return particles->draw_passes[p_pass];
}
void RendererStorageRD::particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) {
RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance);
void RendererStorageRD::particles_add_collision(RID p_particles, RID p_particles_collision_instance) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
ERR_FAIL_COND(instance->base_type != RS::INSTANCE_PARTICLES_COLLISION);
particles->collisions.insert(instance);
particles->collisions.insert(p_particles_collision_instance);
}
void RendererStorageRD::particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) {
RendererSceneRender::InstanceBase *instance = static_cast<RendererSceneRender::InstanceBase *>(p_instance);
void RendererStorageRD::particles_remove_collision(RID p_particles, RID p_particles_collision_instance) {
Particles *particles = particles_owner.getornull(p_particles);
ERR_FAIL_COND(!particles);
particles->collisions.erase(instance);
particles->collisions.erase(p_particles_collision_instance);
}
void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta) {
@ -4272,9 +4266,15 @@ void RendererStorageRD::_particles_process(Particles *p_particles, float p_delta
to_particles = p_particles->emission_transform.affine_inverse();
}
uint32_t collision_3d_textures_used = 0;
for (const Set<RendererSceneRender::InstanceBase *>::Element *E = p_particles->collisions.front(); E; E = E->next()) {
ParticlesCollision *pc = particles_collision_owner.getornull(E->get()->base);
Transform to_collider = E->get()->transform;
for (const Set<RID>::Element *E = p_particles->collisions.front(); E; E = E->next()) {
ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(E->get());
if (!pci || !pci->active) {
continue;
}
ParticlesCollision *pc = particles_collision_owner.getornull(pci->collision);
ERR_CONTINUE(!pc);
Transform to_collider = pci->transform;
if (p_particles->use_local_coords) {
to_collider = to_particles * to_collider;
}
@ -5096,6 +5096,22 @@ bool RendererStorageRD::particles_collision_is_heightfield(RID p_particles_colli
return particles_collision->type == RS::PARTICLES_COLLISION_TYPE_HEIGHTFIELD_COLLIDE;
}
RID RendererStorageRD::particles_collision_instance_create(RID p_collision) {
ParticlesCollisionInstance pci;
pci.collision = p_collision;
return particles_collision_instance_owner.make_rid(pci);
}
void RendererStorageRD::particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) {
ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance);
ERR_FAIL_COND(!pci);
pci->transform = p_transform;
}
void RendererStorageRD::particles_collision_instance_set_active(RID p_collision_instance, bool p_active) {
ParticlesCollisionInstance *pci = particles_collision_instance_owner.getornull(p_collision_instance);
ERR_FAIL_COND(!pci);
pci->active = p_active;
}
/* SKELETON API */
RID RendererStorageRD::skeleton_create() {
@ -5290,17 +5306,20 @@ RID RendererStorageRD::light_create(RS::LightType p_type) {
light.param[RS::LIGHT_PARAM_SPECULAR] = 0.5;
light.param[RS::LIGHT_PARAM_RANGE] = 1.0;
light.param[RS::LIGHT_PARAM_SIZE] = 0.0;
light.param[RS::LIGHT_PARAM_ATTENUATION] = 1.0;
light.param[RS::LIGHT_PARAM_SPOT_ANGLE] = 45;
light.param[RS::LIGHT_PARAM_SPOT_ATTENUATION] = 1.0;
light.param[RS::LIGHT_PARAM_SHADOW_MAX_DISTANCE] = 0;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_1_OFFSET] = 0.1;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_2_OFFSET] = 0.3;
light.param[RS::LIGHT_PARAM_SHADOW_SPLIT_3_OFFSET] = 0.6;
light.param[RS::LIGHT_PARAM_SHADOW_FADE_START] = 0.8;
light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
light.param[RS::LIGHT_PARAM_SHADOW_NORMAL_BIAS] = 1.0;
light.param[RS::LIGHT_PARAM_SHADOW_BIAS] = 0.02;
light.param[RS::LIGHT_PARAM_SHADOW_BLUR] = 0;
light.param[RS::LIGHT_PARAM_SHADOW_PANCAKE_SIZE] = 20.0;
light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
light.param[RS::LIGHT_PARAM_SHADOW_VOLUMETRIC_FOG_FADE] = 1.0;
light.param[RS::LIGHT_PARAM_TRANSMITTANCE_BIAS] = 0.05;
return light_owner.make_rid(light);
}
@ -8188,6 +8207,8 @@ bool RendererStorageRD::free(RID p_rid) {
}
particles_collision->instance_dependency.instance_notify_deleted(p_rid);
particles_collision_owner.free(p_rid);
} else if (particles_collision_instance_owner.owns(p_rid)) {
particles_collision_instance_owner.free(p_rid);
} else if (render_target_owner.owns(p_rid)) {
RenderTarget *rt = render_target_owner.getornull(p_rid);

View file

@ -734,7 +734,7 @@ private:
ParticleEmissionBuffer *emission_buffer = nullptr;
RID emission_storage_buffer;
Set<RendererSceneRender::InstanceBase *> collisions;
Set<RID> collisions;
Particles() :
inactive(true),
@ -894,6 +894,14 @@ private:
mutable RID_Owner<ParticlesCollision> particles_collision_owner;
struct ParticlesCollisionInstance {
RID collision;
Transform transform;
bool active = false;
};
mutable RID_Owner<ParticlesCollisionInstance> particles_collision_instance_owner;
/* Skeleton */
struct Skeleton {
@ -1977,7 +1985,11 @@ public:
_FORCE_INLINE_ float lightmap_get_probe_capture_update_speed() const {
return lightmap_probe_capture_update_speed;
}
_FORCE_INLINE_ RID lightmap_get_texture(RID p_lightmap) const {
const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
ERR_FAIL_COND_V(!lm, RID());
return lm->light_texture;
}
_FORCE_INLINE_ int32_t lightmap_get_array_index(RID p_lightmap) const {
ERR_FAIL_COND_V(!using_lightmap_array, -1); //only for arrays
const Lightmap *lm = lightmap_owner.getornull(p_lightmap);
@ -2078,8 +2090,8 @@ public:
return particles->particles_transforms_buffer_uniform_set;
}
virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance);
virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance);
virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance);
virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance);
/* PARTICLES COLLISION */
@ -2099,6 +2111,11 @@ public:
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const;
RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const;
//used from 2D and 3D
virtual RID particles_collision_instance_create(RID p_collision);
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform);
virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active);
/* GLOBAL VARIABLES API */
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value);

View file

@ -177,35 +177,33 @@ layout(set = 0, binding = 10, std140) restrict readonly buffer Lightmaps {
}
lightmaps;
layout(set = 0, binding = 11) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
struct LightmapCapture {
vec4 sh[9];
};
layout(set = 0, binding = 12, std140) restrict readonly buffer LightmapCaptures {
layout(set = 0, binding = 11, std140) restrict readonly buffer LightmapCaptures {
LightmapCapture data[];
}
lightmap_captures;
layout(set = 0, binding = 13) uniform texture2D decal_atlas;
layout(set = 0, binding = 14) uniform texture2D decal_atlas_srgb;
layout(set = 0, binding = 12) uniform texture2D decal_atlas;
layout(set = 0, binding = 13) uniform texture2D decal_atlas_srgb;
layout(set = 0, binding = 15, std430) restrict readonly buffer Decals {
layout(set = 0, binding = 14, std430) restrict readonly buffer Decals {
DecalData data[];
}
decals;
layout(set = 0, binding = 16) uniform utexture3D cluster_texture;
layout(set = 0, binding = 15) uniform utexture3D cluster_texture;
layout(set = 0, binding = 17, std430) restrict readonly buffer ClusterData {
layout(set = 0, binding = 16, std430) restrict readonly buffer ClusterData {
uint indices[];
}
cluster_data;
layout(set = 0, binding = 18) uniform texture2D directional_shadow_atlas;
layout(set = 0, binding = 17) uniform texture2D directional_shadow_atlas;
layout(set = 0, binding = 19, std430) restrict readonly buffer GlobalVariableData {
layout(set = 0, binding = 18, std430) restrict readonly buffer GlobalVariableData {
vec4 data[];
}
global_variables;
@ -219,7 +217,7 @@ struct SDFGIProbeCascadeData {
float to_cell; // 1/bounds * grid_size
};
layout(set = 0, binding = 20, std140) uniform SDFGI {
layout(set = 0, binding = 19, std140) uniform SDFGI {
vec3 grid_size;
uint max_cascades;
@ -269,18 +267,20 @@ layout(set = 1, binding = 1) uniform textureCubeArray reflection_atlas;
layout(set = 1, binding = 2) uniform texture2D shadow_atlas;
layout(set = 1, binding = 3) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
#ifndef LOW_END_MODE
layout(set = 1, binding = 3) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
layout(set = 1, binding = 4) uniform texture3D gi_probe_textures[MAX_GI_PROBES];
#endif
/* Set 3, Render Buffers */
#ifdef MODE_RENDER_SDF
layout(r16ui, set = 1, binding = 4) uniform restrict writeonly uimage3D albedo_volume_grid;
layout(r32ui, set = 1, binding = 5) uniform restrict writeonly uimage3D emission_grid;
layout(r32ui, set = 1, binding = 6) uniform restrict writeonly uimage3D emission_aniso_grid;
layout(r32ui, set = 1, binding = 7) uniform restrict uimage3D geom_facing_grid;
layout(r16ui, set = 1, binding = 5) uniform restrict writeonly uimage3D albedo_volume_grid;
layout(r32ui, set = 1, binding = 6) uniform restrict writeonly uimage3D emission_grid;
layout(r32ui, set = 1, binding = 7) uniform restrict writeonly uimage3D emission_aniso_grid;
layout(r32ui, set = 1, binding = 8) uniform restrict uimage3D geom_facing_grid;
//still need to be present for shaders that use it, so remap them to something
#define depth_buffer shadow_atlas
@ -289,17 +289,17 @@ layout(r32ui, set = 1, binding = 7) uniform restrict uimage3D geom_facing_grid;
#else
layout(set = 1, binding = 4) uniform texture2D depth_buffer;
layout(set = 1, binding = 5) uniform texture2D color_buffer;
layout(set = 1, binding = 5) uniform texture2D depth_buffer;
layout(set = 1, binding = 6) uniform texture2D color_buffer;
#ifndef LOW_END_MODE
layout(set = 1, binding = 6) uniform texture2D normal_roughness_buffer;
layout(set = 1, binding = 7) uniform texture2D ao_buffer;
layout(set = 1, binding = 8) uniform texture2D ambient_buffer;
layout(set = 1, binding = 9) uniform texture2D reflection_buffer;
layout(set = 1, binding = 10) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 1, binding = 11) uniform texture3D sdfgi_occlusion_cascades;
layout(set = 1, binding = 7) uniform texture2D normal_roughness_buffer;
layout(set = 1, binding = 8) uniform texture2D ao_buffer;
layout(set = 1, binding = 9) uniform texture2D ambient_buffer;
layout(set = 1, binding = 10) uniform texture2D reflection_buffer;
layout(set = 1, binding = 11) uniform texture2DArray sdfgi_lightprobe_texture;
layout(set = 1, binding = 12) uniform texture3D sdfgi_occlusion_cascades;
struct GIProbeData {
mat4 xform;
@ -317,12 +317,12 @@ struct GIProbeData {
uint mipmaps;
};
layout(set = 1, binding = 12, std140) uniform GIProbes {
layout(set = 1, binding = 13, std140) uniform GIProbes {
GIProbeData data[MAX_GI_PROBES];
}
gi_probes;
layout(set = 1, binding = 13) uniform texture3D volumetric_fog_texture;
layout(set = 1, binding = 14) uniform texture3D volumetric_fog_texture;
#endif // LOW_END_MODE

View file

@ -135,7 +135,7 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY;
}
} else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
} else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@ -147,7 +147,7 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY;
}
} else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
} else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@ -174,7 +174,7 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture
}
} else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
} else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@ -195,7 +195,8 @@ void RendererSceneCull::_instance_pair(Instance *p_A, Instance *p_B) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
gi_probe->lights.insert(A);
} else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
RSG::storage->particles_add_collision(A->base, B);
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
RSG::storage->particles_add_collision(A->base, collision->instance);
}
}
@ -225,7 +226,7 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
idata.flags |= InstanceData::FLAG_GEOM_LIGHTING_DIRTY;
}
} else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
} else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && B->base_type == RS::INSTANCE_REFLECTION_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@ -237,7 +238,7 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
idata.flags |= InstanceData::FLAG_GEOM_REFLECTION_DIRTY;
}
} else if (self->pair_volumes_to_mesh && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
} else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && B->base_type == RS::INSTANCE_DECAL && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceDecalData *decal = static_cast<InstanceDecalData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@ -264,7 +265,7 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
((RendererSceneCull *)self)->_instance_queue_update(A, false, false); //need to update capture
}
} else if (B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
} else if (self->geometry_instance_pair_mask & (1 << RS::INSTANCE_GI_PROBE) && B->base_type == RS::INSTANCE_GI_PROBE && ((1 << A->base_type) & RS::INSTANCE_GEOMETRY_MASK)) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(A->base_data);
@ -284,7 +285,8 @@ void RendererSceneCull::_instance_unpair(Instance *p_A, Instance *p_B) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(B->base_data);
gi_probe->lights.erase(A);
} else if (B->base_type == RS::INSTANCE_PARTICLES_COLLISION && A->base_type == RS::INSTANCE_PARTICLES) {
RSG::storage->particles_remove_collision(A->base, B);
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(B->base_data);
RSG::storage->particles_remove_collision(A->base, collision->instance);
}
}
@ -386,6 +388,9 @@ void RendererSceneCull::_instance_update_mesh_instance(Instance *p_instance) {
p_instance->mesh_instance = RID();
}
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
scene_render->geometry_instance_set_mesh_instance(geom->geometry_instance, p_instance->mesh_instance);
if (p_instance->scenario && p_instance->array_index >= 0) {
InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
if (p_instance->mesh_instance.is_valid()) {
@ -421,6 +426,13 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
}
switch (instance->base_type) {
case RS::INSTANCE_MESH:
case RS::INSTANCE_MULTIMESH:
case RS::INSTANCE_IMMEDIATE:
case RS::INSTANCE_PARTICLES: {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_free(geom->geometry_instance);
} break;
case RS::INSTANCE_LIGHT: {
InstanceLightData *light = static_cast<InstanceLightData *>(instance->base_data);
@ -439,6 +451,10 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
}
scene_render->free(light->instance);
} break;
case RS::INSTANCE_PARTICLES_COLLISION: {
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
RSG::storage->free(collision->instance);
} break;
case RS::INSTANCE_REFLECTION_PROBE: {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(instance->base_data);
scene_render->free(reflection_probe->instance);
@ -457,6 +473,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
while (lightmap_data->users.front()) {
instance_geometry_set_lightmap(lightmap_data->users.front()->get()->self, RID(), Rect2(), 0);
}
scene_render->free(lightmap_data->instance);
} break;
case RS::INSTANCE_GI_PROBE: {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(instance->base_data);
@ -514,7 +531,28 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
case RS::INSTANCE_PARTICLES: {
InstanceGeometryData *geom = memnew(InstanceGeometryData);
instance->base_data = geom;
geom->geometry_instance = scene_render->geometry_instance_create(p_base);
scene_render->geometry_instance_set_skeleton(geom->geometry_instance, instance->skeleton);
scene_render->geometry_instance_set_material_override(geom->geometry_instance, instance->material_override);
scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, instance->materials);
scene_render->geometry_instance_set_transform(geom->geometry_instance, instance->transform, instance->aabb, instance->transformed_aabb);
scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, instance->layer_mask);
scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, instance->lod_bias);
scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, instance->baked_light);
scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, instance->dynamic_gi);
scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, RID(), instance->lightmap_uv_scale, instance->lightmap_slice_index);
if (instance->lightmap_sh.size() == 9) {
scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, instance->lightmap_sh.ptr());
}
} break;
case RS::INSTANCE_PARTICLES_COLLISION: {
InstanceParticlesCollisionData *collision = memnew(InstanceParticlesCollisionData);
collision->instance = RSG::storage->particles_collision_instance_create(p_base);
RSG::storage->particles_collision_instance_set_active(collision->instance, instance->visible);
instance->base_data = collision;
} break;
case RS::INSTANCE_REFLECTION_PROBE: {
InstanceReflectionProbeData *reflection_probe = memnew(InstanceReflectionProbeData);
@ -533,7 +571,7 @@ void RendererSceneCull::instance_set_base(RID p_instance, RID p_base) {
case RS::INSTANCE_LIGHTMAP: {
InstanceLightmapData *lightmap_data = memnew(InstanceLightmapData);
instance->base_data = lightmap_data;
//lightmap_data->instance = scene_render->lightmap_data_instance_create(p_base);
lightmap_data->instance = scene_render->lightmap_instance_create(p_base);
} break;
case RS::INSTANCE_GI_PROBE: {
InstanceGIProbeData *gi_probe = memnew(InstanceGIProbeData);
@ -659,6 +697,11 @@ void RendererSceneCull::instance_set_layer_mask(RID p_instance, uint32_t p_mask)
if (instance->scenario && instance->array_index >= 0) {
instance->scenario->instance_data[instance->array_index].layer_mask = p_mask;
}
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_set_layer_mask(geom->geometry_instance, p_mask);
}
}
void RendererSceneCull::instance_set_transform(RID p_instance, const Transform &p_transform) {
@ -739,6 +782,11 @@ void RendererSceneCull::instance_set_visible(RID p_instance, bool p_visible) {
} else if (instance->indexer_id.is_valid()) {
_unpair_instance(instance);
}
if (instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(instance->base_data);
RSG::storage->particles_collision_instance_set_active(collision->instance, p_visible);
}
}
inline bool is_geometry_instance(RenderingServer::InstanceType p_type) {
@ -785,9 +833,14 @@ void RendererSceneCull::instance_attach_skeleton(RID p_instance, RID p_skeleton)
RSG::storage->skeleton_update_dependency(p_skeleton, instance);
}
_instance_update_mesh_instance(instance);
_instance_queue_update(instance, true, true);
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
_instance_update_mesh_instance(instance);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_set_skeleton(geom->geometry_instance, p_skeleton);
}
}
void RendererSceneCull::instance_set_exterior(RID p_instance, bool p_enabled) {
@ -892,6 +945,11 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF
}
}
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_set_use_baked_light(geom->geometry_instance, p_enabled);
}
} break;
case RS::INSTANCE_FLAG_USE_DYNAMIC_GI: {
if (p_enabled == instance->dynamic_gi) {
@ -907,6 +965,11 @@ void RendererSceneCull::instance_geometry_set_flag(RID p_instance, RS::InstanceF
//once out of octree, can be changed
instance->dynamic_gi = p_enabled;
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_set_use_dynamic_gi(geom->geometry_instance, p_enabled);
}
} break;
case RS::INSTANCE_FLAG_DRAW_NEXT_FRAME_IF_VISIBLE: {
instance->redraw_if_visible = p_enabled;
@ -948,6 +1011,11 @@ void RendererSceneCull::instance_geometry_set_cast_shadows_setting(RID p_instanc
}
}
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_set_cast_double_sided_shadows(geom->geometry_instance, instance->cast_shadows == RS::SHADOW_CASTING_SETTING_DOUBLE_SIDED);
}
_instance_queue_update(instance, false, true);
}
@ -957,6 +1025,11 @@ void RendererSceneCull::instance_geometry_set_material_override(RID p_instance,
instance->material_override = p_material;
_instance_queue_update(instance, false, true);
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_set_material_override(geom->geometry_instance, p_material);
}
}
void RendererSceneCull::instance_geometry_set_draw_range(RID p_instance, float p_min, float p_max, float p_min_margin, float p_max_margin) {
@ -981,9 +1054,17 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig
instance->lightmap_uv_scale = p_lightmap_uv_scale;
instance->lightmap_slice_index = p_slice_index;
RID lightmap_instance_rid;
if (lightmap_instance) {
InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(lightmap_instance->base_data);
lightmap_data->users.insert(instance);
lightmap_instance_rid = lightmap_data->instance;
}
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_set_use_lightmap(geom->geometry_instance, lightmap_instance_rid, p_lightmap_uv_scale, p_slice_index);
}
}
@ -992,16 +1073,21 @@ void RendererSceneCull::instance_geometry_set_lod_bias(RID p_instance, float p_l
ERR_FAIL_COND(!instance);
instance->lod_bias = p_lod_bias;
if ((1 << instance->base_type) & RS::INSTANCE_GEOMETRY_MASK && instance->base_data) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
scene_render->geometry_instance_set_lod_bias(geom->geometry_instance, p_lod_bias);
}
}
void RendererSceneCull::instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value) {
Instance *instance = instance_owner.getornull(p_instance);
ERR_FAIL_COND(!instance);
Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter);
Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.find(p_parameter);
if (!E) {
RendererSceneRender::InstanceBase::InstanceShaderParameter isp;
Instance::InstanceShaderParameter isp;
isp.index = -1;
isp.info = PropertyInfo();
isp.value = p_value;
@ -1042,7 +1128,7 @@ void RendererSceneCull::instance_geometry_get_shader_parameter_list(RID p_instan
const_cast<RendererSceneCull *>(this)->update_dirty_instances();
Vector<StringName> names;
for (Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) {
for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = instance->instance_shader_parameters.front(); E; E = E->next()) {
names.push_back(E->key());
}
names.sort_custom<StringName::AlphCompare>();
@ -1079,9 +1165,7 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
if (light->max_sdfgi_cascade != max_sdfgi_cascade) {
light->max_sdfgi_cascade = max_sdfgi_cascade; //should most likely make sdfgi dirty in scenario
}
}
if (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE) {
} 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);
@ -1090,35 +1174,49 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
InstanceData &idata = p_instance->scenario->instance_data[p_instance->array_index];
idata.flags |= InstanceData::FLAG_REFLECTION_PROBE_DIRTY;
}
}
if (p_instance->base_type == RS::INSTANCE_DECAL) {
} 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);
}
} else if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
InstanceLightmapData *lightmap = static_cast<InstanceLightmapData *>(p_instance->base_data);
if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
scene_render->lightmap_instance_set_transform(lightmap->instance, p_instance->transform);
} else if (p_instance->base_type == RS::INSTANCE_GI_PROBE) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(p_instance->base_data);
scene_render->gi_probe_instance_set_transform_to_data(gi_probe->probe_instance, p_instance->transform);
}
if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES) {
RSG::storage->particles_set_emission_transform(p_instance->base, p_instance->transform);
}
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
InstanceParticlesCollisionData *collision = static_cast<InstanceParticlesCollisionData *>(p_instance->base_data);
if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
//remove materials no longer used and un-own them
if (RSG::storage->particles_collision_is_heightfield(p_instance->base)) {
heightfield_particle_colliders_update_list.insert(p_instance);
}
RSG::storage->particles_collision_instance_set_transform(collision->instance, p_instance->transform);
}
if (p_instance->aabb.has_no_surface()) {
return;
}
if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
//if this moved, update the captured objects
InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data);
//erase dependencies, since no longer a lightmap
for (Set<Instance *>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) {
Instance *geom = E->get();
_instance_queue_update(geom, true, false);
}
}
AABB new_aabb;
new_aabb = p_instance->transform.xform(p_instance->aabb);
p_instance->transformed_aabb = new_aabb;
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
//make sure lights are updated if it casts shadow
@ -1137,29 +1235,13 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
if (!p_instance->lightmap_sh.is_empty()) {
p_instance->lightmap_sh.clear(); //don't need SH
p_instance->lightmap_target_sh.clear(); //don't need SH
scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, nullptr);
}
}
scene_render->geometry_instance_set_transform(geom->geometry_instance, p_instance->transform, p_instance->aabb, p_instance->transformed_aabb);
}
if (p_instance->base_type == RS::INSTANCE_LIGHTMAP) {
//if this moved, update the captured objects
InstanceLightmapData *lightmap_data = static_cast<InstanceLightmapData *>(p_instance->base_data);
//erase dependencies, since no longer a lightmap
for (Set<Instance *>::Element *E = lightmap_data->geometries.front(); E; E = E->next()) {
Instance *geom = E->get();
_instance_queue_update(geom, true, false);
}
}
p_instance->mirror = p_instance->transform.basis.determinant() < 0.0;
AABB new_aabb;
new_aabb = p_instance->transform.xform(p_instance->aabb);
p_instance->transformed_aabb = new_aabb;
if (p_instance->scenario == nullptr || !p_instance->visible || Math::is_zero_approx(p_instance->transform.basis.determinant())) {
p_instance->prev_transformed_aabb = p_instance->transformed_aabb;
return;
@ -1195,17 +1277,26 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
idata.flags = p_instance->base_type; //changing it means de-indexing, so this never needs to be changed later
idata.base_rid = p_instance->base;
switch (p_instance->base_type) {
case RS::INSTANCE_MESH:
case RS::INSTANCE_MULTIMESH:
case RS::INSTANCE_IMMEDIATE:
case RS::INSTANCE_PARTICLES: {
idata.instance_geometry = static_cast<InstanceGeometryData *>(p_instance->base_data)->geometry_instance;
} break;
case RS::INSTANCE_LIGHT: {
idata.instance_data_rid = static_cast<InstanceLightData *>(p_instance->base_data)->instance;
idata.instance_data_rid = static_cast<InstanceLightData *>(p_instance->base_data)->instance.get_id();
} break;
case RS::INSTANCE_REFLECTION_PROBE: {
idata.instance_data_rid = static_cast<InstanceReflectionProbeData *>(p_instance->base_data)->instance;
idata.instance_data_rid = static_cast<InstanceReflectionProbeData *>(p_instance->base_data)->instance.get_id();
} break;
case RS::INSTANCE_DECAL: {
idata.instance_data_rid = static_cast<InstanceDecalData *>(p_instance->base_data)->instance;
idata.instance_data_rid = static_cast<InstanceDecalData *>(p_instance->base_data)->instance.get_id();
} break;
case RS::INSTANCE_LIGHTMAP: {
idata.instance_data_rid = static_cast<InstanceLightmapData *>(p_instance->base_data)->instance.get_id();
} break;
case RS::INSTANCE_GI_PROBE: {
idata.instance_data_rid = static_cast<InstanceGIProbeData *>(p_instance->base_data)->probe_instance;
idata.instance_data_rid = static_cast<InstanceGIProbeData *>(p_instance->base_data)->probe_instance.get_id();
} break;
default: {
}
@ -1258,10 +1349,8 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
pair.pair_mask |= 1 << RS::INSTANCE_GI_PROBE;
pair.pair_mask |= 1 << RS::INSTANCE_LIGHTMAP;
if (pair_volumes_to_mesh) {
pair.pair_mask |= 1 << RS::INSTANCE_DECAL;
pair.pair_mask |= 1 << RS::INSTANCE_REFLECTION_PROBE;
}
pair.pair_mask |= geometry_instance_pair_mask;
pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
} else if (p_instance->base_type == RS::INSTANCE_LIGHT) {
pair.pair_mask |= RS::INSTANCE_GEOMETRY_MASK;
@ -1271,7 +1360,10 @@ void RendererSceneCull::_update_instance(Instance *p_instance) {
pair.pair_mask |= (1 << RS::INSTANCE_GI_PROBE);
pair.bvh2 = &p_instance->scenario->indexers[Scenario::INDEXER_VOLUMES];
}
} else if (pair_volumes_to_mesh && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE || p_instance->base_type == RS::INSTANCE_DECAL)) {
} else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (p_instance->base_type == RS::INSTANCE_REFLECTION_PROBE)) {
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
} else if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (p_instance->base_type == RS::INSTANCE_DECAL)) {
pair.pair_mask = RS::INSTANCE_GEOMETRY_MASK;
pair.bvh = &p_instance->scenario->indexers[Scenario::INDEXER_GEOMETRY];
} else if (p_instance->base_type == RS::INSTANCE_PARTICLES_COLLISION) {
@ -1325,10 +1417,12 @@ void RendererSceneCull::_unpair_instance(Instance *p_instance) {
p_instance->array_index = -1;
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
// Clear these now because the InstanceData containing the dirty flags is gone
p_instance->light_instances.clear();
p_instance->reflection_probe_instances.clear();
//p_instance->decal_instances.clear(); will implement later
p_instance->gi_probe_instances.clear();
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, nullptr, 0);
scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, nullptr, 0);
scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, nullptr, 0);
scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, nullptr, 0);
}
}
@ -1486,6 +1580,8 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance)
}
}
}
scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, p_instance->lightmap_sh.ptr());
}
void RendererSceneCull::_light_instance_setup_directional_shadow(int p_shadow_index, Instance *p_instance, const Transform p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_orthogonal, bool p_cam_vaspect) {
@ -1849,7 +1945,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
}
}
geometry_instances_to_shadow_render.push_back(instance);
geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
}
RSG::storage->update_mesh_instances();
@ -1922,7 +2018,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
}
}
geometry_instances_to_shadow_render.push_back(instance);
geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
}
RSG::storage->update_mesh_instances();
@ -1980,7 +2076,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
RSG::storage->mesh_instance_check_for_update(instance->mesh_instance);
}
}
geometry_instances_to_shadow_render.push_back(instance);
geometry_instances_to_shadow_render.push_back(static_cast<InstanceGeometryData *>(instance->base_data)->geometry_instance);
}
RSG::storage->update_mesh_instances();
@ -2257,6 +2353,8 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
uint32_t sdfgi_last_light_index = 0xFFFFFFFF;
uint32_t sdfgi_last_light_cascade = 0xFFFFFFFF;
RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
for (uint64_t i = 0; i < cull_count; i++) {
bool mesh_visible = false;
@ -2268,16 +2366,16 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
//failure
} else if (base_type == RS::INSTANCE_LIGHT) {
light_cull_result.push_back(idata.instance);
light_instance_cull_result.push_back(idata.instance_data_rid);
light_instance_cull_result.push_back(RID::from_uint64(idata.instance_data_rid));
if (p_shadow_atlas.is_valid() && RSG::storage->light_has_shadow(idata.base_rid)) {
scene_render->light_instance_mark_visible(idata.instance_data_rid); //mark it visible for shadow allocation later
scene_render->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 (render_reflection_probe != idata.instance) {
//avoid entering The Matrix
if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || scene_render->reflection_probe_instance_needs_redraw(idata.instance_data_rid)) {
if ((idata.flags & InstanceData::FLAG_REFLECTION_PROBE_DIRTY) || scene_render->reflection_probe_instance_needs_redraw(RID::from_uint64(idata.instance_data_rid))) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(idata.instance->base_data);
cull.lock.lock();
if (!reflection_probe->update_list.in_list()) {
@ -2289,12 +2387,12 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
idata.flags &= ~uint32_t(InstanceData::FLAG_REFLECTION_PROBE_DIRTY);
}
if (scene_render->reflection_probe_instance_has_reflection(idata.instance_data_rid)) {
reflection_probe_instance_cull_result.push_back(idata.instance_data_rid);
if (scene_render->reflection_probe_instance_has_reflection(RID::from_uint64(idata.instance_data_rid))) {
reflection_probe_instance_cull_result.push_back(RID::from_uint64(idata.instance_data_rid));
}
}
} else if (base_type == RS::INSTANCE_DECAL) {
decal_instance_cull_result.push_back(idata.instance_data_rid);
decal_instance_cull_result.push_back(RID::from_uint64(idata.instance_data_rid));
} else if (base_type == RS::INSTANCE_GI_PROBE) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(idata.instance->base_data);
@ -2303,10 +2401,10 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
gi_probe_update_list.add(&gi_probe->update_element);
}
cull.lock.unlock();
gi_probe_instance_cull_result.push_back(idata.instance_data_rid);
gi_probe_instance_cull_result.push_back(RID::from_uint64(idata.instance_data_rid));
} else if (base_type == RS::INSTANCE_LIGHTMAP) {
lightmap_cull_result.push_back(idata.instance);
lightmap_cull_result.push_back(RID::from_uint64(idata.instance_data_rid));
} else if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && !(idata.flags & InstanceData::FLAG_CAST_SHADOWS_ONLY)) {
bool keep = true;
@ -2331,68 +2429,83 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
}
}
if (pair_volumes_to_mesh && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) {
if (geometry_instance_pair_mask & (1 << RS::INSTANCE_LIGHT) && (idata.flags & InstanceData::FLAG_GEOM_LIGHTING_DIRTY)) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
int l = 0;
//only called when lights AABB enter/exit this geometry
idata.instance->light_instances.resize(geom->lights.size());
uint32_t idx = 0;
for (Set<Instance *>::Element *E = geom->lights.front(); E; E = E->next()) {
InstanceLightData *light = static_cast<InstanceLightData *>(E->get()->base_data);
idata.instance->light_instances.write[l++] = light->instance;
instance_pair_buffer[idx++] = light->instance;
if (idx == MAX_INSTANCE_PAIRS) {
break;
}
}
scene_render->geometry_instance_pair_light_instances(geom->geometry_instance, instance_pair_buffer, idx);
idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_LIGHTING_DIRTY);
}
if (pair_volumes_to_mesh && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) {
if (geometry_instance_pair_mask & (1 << RS::INSTANCE_REFLECTION_PROBE) && (idata.flags & InstanceData::FLAG_GEOM_REFLECTION_DIRTY)) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
int l = 0;
//only called when reflection probe AABB enter/exit this geometry
idata.instance->reflection_probe_instances.resize(geom->reflection_probes.size());
uint32_t idx = 0;
for (Set<Instance *>::Element *E = geom->reflection_probes.front(); E; E = E->next()) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
idata.instance->reflection_probe_instances.write[l++] = reflection_probe->instance;
instance_pair_buffer[idx++] = reflection_probe->instance;
if (idx == MAX_INSTANCE_PAIRS) {
break;
}
}
scene_render->geometry_instance_pair_reflection_probe_instances(geom->geometry_instance, instance_pair_buffer, idx);
idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_REFLECTION_DIRTY);
}
if (pair_volumes_to_mesh && (idata.flags & InstanceData::FLAG_GEOM_DECAL_DIRTY)) {
if (geometry_instance_pair_mask & (1 << RS::INSTANCE_DECAL) && (idata.flags & InstanceData::FLAG_GEOM_DECAL_DIRTY)) {
//InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
//todo for GLES3
idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_DECAL_DIRTY);
/*for (Set<Instance *>::Element *E = geom->dec.front(); E; E = E->next()) {
InstanceReflectionProbeData *reflection_probe = static_cast<InstanceReflectionProbeData *>(E->get()->base_data);
instance_pair_buffer[idx++] = reflection_probe->instance;
if (idx==MAX_INSTANCE_PAIRS) {
break;
}
}*/
//scene_render->geometry_instance_pair_decal_instances(geom->geometry_instance, light_instances, idx);
}
if (idata.flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
int l = 0;
//only called when reflection probe AABB enter/exit this geometry
idata.instance->gi_probe_instances.resize(geom->gi_probes.size());
uint32_t idx = 0;
for (Set<Instance *>::Element *E = geom->gi_probes.front(); E; E = E->next()) {
InstanceGIProbeData *gi_probe = static_cast<InstanceGIProbeData *>(E->get()->base_data);
idata.instance->gi_probe_instances.write[l++] = gi_probe->probe_instance;
instance_pair_buffer[idx++] = gi_probe->probe_instance;
if (idx == MAX_INSTANCE_PAIRS) {
break;
}
}
scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx);
idata.flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY);
}
if ((idata.flags & InstanceData::FLAG_LIGHTMAP_CAPTURE) && idata.instance->last_frame_pass != frame_number && !idata.instance->lightmap_target_sh.is_empty() && !idata.instance->lightmap_sh.is_empty()) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(idata.instance->base_data);
Color *sh = idata.instance->lightmap_sh.ptrw();
const Color *target_sh = idata.instance->lightmap_target_sh.ptr();
for (uint32_t j = 0; j < 9; j++) {
sh[j] = sh[j].lerp(target_sh[j], MIN(1.0, lightmap_probe_update_speed));
}
scene_render->geometry_instance_set_lightmap_capture(geom->geometry_instance, sh);
idata.instance->last_frame_pass = frame_number;
}
if (keep) {
geometry_instances_to_render.push_back(idata.instance);
geometry_instances_to_render.push_back(idata.instance_geometry);
}
}
}
@ -2404,7 +2517,7 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
uint32_t base_type = idata.flags & InstanceData::FLAG_BASE_TYPE_MASK;
if (((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) && idata.flags & InstanceData::FLAG_CAST_SHADOWS) {
cull.shadows[j].cascades[k].cull_result.push_back(idata.instance);
cull.shadows[j].cascades[k].cull_result.push_back(idata.instance_geometry);
mesh_visible = true;
}
}
@ -2427,7 +2540,7 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
}
} else if ((1 << base_type) & RS::INSTANCE_GEOMETRY_MASK) {
if (idata.flags & InstanceData::FLAG_USES_BAKED_LIGHT) {
cull.sdfgi.region_cull_result[j].push_back(idata.instance);
cull.sdfgi.region_cull_result[j].push_back(idata.instance_geometry);
mesh_visible = true;
}
}
@ -2654,7 +2767,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario,
environment = scenario->fallback_environment;
}
RENDER_TIMESTAMP("Render Empty Scene ");
scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::InstanceBase *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RendererSceneRender::InstanceBase *>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0);
scene_render->render_scene(p_render_buffers, Transform(), CameraMatrix(), true, PagedArray<RendererSceneRender::GeometryInstance *>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), PagedArray<RID>(), RID(), RID(), p_shadow_atlas, scenario->reflection_atlas, RID(), 0, 0);
#endif
}
@ -2931,6 +3044,8 @@ void RendererSceneCull::render_probes() {
geometry_instances_to_render.clear();
RID instance_pair_buffer[MAX_INSTANCE_PAIRS];
for (Set<Instance *>::Element *E = probe->dynamic_geometries.front(); E; E = E->next()) {
Instance *ins = E->get();
if (!ins->visible) {
@ -2939,21 +3054,22 @@ void RendererSceneCull::render_probes() {
InstanceGeometryData *geom = (InstanceGeometryData *)ins->base_data;
if (ins->scenario && ins->array_index >= 0 && (ins->scenario->instance_data[ins->array_index].flags & InstanceData::FLAG_GEOM_GI_PROBE_DIRTY)) {
//giprobes may be dirty, so update
int l = 0;
//only called when reflection probe AABB enter/exit this geometry
ins->gi_probe_instances.resize(geom->gi_probes.size());
uint32_t idx = 0;
for (Set<Instance *>::Element *F = geom->gi_probes.front(); F; F = F->next()) {
InstanceGIProbeData *gi_probe2 = static_cast<InstanceGIProbeData *>(F->get()->base_data);
ins->gi_probe_instances.write[l++] = gi_probe2->probe_instance;
instance_pair_buffer[idx++] = gi_probe2->probe_instance;
if (idx == MAX_INSTANCE_PAIRS) {
break;
}
}
scene_render->geometry_instance_pair_gi_probe_instances(geom->geometry_instance, instance_pair_buffer, idx);
ins->scenario->instance_data[ins->array_index].flags &= ~uint32_t(InstanceData::FLAG_GEOM_GI_PROBE_DIRTY);
}
geometry_instances_to_render.push_back(E->get());
geometry_instances_to_render.push_back(geom->geometry_instance);
}
scene_render->gi_probe_update(probe->probe_instance, update_lights, probe->light_instances, geometry_instances_to_render);
@ -2992,7 +3108,8 @@ void RendererSceneCull::render_particle_colliders() {
if (!instance || !((1 << instance->base_type) & (RS::INSTANCE_GEOMETRY_MASK & (~(1 << RS::INSTANCE_PARTICLES))))) { //all but particles to avoid self collision
continue;
}
geometry_instances_to_render.push_back(instance);
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(instance->base_data);
geometry_instances_to_render.push_back(geom->geometry_instance);
}
scene_render->render_particle_collider_heightfield(hfpc->base, hfpc->transform, geometry_instances_to_render);
@ -3001,7 +3118,7 @@ void RendererSceneCull::render_particle_colliders() {
}
}
void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material) {
void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material) {
List<RendererStorage::InstanceShaderParam> plist;
RSG::storage->material_get_instance_shader_parameters(p_material, &plist);
for (List<RendererStorage::InstanceShaderParam>::Element *E = plist.front(); E; E = E->next()) {
@ -3016,7 +3133,7 @@ void RendererSceneCull::_update_instance_shader_parameters_from_material(Map<Str
continue; //first one found always has priority
}
RendererSceneRender::InstanceBase::InstanceShaderParameter isp;
Instance::InstanceShaderParameter isp;
isp.index = E->get().index;
isp.info = E->get().info;
isp.default_value = E->get().default_value;
@ -3059,7 +3176,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
bool can_cast_shadows = true;
bool is_animated = false;
Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> isparams;
Map<StringName, Instance::InstanceShaderParameter> isparams;
if (p_instance->cast_shadows == RS::SHADOW_CASTING_SETTING_OFF) {
can_cast_shadows = false;
@ -3210,7 +3327,9 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
p_instance->instance_allocated_shader_parameters = (p_instance->instance_shader_parameters.size() > 0);
if (p_instance->instance_allocated_shader_parameters) {
p_instance->instance_allocated_shader_parameters_offset = RSG::storage->global_variables_instance_allocate(p_instance->self);
for (Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) {
scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, p_instance->instance_allocated_shader_parameters_offset);
for (Map<StringName, Instance::InstanceShaderParameter>::Element *E = p_instance->instance_shader_parameters.front(); E; E = E->next()) {
if (E->get().value.get_type() != Variant::NIL) {
RSG::storage->global_variables_instance_update(p_instance->self, E->get().index, E->get().value);
}
@ -3218,6 +3337,7 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
} else {
RSG::storage->global_variables_instance_free(p_instance->self);
p_instance->instance_allocated_shader_parameters_offset = -1;
scene_render->geometry_instance_set_instance_shader_parameters_offset(geom->geometry_instance, -1);
}
}
}
@ -3227,6 +3347,11 @@ void RendererSceneCull::_update_dirty_instance(Instance *p_instance) {
}
p_instance->clean_up_dependencies();
if ((1 << p_instance->base_type) & RS::INSTANCE_GEOMETRY_MASK) {
InstanceGeometryData *geom = static_cast<InstanceGeometryData *>(p_instance->base_data);
scene_render->geometry_instance_set_surface_materials(geom->geometry_instance, p_instance->materials);
}
}
_instance_update_list.remove(&p_instance->update_item);
@ -3322,21 +3447,24 @@ TypedArray<Image> RendererSceneCull::bake_render_uv2(RID p_base, const Vector<RI
RendererSceneCull *RendererSceneCull::singleton = nullptr;
void RendererSceneCull::set_scene_render(RendererSceneRender *p_scene_render) {
scene_render = p_scene_render;
geometry_instance_pair_mask = scene_render->geometry_instance_get_pair_mask();
}
RendererSceneCull::RendererSceneCull() {
render_pass = 1;
singleton = this;
pair_volumes_to_mesh = false;
instance_cull_result.set_page_pool(&instance_cull_page_pool);
mesh_instance_cull_result.set_page_pool(&rid_cull_page_pool);
instance_shadow_cull_result.set_page_pool(&instance_cull_page_pool);
instance_sdfgi_cull_result.set_page_pool(&instance_cull_page_pool);
light_cull_result.set_page_pool(&instance_cull_page_pool);
geometry_instances_to_render.set_page_pool(&base_instance_cull_page_pool);
geometry_instances_to_shadow_render.set_page_pool(&base_instance_cull_page_pool);
lightmap_cull_result.set_page_pool(&base_instance_cull_page_pool);
geometry_instances_to_render.set_page_pool(&geometry_instance_cull_page_pool);
geometry_instances_to_shadow_render.set_page_pool(&geometry_instance_cull_page_pool);
lightmap_cull_result.set_page_pool(&rid_cull_page_pool);
reflection_probe_instance_cull_result.set_page_pool(&rid_cull_page_pool);
light_instance_cull_result.set_page_pool(&rid_cull_page_pool);
gi_probe_instance_cull_result.set_page_pool(&rid_cull_page_pool);
@ -3344,12 +3472,12 @@ RendererSceneCull::RendererSceneCull() {
for (int i = 0; i < RendererSceneRender::MAX_DIRECTIONAL_LIGHTS; i++) {
for (int j = 0; j < RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES; j++) {
cull.shadows[i].cascades[j].cull_result.set_page_pool(&base_instance_cull_page_pool);
cull.shadows[i].cascades[j].cull_result.set_page_pool(&geometry_instance_cull_page_pool);
}
}
for (int i = 0; i < SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE; i++) {
cull.sdfgi.region_cull_result[i].set_page_pool(&base_instance_cull_page_pool);
cull.sdfgi.region_cull_result[i].set_page_pool(&geometry_instance_cull_page_pool);
}
for (int i = 0; i < SDFGI_MAX_CASCADES; i++) {
@ -3363,7 +3491,6 @@ RendererSceneCull::~RendererSceneCull() {
instance_cull_result.reset();
mesh_instance_cull_result.reset();
instance_shadow_cull_result.reset();
instance_sdfgi_cull_result.reset();
light_cull_result.reset();
geometry_instances_to_render.reset();

View file

@ -53,7 +53,8 @@ public:
enum {
SDFGI_MAX_CASCADES = 8,
SDFGI_MAX_REGIONS_PER_CASCADE = 3
SDFGI_MAX_REGIONS_PER_CASCADE = 3,
MAX_INSTANCE_PAIRS = 32
};
uint64_t render_pass;
@ -249,7 +250,10 @@ public:
uint32_t flags = 0;
uint32_t layer_mask = 0; //for fast layer-mask discard
RID base_rid;
RID instance_data_rid;
union {
uint64_t instance_data_rid;
RendererSceneRender::GeometryInstance *instance_geometry;
};
Instance *instance = nullptr;
};
@ -296,7 +300,7 @@ public:
static void _instance_pair(Instance *p_A, Instance *p_B);
static void _instance_unpair(Instance *p_A, Instance *p_B);
static void _instance_update_mesh_instance(Instance *p_instance);
void _instance_update_mesh_instance(Instance *p_instance);
virtual RID scenario_create();
@ -325,7 +329,55 @@ public:
virtual ~InstanceBaseData() {}
};
struct Instance : RendererSceneRender::InstanceBase {
struct Instance : public RendererStorage::InstanceBaseDependency {
RS::InstanceType base_type;
RID base;
RID skeleton;
RID material_override;
RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist
Transform transform;
float lod_bias;
Vector<RID> materials;
RS::ShadowCastingSetting cast_shadows;
uint32_t layer_mask;
//fit in 32 bits
bool mirror : 8;
bool receive_shadows : 8;
bool visible : 8;
bool baked_light : 2; //this flag is only to know if it actually did use baked light
bool dynamic_gi : 2; //this flag is only to know if it actually did use baked light
bool redraw_if_visible : 4;
Instance *lightmap;
Rect2 lightmap_uv_scale;
int lightmap_slice_index;
uint32_t lightmap_cull_index;
Vector<Color> lightmap_sh; //spherical harmonic
AABB aabb;
AABB transformed_aabb;
AABB prev_transformed_aabb;
struct InstanceShaderParameter {
int32_t index = -1;
Variant value;
Variant default_value;
PropertyInfo info;
};
Map<StringName, InstanceShaderParameter> instance_shader_parameters;
bool instance_allocated_shader_parameters = false;
int32_t instance_allocated_shader_parameters_offset = -1;
//
RID self;
//scenario stuff
DynamicBVH::ID indexer_id;
@ -377,6 +429,20 @@ public:
Instance() :
scenario_item(this),
update_item(this) {
base_type = RS::INSTANCE_NONE;
cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
receive_shadows = true;
visible = true;
layer_mask = 1;
instance_version = 0;
baked_light = false;
dynamic_gi = false;
redraw_if_visible = false;
lightmap_slice_index = 0;
lightmap = nullptr;
lightmap_cull_index = 0;
lod_bias = 1.0;
scenario = nullptr;
update_aabb = false;
@ -415,6 +481,7 @@ public:
void _instance_queue_update(Instance *p_instance, bool p_update_aabb, bool p_update_dependencies = false);
struct InstanceGeometryData : public InstanceBaseData {
RendererSceneRender::GeometryInstance *geometry_instance = nullptr;
Set<Instance *> lights;
bool can_cast_shadows;
bool material_is_animated;
@ -458,6 +525,10 @@ public:
SelfList<InstanceReflectionProbeData>::List reflection_probe_render_list;
struct InstanceParticlesCollisionData : public InstanceBaseData {
RID instance;
};
struct InstanceLightData : public InstanceBaseData {
RID instance;
uint64_t last_version;
@ -523,6 +594,7 @@ public:
SelfList<InstanceGIProbeData>::List gi_probe_update_list;
struct InstanceLightmapData : public InstanceBaseData {
RID instance;
Set<Instance *> geometries;
Set<Instance *> users;
@ -600,17 +672,16 @@ public:
Set<Instance *> heightfield_particle_colliders_update_list;
PagedArrayPool<Instance *> instance_cull_page_pool;
PagedArrayPool<RendererSceneRender::InstanceBase *> base_instance_cull_page_pool;
PagedArrayPool<RendererSceneRender::GeometryInstance *> geometry_instance_cull_page_pool;
PagedArrayPool<RID> rid_cull_page_pool;
PagedArray<Instance *> instance_cull_result;
PagedArray<RID> mesh_instance_cull_result;
PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_render;
PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances_to_render;
PagedArray<Instance *> instance_shadow_cull_result;
PagedArray<RendererSceneRender::InstanceBase *> geometry_instances_to_shadow_render;
PagedArray<Instance *> instance_sdfgi_cull_result;
PagedArray<RendererSceneRender::GeometryInstance *> geometry_instances_to_shadow_render;
PagedArray<Instance *> light_cull_result;
PagedArray<RendererSceneRender::InstanceBase *> lightmap_cull_result;
PagedArray<RID> lightmap_cull_result;
PagedArray<RID> reflection_probe_instance_cull_result;
PagedArray<RID> light_instance_cull_result;
@ -619,7 +690,7 @@ public:
RID_PtrOwner<Instance> instance_owner;
bool pair_volumes_to_mesh; // used in traditional forward, unnecesary on clustered
uint32_t geometry_instance_pair_mask; // used in traditional forward, unnecesary on clustered
virtual RID instance_create();
@ -653,7 +724,7 @@ public:
virtual void instance_geometry_set_lightmap(RID p_instance, RID p_lightmap, const Rect2 &p_lightmap_uv_scale, int p_slice_index);
virtual void instance_geometry_set_lod_bias(RID p_instance, float p_lod_bias);
void _update_instance_shader_parameters_from_material(Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &isparams, const Map<StringName, RendererSceneRender::InstanceBase::InstanceShaderParameter> &existing_isparams, RID p_material);
void _update_instance_shader_parameters_from_material(Map<StringName, Instance::InstanceShaderParameter> &isparams, const Map<StringName, Instance::InstanceShaderParameter> &existing_isparams, RID p_material);
virtual void instance_geometry_set_shader_parameter(RID p_instance, const StringName &p_parameter, const Variant &p_value);
virtual void instance_geometry_get_shader_parameter_list(RID p_instance, List<PropertyInfo> *p_parameters) const;
@ -687,7 +758,7 @@ public:
real_t range_begin;
Vector2 uv_scale;
PagedArray<RendererSceneRender::InstanceBase *> cull_result;
PagedArray<RendererSceneRender::GeometryInstance *> cull_result;
} cascades[RendererSceneRender::MAX_DIRECTIONAL_LIGHT_CASCADES]; //max 4 cascades
uint32_t cascade_count;
@ -698,7 +769,7 @@ public:
struct SDFGI {
//have arrays here because SDFGI functions expects this, plus regions can have areas
PagedArray<RendererSceneRender::InstanceBase *> region_cull_result[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE];
PagedArray<RendererSceneRender::GeometryInstance *> region_cull_result[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE];
AABB region_aabb[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade
uint32_t region_cascade[SDFGI_MAX_CASCADES * SDFGI_MAX_REGIONS_PER_CASCADE]; //max 3 regions per cascade
uint32_t region_count = 0;
@ -828,6 +899,8 @@ public:
bool free(RID p_rid);
void set_scene_render(RendererSceneRender *p_scene_render);
RendererSceneCull();
virtual ~RendererSceneCull();
};

View file

@ -41,6 +41,34 @@ public:
MAX_DIRECTIONAL_LIGHTS = 8,
MAX_DIRECTIONAL_LIGHT_CASCADES = 4
};
struct GeometryInstance {
virtual ~GeometryInstance() {}
};
virtual GeometryInstance *geometry_instance_create(RID p_base) = 0;
virtual void geometry_instance_set_skeleton(GeometryInstance *p_geometry_instance, RID p_skeleton) = 0;
virtual void geometry_instance_set_material_override(GeometryInstance *p_geometry_instance, RID p_override) = 0;
virtual void geometry_instance_set_surface_materials(GeometryInstance *p_geometry_instance, const Vector<RID> &p_material) = 0;
virtual void geometry_instance_set_mesh_instance(GeometryInstance *p_geometry_instance, RID p_mesh_instance) = 0;
virtual void geometry_instance_set_transform(GeometryInstance *p_geometry_instance, const Transform &p_transform, const AABB &p_aabb, const AABB &p_transformed_aabbb) = 0;
virtual void geometry_instance_set_layer_mask(GeometryInstance *p_geometry_instance, uint32_t p_layer_mask) = 0;
virtual void geometry_instance_set_lod_bias(GeometryInstance *p_geometry_instance, float p_lod_bias) = 0;
virtual void geometry_instance_set_use_baked_light(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
virtual void geometry_instance_set_use_dynamic_gi(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
virtual void geometry_instance_set_use_lightmap(GeometryInstance *p_geometry_instance, RID p_lightmap_instance, const Rect2 &p_lightmap_uv_scale, int p_lightmap_slice_index) = 0;
virtual void geometry_instance_set_lightmap_capture(GeometryInstance *p_geometry_instance, const Color *p_sh9) = 0;
virtual void geometry_instance_set_instance_shader_parameters_offset(GeometryInstance *p_geometry_instance, int32_t p_offset) = 0;
virtual void geometry_instance_set_cast_double_sided_shadows(GeometryInstance *p_geometry_instance, bool p_enable) = 0;
virtual uint32_t geometry_instance_get_pair_mask() = 0;
virtual void geometry_instance_pair_light_instances(GeometryInstance *p_geometry_instance, const RID *p_light_instances, uint32_t p_light_instance_count) = 0;
virtual void geometry_instance_pair_reflection_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_reflection_probe_instances, uint32_t p_reflection_probe_instance_count) = 0;
virtual void geometry_instance_pair_decal_instances(GeometryInstance *p_geometry_instance, const RID *p_decal_instances, uint32_t p_decal_instance_count) = 0;
virtual void geometry_instance_pair_gi_probe_instances(GeometryInstance *p_geometry_instance, const RID *p_gi_probe_instances, uint32_t p_gi_probe_instance_count) = 0;
virtual void geometry_instance_free(GeometryInstance *p_geometry_instance) = 0;
/* SHADOW ATLAS API */
virtual RID
@ -55,8 +83,6 @@ public:
/* SDFGI UPDATE */
struct InstanceBase;
virtual void sdfgi_update(RID p_render_buffers, RID p_environment, const Vector3 &p_world_position) = 0;
virtual int sdfgi_get_pending_region_count(RID p_render_buffers) const = 0;
virtual AABB sdfgi_get_pending_region_bounds(RID p_render_buffers, int p_region) const = 0;
@ -134,83 +160,6 @@ public:
virtual void shadows_quality_set(RS::ShadowQuality p_quality) = 0;
virtual void directional_shadow_quality_set(RS::ShadowQuality p_quality) = 0;
struct InstanceBase : public RendererStorage::InstanceBaseDependency {
RS::InstanceType base_type;
RID base;
RID skeleton;
RID material_override;
RID mesh_instance; //only used for meshes and when skeleton/blendshapes exist
Transform transform;
float lod_bias;
int depth_layer;
uint32_t layer_mask;
//RID sampled_light;
Vector<RID> materials;
Vector<RID> light_instances;
Vector<RID> reflection_probe_instances;
Vector<RID> gi_probe_instances;
RS::ShadowCastingSetting cast_shadows;
//fit in 32 bits
bool mirror : 8;
bool receive_shadows : 8;
bool visible : 8;
bool baked_light : 2; //this flag is only to know if it actually did use baked light
bool dynamic_gi : 2; //this flag is only to know if it actually did use baked light
bool redraw_if_visible : 4;
float depth; //used for sorting
InstanceBase *lightmap;
Rect2 lightmap_uv_scale;
int lightmap_slice_index;
uint32_t lightmap_cull_index;
Vector<Color> lightmap_sh; //spherical harmonic
AABB aabb;
AABB transformed_aabb;
AABB prev_transformed_aabb;
struct InstanceShaderParameter {
int32_t index = -1;
Variant value;
Variant default_value;
PropertyInfo info;
};
Map<StringName, InstanceShaderParameter> instance_shader_parameters;
bool instance_allocated_shader_parameters = false;
int32_t instance_allocated_shader_parameters_offset = -1;
InstanceBase() {
base_type = RS::INSTANCE_NONE;
cast_shadows = RS::SHADOW_CASTING_SETTING_ON;
receive_shadows = true;
visible = true;
depth_layer = 0;
layer_mask = 1;
instance_version = 0;
baked_light = false;
dynamic_gi = false;
redraw_if_visible = false;
lightmap_slice_index = 0;
lightmap = nullptr;
lightmap_cull_index = 0;
lod_bias = 1.0;
}
virtual ~InstanceBase() {
}
};
virtual RID light_instance_create(RID p_light) = 0;
virtual void light_instance_set_transform(RID p_light_instance, const Transform &p_transform) = 0;
virtual void light_instance_set_aabb(RID p_light_instance, const AABB &p_aabb) = 0;
@ -235,20 +184,23 @@ public:
virtual RID decal_instance_create(RID p_decal) = 0;
virtual void decal_instance_set_transform(RID p_decal, const Transform &p_transform) = 0;
virtual RID lightmap_instance_create(RID p_lightmap) = 0;
virtual void lightmap_instance_set_transform(RID p_lightmap, const Transform &p_transform) = 0;
virtual RID gi_probe_instance_create(RID p_gi_probe) = 0;
virtual void gi_probe_instance_set_transform_to_data(RID p_probe, const Transform &p_xform) = 0;
virtual bool gi_probe_needs_update(RID p_probe) const = 0;
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<RendererSceneRender::InstanceBase *> &p_dynamic_objects) = 0;
virtual void gi_probe_update(RID p_probe, bool p_update_light_instances, const Vector<RID> &p_light_instances, const PagedArray<GeometryInstance *> &p_dynamic_objects) = 0;
virtual void gi_probe_set_quality(RS::GIProbeQuality) = 0;
virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<InstanceBase *> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0;
virtual void render_scene(RID p_render_buffers, const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, const PagedArray<RID> &p_lights, const PagedArray<RID> &p_reflection_probes, const PagedArray<RID> &p_gi_probes, const PagedArray<RID> &p_decals, const PagedArray<RID> &p_lightmaps, RID p_environment, RID p_camera_effects, RID p_shadow_atlas, RID p_reflection_atlas, RID p_reflection_probe, int p_reflection_probe_pass, float p_screen_lod_threshold) = 0;
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<InstanceBase *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0;
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<InstanceBase *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<InstanceBase *> &p_instances) = 0;
virtual void render_shadow(RID p_light, RID p_shadow_atlas, int p_pass, const PagedArray<GeometryInstance *> &p_instances, const Plane &p_camera_plane = Plane(), float p_lod_distance_multiplier = 0, float p_screen_lod_threshold = 0.0) = 0;
virtual void render_material(const Transform &p_cam_transform, const CameraMatrix &p_cam_projection, bool p_cam_ortogonal, const PagedArray<GeometryInstance *> &p_instances, RID p_framebuffer, const Rect2i &p_region) = 0;
virtual void render_sdfgi(RID p_render_buffers, int p_region, const PagedArray<GeometryInstance *> &p_instances) = 0;
virtual void render_sdfgi_static_lights(RID p_render_buffers, uint32_t p_cascade_count, const uint32_t *p_cascade_indices, const PagedArray<RID> *p_positional_lights) = 0;
virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<InstanceBase *> &p_instances) = 0;
virtual void render_particle_collider_heightfield(RID p_collider, const Transform &p_transform, const PagedArray<GeometryInstance *> &p_instances) = 0;
virtual void set_scene_pass(uint64_t p_pass) = 0;
virtual void set_time(double p_time, double p_step) = 0;

View file

@ -474,8 +474,8 @@ public:
virtual void particles_set_view_axis(RID p_particles, const Vector3 &p_axis) = 0;
virtual void particles_add_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0;
virtual void particles_remove_collision(RID p_particles, InstanceBaseDependency *p_instance) = 0;
virtual void particles_add_collision(RID p_particles, RID p_particles_collision_instance) = 0;
virtual void particles_remove_collision(RID p_particles, RID p_particles_collision_instance) = 0;
virtual void update_particles() = 0;
@ -496,6 +496,11 @@ public:
virtual bool particles_collision_is_heightfield(RID p_particles_collision) const = 0;
virtual RID particles_collision_get_heightfield_framebuffer(RID p_particles_collision) const = 0;
//used from 2D and 3D
virtual RID particles_collision_instance_create(RID p_collision) = 0;
virtual void particles_collision_instance_set_transform(RID p_collision_instance, const Transform &p_transform) = 0;
virtual void particles_collision_instance_set_active(RID p_collision_instance, bool p_active) = 0;
/* GLOBAL VARIABLES */
virtual void global_variable_add(const StringName &p_name, RS::GlobalVariableType p_type, const Variant &p_value) = 0;

View file

@ -267,7 +267,7 @@ RenderingServerDefault::RenderingServerDefault() {
RSG::rasterizer = RendererCompositor::create();
RSG::storage = RSG::rasterizer->get_storage();
RSG::canvas_render = RSG::rasterizer->get_canvas();
sr->scene_render = RSG::rasterizer->get_scene();
sr->set_scene_render(RSG::rasterizer->get_scene());
frame_profile_frame = 0;