Cleanup and improve sky render

This commit is contained in:
Bastiaan Olij 2022-12-15 22:20:06 +11:00
parent 291add339f
commit e886a7af81
15 changed files with 345 additions and 389 deletions

View file

@ -502,6 +502,10 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
return false;
}
Ref<RenderSceneBuffers> LightStorage::reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) {
return Ref<RenderSceneBuffers>();
}
bool LightStorage::reflection_probe_instance_postprocess_step(RID p_instance) {
return true;
}

View file

@ -366,6 +366,7 @@ public:
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override;
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override;
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override;
virtual Ref<RenderSceneBuffers> reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) override;
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override;
/* LIGHTMAP CAPTURE */

View file

@ -135,6 +135,7 @@ public:
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override { return false; }
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override { return false; }
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override { return false; }
virtual Ref<RenderSceneBuffers> reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) override { return Ref<RenderSceneBuffers>(); }
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override { return true; }
/* LIGHTMAP CAPTURE */

View file

@ -32,16 +32,22 @@
#include "core/config/project_settings.h"
#include "core/math/math_defs.h"
#include "servers/rendering/renderer_rd/effects/copy_effects.h"
#include "servers/rendering/renderer_rd/framebuffer_cache_rd.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
#include "servers/rendering/renderer_rd/renderer_scene_render_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/material_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/renderer_rd/uniform_set_cache_rd.h"
#include "servers/rendering/rendering_server_default.h"
#include "servers/rendering/rendering_server_globals.h"
using namespace RendererRD;
#define RB_SCOPE_SKY SNAME("sky_buffers")
#define RB_HALF_TEXTURE SNAME("half_texture")
#define RB_QUARTER_TEXTURE SNAME("quarter_texture")
////////////////////////////////////////////////////////////////////////////////
// SKY SHADER
@ -204,18 +210,17 @@ static _FORCE_INLINE_ void store_transform_3x3(const Basis &p_basis, float *p_ar
p_array[11] = 0;
}
void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier) {
void SkyRD::_render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier) {
SkyPushConstant sky_push_constant;
memset(&sky_push_constant, 0, sizeof(SkyPushConstant));
for (uint32_t v = 0; v < p_view_count; v++) {
// We only need key components of our projection matrix
sky_push_constant.projections[v][0] = p_projections[v].columns[2][0];
sky_push_constant.projections[v][1] = p_projections[v].columns[0][0];
sky_push_constant.projections[v][2] = p_projections[v].columns[2][1];
sky_push_constant.projections[v][3] = p_projections[v].columns[1][1];
}
// We only need key components of our projection matrix
sky_push_constant.projection[0] = p_projection.columns[2][0];
sky_push_constant.projection[1] = p_projection.columns[0][0];
sky_push_constant.projection[2] = p_projection.columns[2][1];
sky_push_constant.projection[3] = p_projection.columns[1][1];
sky_push_constant.position[0] = p_position.x;
sky_push_constant.position[1] = p_position.y;
sky_push_constant.position[2] = p_position.z;
@ -540,28 +545,15 @@ void SkyRD::Sky::free() {
uniform_buffer = RID();
}
if (half_res_pass.is_valid()) {
RD::get_singleton()->free(half_res_pass);
half_res_pass = RID();
}
if (quarter_res_pass.is_valid()) {
RD::get_singleton()->free(quarter_res_pass);
quarter_res_pass = RID();
}
if (material.is_valid()) {
RSG::material_storage->material_free(material);
material = RID();
}
}
RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd) {
RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, Ref<RenderSceneBuffersRD> p_render_buffers) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
if (texture_uniform_sets[p_version].is_valid() && RD::get_singleton()->uniform_set_is_valid(texture_uniform_sets[p_version])) {
return texture_uniform_sets[p_version];
}
Vector<RD::Uniform> uniforms;
{
RD::Uniform u;
@ -578,17 +570,18 @@ RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shade
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 1; // half res
if (half_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) {
if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
if (reflection.layers[0].views[1].is_valid() && p_version != SKY_TEXTURE_SET_CUBEMAP_HALF_RES) {
u.append_id(reflection.layers[0].views[1]);
} else {
u.append_id(half_res_pass);
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
}
} else {
if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE));
RID half_texture = p_render_buffers->has_texture(RB_SCOPE_SKY, RB_HALF_TEXTURE) ? p_render_buffers->get_texture(RB_SCOPE_SKY, RB_HALF_TEXTURE) : RID();
if (half_texture.is_valid() && p_version != SKY_TEXTURE_SET_HALF_RES) {
u.append_id(half_texture);
} else {
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE));
}
}
uniforms.push_back(u);
@ -597,24 +590,24 @@ RID SkyRD::Sky::get_textures(SkyTextureSetVersion p_version, RID p_default_shade
RD::Uniform u;
u.uniform_type = RD::UNIFORM_TYPE_TEXTURE;
u.binding = 2; // quarter res
if (quarter_res_pass.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) {
if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
if (p_version >= SKY_TEXTURE_SET_CUBEMAP) {
if (reflection.layers[0].views[2].is_valid() && p_version != SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES) {
u.append_id(reflection.layers[0].views[2]);
} else {
u.append_id(quarter_res_pass);
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
}
} else {
if (p_version < SKY_TEXTURE_SET_CUBEMAP) {
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE));
RID quarter_texture = p_render_buffers->has_texture(RB_SCOPE_SKY, RB_QUARTER_TEXTURE) ? p_render_buffers->get_texture(RB_SCOPE_SKY, RB_QUARTER_TEXTURE) : RID();
if (quarter_texture.is_valid() && p_version != SKY_TEXTURE_SET_QUARTER_RES) {
u.append_id(quarter_texture);
} else {
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_CUBEMAP_BLACK));
u.append_id(texture_storage->texture_rd_get_default(RendererRD::TextureStorage::DEFAULT_RD_TEXTURE_WHITE));
}
}
uniforms.push_back(u);
}
texture_uniform_sets[p_version] = RD::get_singleton()->uniform_set_create(uniforms, p_default_shader_rd, SKY_SET_TEXTURES);
return texture_uniform_sets[p_version];
return UniformSetCacheRD::get_singleton()->get_cache_vec(p_default_shader_rd, SKY_SET_TEXTURES, uniforms);
}
bool SkyRD::Sky::set_radiance_size(int p_radiance_size) {
@ -1020,11 +1013,17 @@ SkyRD::~SkyRD() {
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
}
void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, uint32_t p_view_count, const Projection *p_view_projections, const Vector3 *p_view_eye_offsets, const Transform3D &p_cam_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render) {
RendererRD::LightStorage *light_storage = RendererRD::LightStorage::get_singleton();
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(p_env.is_null());
ERR_FAIL_COND(p_render_buffers.is_null());
// make sure we support our view count
ERR_FAIL_COND(p_view_count == 0);
ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS);
SkyMaterialData *material = nullptr;
Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
@ -1055,31 +1054,12 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P
material->set_as_used();
// Invalidate supbass buffers if screen size changes
if (sky->screen_size != p_screen_size) {
sky->screen_size = p_screen_size;
sky->screen_size.x = sky->screen_size.x < 4 ? 4 : sky->screen_size.x;
sky->screen_size.y = sky->screen_size.y < 4 ? 4 : sky->screen_size.y;
if (shader_data->uses_half_res) {
if (sky->half_res_pass.is_valid()) {
RD::get_singleton()->free(sky->half_res_pass);
sky->half_res_pass = RID();
}
invalidate_sky(sky);
}
if (shader_data->uses_quarter_res) {
if (sky->quarter_res_pass.is_valid()) {
RD::get_singleton()->free(sky->quarter_res_pass);
sky->quarter_res_pass = RID();
}
invalidate_sky(sky);
}
}
// Save our screen size, our buffers will already have been cleared
sky->screen_size.x = p_screen_size.x < 4 ? 4 : p_screen_size.x;
sky->screen_size.y = p_screen_size.y < 4 ? 4 : p_screen_size.y;
// Create new subpass buffers if necessary
if ((shader_data->uses_half_res && sky->half_res_pass.is_null()) ||
(shader_data->uses_quarter_res && sky->quarter_res_pass.is_null()) ||
sky->radiance.is_null()) {
// Trigger updating radiance buffers
if (sky->radiance.is_null()) {
invalidate_sky(sky);
update_dirty_skys();
}
@ -1100,8 +1080,8 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P
sky->reflection.dirty = true;
}
if (!p_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) {
sky->prev_position = p_transform.origin;
if (!p_cam_transform.origin.is_equal_approx(sky->prev_position) && shader_data->uses_position) {
sky->prev_position = p_cam_transform.origin;
sky->reflection.dirty = true;
}
@ -1229,7 +1209,20 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P
}
}
sky_scene_state.ubo.z_far = p_projection.get_z_far();
sky_scene_state.view_count = p_view_count;
sky_scene_state.cam_transform = p_cam_transform;
sky_scene_state.cam_projection = p_view_projections[0]; // We only use this when rendering a single view
// Our info in our UBO is only used if we're rendering stereo
for (uint32_t i = 0; i < p_view_count; i++) {
RendererRD::MaterialStorage::store_camera(p_view_projections[i].inverse(), sky_scene_state.ubo.view_inv_projections[i]);
sky_scene_state.ubo.view_eye_offsets[i][0] = p_view_eye_offsets[i].x;
sky_scene_state.ubo.view_eye_offsets[i][1] = p_view_eye_offsets[i].y;
sky_scene_state.ubo.view_eye_offsets[i][2] = p_view_eye_offsets[i].z;
sky_scene_state.ubo.view_eye_offsets[i][3] = 0.0;
}
sky_scene_state.ubo.z_far = p_view_projections[0].get_z_far(); // Should be the same for all projection
sky_scene_state.ubo.fog_enabled = RendererSceneRenderRD::get_singleton()->environment_get_fog_enabled(p_env);
sky_scene_state.ubo.fog_density = RendererSceneRenderRD::get_singleton()->environment_get_fog_density(p_env);
sky_scene_state.ubo.fog_aerial_perspective = RendererSceneRenderRD::get_singleton()->environment_get_fog_aerial_perspective(p_env);
@ -1246,7 +1239,8 @@ void SkyRD::setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const P
RD::get_singleton()->buffer_update(sky_scene_state.uniform_buffer, 0, sizeof(SkySceneState::UBO), &sky_scene_state.ubo);
}
void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
void SkyRD::update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier) {
ERR_FAIL_COND(p_render_buffers.is_null());
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(p_env.is_null());
@ -1324,6 +1318,8 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
correction.set_depth_correction(true);
cm = correction * cm;
// Note, we ignore environment_get_sky_orientation here as this is applied when we do our lookup in our scene shader.
if (shader_data->uses_quarter_res) {
RD::get_singleton()->draw_command_begin_label("Render Sky to Quarter Res Cubemap");
PipelineCacheRD *pipeline = &shader_data->pipelines[SKY_VERSION_CUBEMAP_QUARTER_RES];
@ -1334,10 +1330,10 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
for (int i = 0; i < 6; i++) {
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_QUARTER_RES, sky_shader.default_shader_rd, p_render_buffers);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[2].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, p_transform.origin, p_luminance_multiplier);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[2].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
RD::get_singleton()->draw_command_end_label();
@ -1353,10 +1349,10 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
for (int i = 0; i < 6; i++) {
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP_HALF_RES, sky_shader.default_shader_rd, p_render_buffers);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[1].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, p_transform.origin, p_luminance_multiplier);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[1].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
RD::get_singleton()->draw_command_end_label();
@ -1368,10 +1364,10 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
RD::get_singleton()->draw_command_begin_label("Render Sky Cubemap");
for (int i = 0; i < 6; i++) {
Basis local_view = Basis::looking_at(view_normals[i], view_up[i]);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_CUBEMAP, sky_shader.default_shader_rd, p_render_buffers);
cubemap_draw_list = RD::get_singleton()->draw_list_begin(sky->reflection.layers[0].mipmaps[0].framebuffers[i], RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_DISCARD);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, 1, &cm, local_view, p_transform.origin, p_luminance_multiplier);
_render_sky(cubemap_draw_list, p_time, sky->reflection.layers[0].mipmaps[0].framebuffers[i], pipeline, material->uniform_set, texture_uniform_set, cm, local_view, p_global_pos, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
RD::get_singleton()->draw_command_end_label();
@ -1413,13 +1409,11 @@ void SkyRD::update(RID p_env, const Projection &p_projection, const Transform3D
}
}
void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
void SkyRD::update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier) {
ERR_FAIL_COND(p_render_buffers.is_null());
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(p_env.is_null());
ERR_FAIL_COND(p_view_count == 0);
ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS);
Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
SkyMaterialData *material = nullptr;
@ -1452,168 +1446,82 @@ void SkyRD::draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth
ERR_FAIL_COND(!material);
SkyShaderData *shader_data = material->shader_data;
ERR_FAIL_COND(!shader_data);
if (!shader_data->uses_quarter_res && !shader_data->uses_half_res) {
return;
}
material->set_as_used();
RENDER_TIMESTAMP("Setup Sky Resolution Buffers");
RD::get_singleton()->draw_command_begin_label("Setup Sky Resolution Buffers");
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
sky_transform.invert();
float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env);
// Camera
Projection camera;
uint32_t view_count = p_view_count;
const Projection *projections = p_projections;
Projection projection = sky_scene_state.cam_projection;
if (custom_fov) {
if (custom_fov && sky_scene_state.view_count == 1) {
// With custom fov we don't support stereo...
float near_plane = p_projections[0].get_z_near();
float far_plane = p_projections[0].get_z_far();
float aspect = p_projections[0].get_aspect();
float near_plane = projection.get_z_near();
float far_plane = projection.get_z_far();
float aspect = projection.get_aspect();
camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
view_count = 1;
projections = &camera;
projection.set_perspective(custom_fov, aspect, near_plane, far_plane);
}
sky_transform = sky_transform * p_transform.basis;
sky_transform = sky_transform * sky_scene_state.cam_transform.basis;
if (shader_data->uses_quarter_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
// Grab texture and framebuffer from cache, create if needed...
uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
Size2i quarter_size = sky->screen_size / 4;
RID texture = p_render_buffers->create_texture(RB_SCOPE_SKY, RB_QUARTER_TEXTURE, texture_format, usage_bits, RD::TEXTURE_SAMPLES_1, quarter_size);
RID framebuffer = FramebufferCacheRD::get_singleton()->get_cache_multiview(sky_scene_state.view_count, texture);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd, p_render_buffers);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
_render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
if (shader_data->uses_half_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
// Grab texture and framebuffer from cache, create if needed...
uint32_t usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
Size2i half_size = sky->screen_size / 2;
RID texture = p_render_buffers->create_texture(RB_SCOPE_SKY, RB_HALF_TEXTURE, texture_format, usage_bits, RD::TEXTURE_SAMPLES_1, half_size);
RID framebuffer = FramebufferCacheRD::get_singleton()->get_cache_multiview(sky_scene_state.view_count, texture);
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd, p_render_buffers);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
_render_sky(draw_list, p_time, framebuffer, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND];
RID texture_uniform_set;
if (sky) {
texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
} else {
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
}
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(p_fb, RD::INITIAL_ACTION_CONTINUE, p_can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, p_can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
_render_sky(draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
}
void SkyRD::update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
void SkyRD::draw_sky(RD::DrawListID p_draw_list, Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier) {
ERR_FAIL_COND(p_render_buffers.is_null());
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(p_env.is_null());
ERR_FAIL_COND(p_view_count == 0);
ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS);
Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
ERR_FAIL_COND(!sky);
SkyMaterialData *material = nullptr;
RID sky_material;
sky_material = sky_get_material(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
if (sky_material.is_valid()) {
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY));
if (!material || !material->shader_data->valid) {
material = nullptr;
}
}
if (!material) {
sky_material = sky_shader.default_material;
material = static_cast<SkyMaterialData *>(material_storage->material_get_data(sky_material, RendererRD::MaterialStorage::SHADER_TYPE_SKY));
}
ERR_FAIL_COND(!material);
SkyShaderData *shader_data = material->shader_data;
ERR_FAIL_COND(!shader_data);
material->set_as_used();
Basis sky_transform = RendererSceneRenderRD::get_singleton()->environment_get_sky_orientation(p_env);
sky_transform.invert();
float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env);
// Camera
Projection camera;
uint32_t view_count = p_view_count;
const Projection *projections = p_projections;
if (custom_fov) {
// With custom fov we don't support stereo...
float near_plane = p_projections[0].get_z_near();
float far_plane = p_projections[0].get_z_far();
float aspect = p_projections[0].get_aspect();
camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
view_count = 1;
projections = &camera;
}
sky_transform = sky_transform * p_transform.basis;
if (shader_data->uses_quarter_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_QUARTER_RES_MULTIVIEW : SKY_VERSION_QUARTER_RES];
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_QUARTER_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->quarter_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
_render_sky(draw_list, p_time, sky->quarter_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
if (shader_data->uses_half_res) {
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_HALF_RES_MULTIVIEW : SKY_VERSION_HALF_RES];
RID texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_HALF_RES, sky_shader.default_shader_rd);
Vector<Color> clear_colors;
clear_colors.push_back(Color(0.0, 0.0, 0.0));
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(sky->half_res_framebuffer, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_DISCARD, clear_colors);
_render_sky(draw_list, p_time, sky->half_res_framebuffer, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
RD::get_singleton()->draw_list_end();
}
}
void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier) {
RendererRD::MaterialStorage *material_storage = RendererRD::MaterialStorage::get_singleton();
ERR_FAIL_COND(p_env.is_null());
ERR_FAIL_COND(p_view_count == 0);
ERR_FAIL_COND(p_view_count > RendererSceneRender::MAX_RENDER_VIEWS);
Sky *sky = get_sky(RendererSceneRenderRD::get_singleton()->environment_get_sky(p_env));
SkyMaterialData *material = nullptr;
@ -1646,7 +1554,6 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie
ERR_FAIL_COND(!material);
SkyShaderData *shader_data = material->shader_data;
ERR_FAIL_COND(!shader_data);
material->set_as_used();
@ -1657,34 +1564,29 @@ void SkyRD::draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_vie
float custom_fov = RendererSceneRenderRD::get_singleton()->environment_get_sky_custom_fov(p_env);
// Camera
Projection camera;
uint32_t view_count = p_view_count;
const Projection *projections = p_projections;
Projection projection = sky_scene_state.cam_projection;
if (custom_fov) {
if (custom_fov && sky_scene_state.view_count == 1) {
// With custom fov we don't support stereo...
float near_plane = p_projections[0].get_z_near();
float far_plane = p_projections[0].get_z_far();
float aspect = p_projections[0].get_aspect();
float near_plane = projection.get_z_near();
float far_plane = projection.get_z_far();
float aspect = projection.get_aspect();
camera.set_perspective(custom_fov, aspect, near_plane, far_plane);
view_count = 1;
projections = &camera;
projection.set_perspective(custom_fov, aspect, near_plane, far_plane);
}
sky_transform = sky_transform * p_transform.basis;
sky_transform = sky_transform * sky_scene_state.cam_transform.basis;
PipelineCacheRD *pipeline = &shader_data->pipelines[view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND];
PipelineCacheRD *pipeline = &shader_data->pipelines[sky_scene_state.view_count > 1 ? SKY_VERSION_BACKGROUND_MULTIVIEW : SKY_VERSION_BACKGROUND];
RID texture_uniform_set;
if (sky) {
texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd);
texture_uniform_set = sky->get_textures(SKY_TEXTURE_SET_BACKGROUND, sky_shader.default_shader_rd, p_render_buffers);
} else {
texture_uniform_set = sky_scene_state.fog_only_texture_uniform_set;
}
_render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, view_count, projections, sky_transform, p_transform.origin, p_luminance_multiplier);
_render_sky(p_draw_list, p_time, p_fb, pipeline, material->uniform_set, texture_uniform_set, projection, sky_transform, sky_scene_state.cam_transform.origin, p_luminance_multiplier);
}
void SkyRD::invalidate_sky(Sky *p_sky) {
@ -1699,9 +1601,11 @@ void SkyRD::update_dirty_skys() {
Sky *sky = dirty_sky_list;
while (sky) {
bool texture_set_dirty = false;
//update sky configuration if texture is missing
// TODO See if we can move this into `update_radiance_buffers` and remove our dirty_sky logic.
// As this is basically a duplicate of the logic in reflection probes we could move this logic
// into RenderSceneBuffersRD and use that from both places.
if (sky->radiance.is_null()) {
int mipmaps = Image::get_image_required_mipmaps(sky->radiance_size, sky->radiance_size, Image::FORMAT_RGBAH) + 1;
@ -1744,47 +1648,6 @@ void SkyRD::update_dirty_skys() {
sky->reflection.update_reflection_data(sky->radiance_size, MIN(mipmaps, layers), false, sky->radiance, 0, sky->mode == RS::SKY_MODE_REALTIME, roughness_layers, texture_format);
}
texture_set_dirty = true;
}
// Create subpass buffers if they haven't been created already
if (sky->half_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->half_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) {
RD::TextureFormat tformat;
tformat.format = texture_format;
tformat.width = sky->screen_size.x / 2;
tformat.height = sky->screen_size.y / 2;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
tformat.texture_type = RD::TEXTURE_TYPE_2D;
sky->half_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
Vector<RID> texs;
texs.push_back(sky->half_res_pass);
sky->half_res_framebuffer = RD::get_singleton()->framebuffer_create(texs);
texture_set_dirty = true;
}
if (sky->quarter_res_pass.is_null() && !RD::get_singleton()->texture_is_valid(sky->quarter_res_pass) && sky->screen_size.x >= 4 && sky->screen_size.y >= 4) {
RD::TextureFormat tformat;
tformat.format = texture_format;
tformat.width = sky->screen_size.x / 4;
tformat.height = sky->screen_size.y / 4;
tformat.usage_bits = RD::TEXTURE_USAGE_SAMPLING_BIT | RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT;
tformat.texture_type = RD::TEXTURE_TYPE_2D;
sky->quarter_res_pass = RD::get_singleton()->texture_create(tformat, RD::TextureView());
Vector<RID> texs;
texs.push_back(sky->quarter_res_pass);
sky->quarter_res_framebuffer = RD::get_singleton()->framebuffer_create(texs);
texture_set_dirty = true;
}
if (texture_set_dirty) {
for (int i = 0; i < SKY_TEXTURE_SET_MAX; i++) {
if (sky->texture_uniform_sets[i].is_valid() && RD::get_singleton()->uniform_set_is_valid(sky->texture_uniform_sets[i])) {
RD::get_singleton()->free(sky->texture_uniform_sets[i]);
sky->texture_uniform_sets[i] = RID();
}
}
}
sky->reflection.dirty = true;

View file

@ -99,11 +99,11 @@ private:
struct SkyPushConstant {
float orientation[12]; // 48 - 48
float projections[RendererSceneRender::MAX_RENDER_VIEWS][4]; // 2 x 16 - 80
float position[3]; // 12 - 92
float time; // 4 - 96
float pad[3]; // 12 - 108
float luminance_multiplier; // 4 - 112
float projection[4]; // 16 - 64
float position[3]; // 12 - 76
float time; // 4 - 80
float pad[3]; // 12 - 92
float luminance_multiplier; // 4 - 96
// 128 is the max size of a push constant. We can replace "pad" but we can't add any more.
};
@ -134,32 +134,39 @@ private:
virtual ~SkyShaderData();
};
void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, uint32_t p_view_count, const Projection *p_projections, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier);
void _render_sky(RD::DrawListID p_list, float p_time, RID p_fb, PipelineCacheRD *p_pipeline, RID p_uniform_set, RID p_texture_set, const Projection &p_projection, const Basis &p_orientation, const Vector3 &p_position, float p_luminance_multiplier);
public:
struct SkySceneState {
struct UBO {
uint32_t volumetric_fog_enabled; // 4 - 4
float volumetric_fog_inv_length; // 4 - 8
float volumetric_fog_detail_spread; // 4 - 12
float volumetric_fog_sky_affect; // 4 - 16
float view_inv_projections[RendererSceneRender::MAX_RENDER_VIEWS][16]; // 2 x 64 - 128
float view_eye_offsets[RendererSceneRender::MAX_RENDER_VIEWS][4]; // 2 x 16 - 160
uint32_t fog_enabled; // 4 - 20
float fog_sky_affect; // 4 - 24
float fog_density; // 4 - 28
float fog_sun_scatter; // 4 - 32
uint32_t volumetric_fog_enabled; // 4 - 164
float volumetric_fog_inv_length; // 4 - 168
float volumetric_fog_detail_spread; // 4 - 172
float volumetric_fog_sky_affect; // 4 - 176
float fog_light_color[3]; // 12 - 44
float fog_aerial_perspective; // 4 - 48
uint32_t fog_enabled; // 4 - 180
float fog_sky_affect; // 4 - 184
float fog_density; // 4 - 188
float fog_sun_scatter; // 4 - 192
float z_far; // 4 - 52
uint32_t directional_light_count; // 4 - 56
uint32_t pad1; // 4 - 60
uint32_t pad2; // 4 - 64
float fog_light_color[3]; // 12 - 204
float fog_aerial_perspective; // 4 - 208
float z_far; // 4 - 212
uint32_t directional_light_count; // 4 - 216
uint32_t pad1; // 4 - 220
uint32_t pad2; // 4 - 224
};
UBO ubo;
uint32_t view_count = 1;
Transform3D cam_transform;
Projection cam_projection;
SkyDirectionalLightData *directional_lights = nullptr;
SkyDirectionalLightData *last_frame_directional_lights = nullptr;
uint32_t max_directional_lights;
@ -238,13 +245,10 @@ public:
struct Sky {
RID radiance;
RID half_res_pass;
RID half_res_framebuffer;
RID quarter_res_pass;
RID quarter_res_framebuffer;
Size2i screen_size;
RID texture_uniform_sets[SKY_TEXTURE_SET_MAX];
RID uniform_set;
RID material;
@ -267,7 +271,7 @@ public:
void free();
RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd);
RID get_textures(SkyTextureSetVersion p_version, RID p_default_shader_rd, Ref<RenderSceneBuffersRD> p_render_buffers);
bool set_radiance_size(int p_radiance_size);
bool set_mode(RS::SkyMode p_mode);
bool set_material(RID p_material);
@ -291,11 +295,10 @@ public:
void set_texture_format(RD::DataFormat p_texture_format);
~SkyRD();
void setup(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, const Projection &p_projection, const Transform3D &p_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
void update(RID p_env, const Projection &p_projection, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
void draw(RID p_env, bool p_can_continue_color, bool p_can_continue_depth, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0); // only called by clustered renderer
void update_res_buffers(RID p_env, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
void draw(RD::DrawListID p_draw_list, RID p_env, RID p_fb, uint32_t p_view_count, const Projection *p_projections, const Transform3D &p_transform, double p_time, float p_luminance_multiplier = 1.0);
void setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, const PagedArray<RID> &p_lights, RID p_camera_attributes, uint32_t p_view_count, const Projection *p_view_projections, const Vector3 *p_view_eye_offsets, const Transform3D &p_cam_transform, const Size2i p_screen_size, RendererSceneRenderRD *p_scene_render);
void update_radiance_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, const Vector3 &p_global_pos, double p_time, float p_luminance_multiplier = 1.0);
void update_res_buffers(Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, double p_time, float p_luminance_multiplier = 1.0);
void draw_sky(RD::DrawListID p_draw_list, Ref<RenderSceneBuffersRD> p_render_buffers, RID p_env, RID p_fb, double p_time, float p_luminance_multiplier = 1.0);
void invalidate_sky(Sky *p_sky);
void update_dirty_skys();

View file

@ -1626,7 +1626,21 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
bool reverse_cull = p_render_data->scene_data->cam_transform.basis.determinant() < 0;
bool using_ssil = p_render_data->environment.is_valid() && environment_get_ssil_enabled(p_render_data->environment);
if (rb.is_valid()) {
if (p_render_data->reflection_probe.is_valid()) {
uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
screen_size.x = resolution;
screen_size.y = resolution;
color_framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
color_only_framebuffer = color_framebuffer;
depth_framebuffer = light_storage->reflection_probe_instance_get_depth_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
p_render_data->environment = RID(); //no environment on interiors
}
reverse_cull = true; // for some reason our views are inverted
} else if (rb.is_valid()) {
screen_size = rb->get_internal_size();
if (rb->get_use_taa() || get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_MOTION_VECTORS) {
@ -1678,20 +1692,6 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
color_framebuffer = rb_data->get_color_pass_fb(color_pass_flags);
color_only_framebuffer = rb_data->get_color_only_fb();
} else if (p_render_data->reflection_probe.is_valid()) {
uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
screen_size.x = resolution;
screen_size.y = resolution;
color_framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
color_only_framebuffer = color_framebuffer;
depth_framebuffer = light_storage->reflection_probe_instance_get_depth_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
p_render_data->environment = RID(); //no environment on interiors
}
reverse_cull = true; // for some reason our views are inverted
} else {
ERR_FAIL(); //bug?
}
@ -1780,29 +1780,40 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
default: {
}
}
// setup sky if used for ambient, reflections, or background
if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
RENDER_TIMESTAMP("Setup Sky");
RD::get_singleton()->draw_command_begin_label("Setup Sky");
Projection projection = p_render_data->scene_data->cam_projection;
// Setup our sky render information for this frame/viewport
if (p_render_data->reflection_probe.is_valid()) {
Vector3 eye_offset;
Projection correction;
correction.set_depth_correction(true);
projection = correction * p_render_data->scene_data->cam_projection;
}
Projection projection = correction * p_render_data->scene_data->cam_projection;
sky.setup(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->scene_data->cam_transform, screen_size, this);
sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, screen_size, this);
} else {
sky.setup_sky(p_render_data->environment, rb, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, screen_size, this);
}
sky_energy_multiplier *= bg_energy_multiplier;
RID sky_rid = environment_get_sky(p_render_data->environment);
if (sky_rid.is_valid()) {
sky.update(p_render_data->environment, projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
sky.update_radiance_buffers(rb, p_render_data->environment, p_render_data->scene_data->cam_transform.origin, time, sky_energy_multiplier);
radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
} else {
// do not try to draw sky if invalid
draw_sky = false;
}
if (draw_sky || draw_sky_fog_only) {
// update sky half/quarter res buffers (if required)
sky.update_res_buffers(rb, p_render_data->environment, time, sky_energy_multiplier);
}
RD::get_singleton()->draw_command_end_label();
}
} else {
@ -1952,15 +1963,11 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RENDER_TIMESTAMP("Render Sky");
RD::get_singleton()->draw_command_begin_label("Draw Sky");
RD::DrawListID draw_list = RD::get_singleton()->draw_list_begin(color_only_framebuffer, RD::INITIAL_ACTION_CONTINUE, can_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, RD::INITIAL_ACTION_CONTINUE, can_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ);
if (p_render_data->reflection_probe.is_valid()) {
Projection correction;
correction.set_depth_correction(true);
Projection projection = correction * p_render_data->scene_data->cam_projection;
sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
} else {
sky.draw(p_render_data->environment, can_continue_color, can_continue_depth, color_only_framebuffer, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
}
sky.draw_sky(draw_list, rb, p_render_data->environment, color_only_framebuffer, time, sky_energy_multiplier);
RD::get_singleton()->draw_list_end();
RD::get_singleton()->draw_command_end_label();
}

View file

@ -361,7 +361,9 @@ RID RenderForwardMobile::_setup_render_pass_uniform_set(RenderListType p_render_
Ref<RenderSceneBuffersRD> rb;
if (p_render_data && p_render_data->render_buffers.is_valid()) {
rb = p_render_data->render_buffers;
rb_data = rb->get_custom_data(RB_SCOPE_MOBILE);
if (rb->has_custom_data(RB_SCOPE_MOBILE)) {
rb_data = rb->get_custom_data(RB_SCOPE_MOBILE);
}
}
// default render buffer and scene state uniform set
@ -640,7 +642,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
Ref<RenderBufferDataForwardMobile> rb_data;
if (p_render_data->render_buffers.is_valid()) {
rb = p_render_data->render_buffers;
rb_data = rb->get_custom_data(RB_SCOPE_MOBILE);
if (rb->has_custom_data(RB_SCOPE_MOBILE)) {
rb_data = rb->get_custom_data(RB_SCOPE_MOBILE);
}
}
RENDER_TIMESTAMP("Prepare 3D Scene");
@ -689,7 +693,21 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
p_render_data->render_info->info[RS::VIEWPORT_RENDER_INFO_TYPE_VISIBLE][RS::VIEWPORT_RENDER_INFO_OBJECTS_IN_FRAME] = p_render_data->instances->size();
}
if (rb_data.is_valid()) {
if (p_render_data->reflection_probe.is_valid()) {
uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
screen_size.x = resolution;
screen_size.y = resolution;
framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
p_render_data->environment = RID(); //no environment on interiors
}
reverse_cull = true;
using_subpass_transparent = true; // we ignore our screen/depth texture here
using_subpass_post_process = false; // not applicable at all for reflection probes.
} else if (rb_data.is_valid()) {
// setup rendering to render buffer
screen_size = p_render_data->render_buffers->get_internal_size();
@ -717,20 +735,6 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
// only opaque and sky as subpasses
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_TWO_SUBPASSES);
}
} else if (p_render_data->reflection_probe.is_valid()) {
uint32_t resolution = light_storage->reflection_probe_instance_get_resolution(p_render_data->reflection_probe);
screen_size.x = resolution;
screen_size.y = resolution;
framebuffer = light_storage->reflection_probe_instance_get_framebuffer(p_render_data->reflection_probe, p_render_data->reflection_probe_pass);
if (light_storage->reflection_probe_is_interior(light_storage->reflection_probe_instance_get_probe(p_render_data->reflection_probe))) {
p_render_data->environment = RID(); //no environment on interiors
}
reverse_cull = true;
using_subpass_transparent = true; // we ignore our screen/depth texture here
using_subpass_post_process = false; // not applicable at all for reflection probes.
} else {
ERR_FAIL(); //bug?
}
@ -796,7 +800,7 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
draw_sky = true;
} break;
case RS::ENV_BG_CANVAS: {
if (rb.is_valid()) {
if (rb_data.is_valid()) {
RID dest_framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_ONE_PASS);
RID texture = RendererRD::TextureStorage::get_singleton()->render_target_get_rd_texture(rb->get_render_target());
copy_effects->copy_to_fb_rect(texture, dest_framebuffer, Rect2i(), false, false, false, false, RID(), false, false, true);
@ -811,55 +815,45 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
default: {
}
}
// setup sky if used for ambient, reflections, or background
if (draw_sky || draw_sky_fog_only || environment_get_reflection_source(p_render_data->environment) == RS::ENV_REFLECTION_SOURCE_SKY || environment_get_ambient_source(p_render_data->environment) == RS::ENV_AMBIENT_SOURCE_SKY) {
RENDER_TIMESTAMP("Setup Sky");
RD::get_singleton()->draw_command_begin_label("Setup Sky");
Projection projection = p_render_data->scene_data->cam_projection;
// Setup our sky render information for this frame/viewport
if (p_render_data->reflection_probe.is_valid()) {
Vector3 eye_offset;
Projection correction;
correction.set_depth_correction(true);
projection = correction * p_render_data->scene_data->cam_projection;
}
Projection projection = correction * p_render_data->scene_data->cam_projection;
sky.setup(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, projection, p_render_data->scene_data->cam_transform, screen_size, this);
sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, 1, &projection, &eye_offset, p_render_data->scene_data->cam_transform, screen_size, this);
} else {
sky.setup_sky(p_render_data->environment, p_render_data->render_buffers, *p_render_data->lights, p_render_data->camera_attributes, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->view_eye_offset, p_render_data->scene_data->cam_transform, screen_size, this);
}
sky_energy_multiplier *= bg_energy_multiplier;
RID sky_rid = environment_get_sky(p_render_data->environment);
if (sky_rid.is_valid()) {
sky.update(p_render_data->environment, projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
sky.update_radiance_buffers(rb, p_render_data->environment, p_render_data->scene_data->cam_transform.origin, time, sky_energy_multiplier);
radiance_texture = sky.sky_get_radiance_texture_rd(sky_rid);
} else {
// do not try to draw sky if invalid
draw_sky = false;
}
if (draw_sky || draw_sky_fog_only) {
// update sky half/quarter res buffers (if required)
sky.update_res_buffers(rb, p_render_data->environment, time, sky_energy_multiplier);
}
RD::get_singleton()->draw_command_end_label(); // Setup Sky
}
} else {
clear_color = p_default_bg_color;
}
// update sky buffers (if required)
if (draw_sky || draw_sky_fog_only) {
// !BAS! @TODO See if we can limit doing some things double and maybe even move this into _pre_opaque_render
// and change Forward Clustered in the same way as we have here (but without using subpasses)
RENDER_TIMESTAMP("Setup Sky Resolution Buffers");
RD::get_singleton()->draw_command_begin_label("Setup Sky Resolution Buffers");
if (p_render_data->reflection_probe.is_valid()) {
Projection correction;
correction.set_depth_correction(true);
Projection projection = correction * p_render_data->scene_data->cam_projection;
sky.update_res_buffers(p_render_data->environment, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
} else {
sky.update_res_buffers(p_render_data->environment, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
}
RD::get_singleton()->draw_command_end_label(); // Setup Sky resolution buffers
}
_pre_opaque_render(p_render_data);
uint32_t spec_constant_base_flags = 0;
@ -944,16 +938,11 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
if (draw_sky || draw_sky_fog_only) {
RD::get_singleton()->draw_command_begin_label("Draw Sky Subpass");
// Note, sky.setup should have been called up above and setup stuff we need.
RD::DrawListID draw_list = RD::get_singleton()->draw_list_switch_to_next_pass();
if (p_render_data->reflection_probe.is_valid()) {
Projection correction;
correction.set_depth_correction(true);
Projection projection = correction * p_render_data->scene_data->cam_projection;
sky.draw(draw_list, p_render_data->environment, framebuffer, 1, &projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
} else {
sky.draw(draw_list, p_render_data->environment, framebuffer, p_render_data->scene_data->view_count, p_render_data->scene_data->view_projection, p_render_data->scene_data->cam_transform, time, sky_energy_multiplier);
}
sky.draw_sky(draw_list, rb, p_render_data->environment, framebuffer, time, sky_energy_multiplier);
RD::get_singleton()->draw_command_end_label(); // Draw Sky Subpass
@ -1021,7 +1010,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
} else {
RENDER_TIMESTAMP("Render Transparent");
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_ONE_PASS);
if (rb_data.is_valid()) {
framebuffer = rb_data->get_color_fbs(RenderBufferDataForwardMobile::FB_CONFIG_ONE_PASS);
}
// this may be needed if we re-introduced steps that change info, not sure which do so in the previous implementation
// _setup_environment(p_render_data, p_render_data->reflection_probe.is_valid(), screen_size, !p_render_data->reflection_probe.is_valid(), p_default_bg_color, false);

View file

@ -1002,10 +1002,20 @@ bool RendererSceneRenderRD::is_using_radiance_cubemap_array() const {
}
void RendererSceneRenderRD::_update_vrs(Ref<RenderSceneBuffersRD> p_render_buffers) {
if (p_render_buffers.is_valid() && vrs) {
if (p_render_buffers.is_null()) {
return;
}
RID render_target = p_render_buffers->get_render_target();
if (render_target.is_null()) {
// must be rendering reflection probes
return;
}
if (vrs) {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RS::ViewportVRSMode vrs_mode = texture_storage->render_target_get_vrs_mode(p_render_buffers->get_render_target());
RS::ViewportVRSMode vrs_mode = texture_storage->render_target_get_vrs_mode(render_target);
if (vrs_mode != RS::VIEWPORT_VRS_DISABLED) {
RID vrs_texture = p_render_buffers->get_texture(RB_SCOPE_VRS, RB_TEXTURE);
@ -1157,7 +1167,7 @@ void RendererSceneRenderRD::render_scene(const Ref<RenderSceneBuffers> &p_render
}
Color clear_color;
if (p_render_buffers.is_valid()) {
if (p_render_buffers.is_valid() && p_reflection_probe.is_null()) {
clear_color = texture_storage->render_target_get_clear_request_color(rb->get_render_target());
} else {
clear_color = RSG::texture_storage->get_default_clear_color();

View file

@ -14,7 +14,7 @@ layout(location = 0) out vec2 uv_interp;
layout(push_constant, std430) uniform Params {
mat3 orientation;
vec4 projections[MAX_VIEWS];
vec4 projection; // only applicable if not multiview
vec3 position;
float time;
vec3 pad;
@ -54,7 +54,7 @@ layout(location = 0) in vec2 uv_interp;
layout(push_constant, std430) uniform Params {
mat3 orientation;
vec4 projections[MAX_VIEWS];
vec4 projection; // only applicable if not multiview
vec3 position;
float time;
vec3 pad;
@ -82,7 +82,10 @@ layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalShaderUnifor
}
global_shader_uniforms;
layout(set = 0, binding = 2, std140) uniform SceneData {
layout(set = 0, binding = 2, std140) uniform SkySceneData {
mat4 view_inv_projections[2];
vec4 view_eye_offsets[2];
bool volumetric_fog_enabled; // 4 - 4
float volumetric_fog_inv_length; // 4 - 8
float volumetric_fog_detail_spread; // 4 - 12
@ -101,7 +104,7 @@ layout(set = 0, binding = 2, std140) uniform SceneData {
uint pad1; // 4 - 60
uint pad2; // 4 - 64
}
scene_data;
sky_scene_data;
struct DirectionalLightData {
vec4 direction_energy;
@ -124,6 +127,9 @@ layout(set = 2, binding = 0) uniform textureCube radiance;
#ifdef USE_CUBEMAP_PASS
layout(set = 2, binding = 1) uniform textureCube half_res;
layout(set = 2, binding = 2) uniform textureCube quarter_res;
#elif defined(USE_MULTIVIEW)
layout(set = 2, binding = 1) uniform texture2DArray half_res;
layout(set = 2, binding = 2) uniform texture2DArray quarter_res;
#else
layout(set = 2, binding = 1) uniform texture2D half_res;
layout(set = 2, binding = 2) uniform texture2D quarter_res;
@ -169,15 +175,15 @@ vec4 volumetric_fog_process(vec2 screen_uv) {
}
vec4 fog_process(vec3 view, vec3 sky_color) {
vec3 fog_color = mix(scene_data.fog_light_color, sky_color, scene_data.fog_aerial_perspective);
vec3 fog_color = mix(sky_scene_data.fog_light_color, sky_color, sky_scene_data.fog_aerial_perspective);
if (scene_data.fog_sun_scatter > 0.001) {
if (sky_scene_data.fog_sun_scatter > 0.001) {
vec4 sun_scatter = vec4(0.0);
float sun_total = 0.0;
for (uint i = 0; i < scene_data.directional_light_count; i++) {
for (uint i = 0; i < sky_scene_data.directional_light_count; i++) {
vec3 light_color = directional_lights.data[i].color_size.xyz * directional_lights.data[i].direction_energy.w;
float light_amount = pow(max(dot(view, directional_lights.data[i].direction_energy.xyz), 0.0), 8.0);
fog_color += light_color * light_amount * scene_data.fog_sun_scatter;
fog_color += light_color * light_amount * sky_scene_data.fog_sun_scatter;
}
}
@ -186,9 +192,17 @@ vec4 fog_process(vec3 view, vec3 sky_color) {
void main() {
vec3 cube_normal;
#ifdef USE_MULTIVIEW
// In multiview our projection matrices will contain positional and rotational offsets that we need to properly unproject.
vec4 unproject = vec4(uv_interp.x, -uv_interp.y, 1.0, 1.0);
vec4 unprojected = sky_scene_data.view_inv_projections[ViewIndex] * unproject;
cube_normal = unprojected.xyz / unprojected.w;
cube_normal += sky_scene_data.view_eye_offsets[ViewIndex].xyz;
#else
cube_normal.z = -1.0;
cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projections[ViewIndex].x)) / params.projections[ViewIndex].y;
cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projections[ViewIndex].z)) / params.projections[ViewIndex].w;
cube_normal.x = (cube_normal.z * (-uv_interp.x - params.projection.x)) / params.projection.y;
cube_normal.y = -(cube_normal.z * (-uv_interp.y - params.projection.z)) / params.projection.w;
#endif
cube_normal = mat3(params.orientation) * cube_normal;
cube_normal = normalize(cube_normal);
@ -209,20 +223,33 @@ void main() {
vec4 custom_fog = vec4(0.0);
#ifdef USE_CUBEMAP_PASS
#ifdef USES_HALF_RES_COLOR
half_res_color = texture(samplerCube(half_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) / params.luminance_multiplier;
#endif
#ifdef USES_QUARTER_RES_COLOR
quarter_res_color = texture(samplerCube(quarter_res, material_samplers[SAMPLER_LINEAR_WITH_MIPMAPS_CLAMP]), cube_normal) / params.luminance_multiplier;
#endif
#else
#ifdef USES_HALF_RES_COLOR
#ifdef USE_MULTIVIEW
half_res_color = textureLod(sampler2DArray(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0) / params.luminance_multiplier;
#else
half_res_color = textureLod(sampler2D(half_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) / params.luminance_multiplier;
#endif
#endif // USE_MULTIVIEW
#endif // USES_HALF_RES_COLOR
#ifdef USES_QUARTER_RES_COLOR
#ifdef USE_MULTIVIEW
quarter_res_color = textureLod(sampler2DArray(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), vec3(uv, ViewIndex), 0.0) / params.luminance_multiplier;
#else
quarter_res_color = textureLod(sampler2D(quarter_res, material_samplers[SAMPLER_LINEAR_CLAMP]), uv, 0.0) / params.luminance_multiplier;
#endif
#endif
#endif // USE_MULTIVIEW
#endif // USES_QUARTER_RES_COLOR
#endif //USE_CUBEMAP_PASS
{
@ -236,14 +263,14 @@ void main() {
#if !defined(DISABLE_FOG) && !defined(USE_CUBEMAP_PASS)
// Draw "fixed" fog before volumetric fog to ensure volumetric fog can appear in front of the sky.
if (scene_data.fog_enabled) {
if (sky_scene_data.fog_enabled) {
vec4 fog = fog_process(cube_normal, frag_color.rgb);
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.fog_sky_affect);
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * sky_scene_data.fog_sky_affect);
}
if (scene_data.volumetric_fog_enabled) {
if (sky_scene_data.volumetric_fog_enabled) {
vec4 fog = volumetric_fog_process(uv);
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * scene_data.volumetric_fog_sky_affect);
frag_color.rgb = mix(frag_color.rgb, fog.rgb, fog.a * sky_scene_data.volumetric_fog_sky_affect);
}
if (custom_fog.a > 0.0) {

View file

@ -1315,6 +1315,10 @@ void LightStorage::reflection_atlas_set_size(RID p_ref_atlas, int p_reflection_s
ra->reflections.clear();
}
if (ra->render_buffers.is_valid()) {
ra->render_buffers->cleanup();
}
}
int LightStorage::reflection_atlas_get_size(RID p_ref_atlas) const {
@ -1360,6 +1364,9 @@ void LightStorage::reflection_probe_release_atlas_index(RID p_instance) {
ERR_FAIL_COND(!atlas);
ERR_FAIL_INDEX(rpi->atlas_index, atlas->reflections.size());
atlas->reflections.write[rpi->atlas_index].owner = RID();
// TODO investigate if this is enough? shouldn't we be freeing our textures and framebuffers?
rpi->atlas_index = -1;
rpi->atlas = RID();
}
@ -1398,6 +1405,10 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
ERR_FAIL_COND_V(!rpi, false);
if (atlas->render_buffers.is_null()) {
atlas->render_buffers.instantiate();
}
RD::get_singleton()->draw_command_begin_label("Reflection probe render");
if (LightStorage::get_singleton()->reflection_probe_get_update_mode(rpi->probe) == RS::REFLECTION_PROBE_UPDATE_ALWAYS && atlas->reflection.is_valid() && atlas->size != 256) {
@ -1455,6 +1466,9 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
Vector<RID> fb;
fb.push_back(atlas->depth_buffer);
atlas->depth_fb = RD::get_singleton()->framebuffer_create(fb);
atlas->render_buffers->cleanup();
atlas->render_buffers->configure_for_reflections(Size2i(atlas->size, atlas->size));
}
if (rpi->atlas_index == -1) {
@ -1494,6 +1508,13 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
return true;
}
Ref<RenderSceneBuffers> LightStorage::reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) {
ReflectionAtlas *atlas = reflection_atlas_owner.get_or_null(p_reflection_atlas);
ERR_FAIL_COND_V(!atlas, Ref<RenderSceneBuffersRD>());
return atlas->render_buffers;
}
bool LightStorage::reflection_probe_instance_postprocess_step(RID p_instance) {
ReflectionProbeInstance *rpi = reflection_probe_instance_owner.get_or_null(p_instance);
ERR_FAIL_COND_V(!rpi, false);

View file

@ -38,6 +38,7 @@
#include "servers/rendering/renderer_rd/cluster_builder_rd.h"
#include "servers/rendering/renderer_rd/environment/sky.h"
#include "servers/rendering/renderer_rd/storage_rd/forward_id_storage.h"
#include "servers/rendering/renderer_rd/storage_rd/render_scene_buffers_rd.h"
#include "servers/rendering/renderer_rd/storage_rd/texture_storage.h"
#include "servers/rendering/storage/light_storage.h"
#include "servers/rendering/storage/utilities.h"
@ -256,6 +257,8 @@ private:
Vector<Reflection> reflections;
Ref<RenderSceneBuffersRD> render_buffers; // Further render buffers used.
ClusterBuilderRD *cluster_builder = nullptr; // only used if cluster builder is supported by the renderer.
};
@ -846,6 +849,7 @@ public:
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) override;
virtual bool reflection_probe_instance_has_reflection(RID p_instance) override;
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) override;
virtual Ref<RenderSceneBuffers> reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) override;
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) override;
uint32_t reflection_probe_instance_get_resolution(RID p_instance);

View file

@ -207,6 +207,21 @@ void RenderSceneBuffersRD::configure(RID p_render_target, const Size2i p_interna
}
}
void RenderSceneBuffersRD::configure_for_reflections(const Size2i p_reflection_size) {
// For now our render buffers for reflections are only used for effects/environment (Sky/Fog/Etc)
// Possibly at some point move our entire reflection atlas buffer management into this class
target_size = p_reflection_size;
internal_size = p_reflection_size;
render_target = RID();
fsr_sharpness = 0.0;
msaa_3d = RS::VIEWPORT_MSAA_DISABLED;
screen_space_aa = RS::VIEWPORT_SCREEN_SPACE_AA_DISABLED;
use_taa = false;
use_debanding = false;
view_count = 1;
}
void RenderSceneBuffersRD::set_fsr_sharpness(float p_fsr_sharpness) {
fsr_sharpness = p_fsr_sharpness;
}
@ -483,6 +498,10 @@ void RenderSceneBuffersRD::set_custom_data(const StringName &p_name, Ref<RenderB
}
Ref<RenderBufferCustomDataRD> RenderSceneBuffersRD::get_custom_data(const StringName &p_name) const {
if (!data_buffers.has(p_name)) {
print_line("test");
}
ERR_FAIL_COND_V(!data_buffers.has(p_name), Ref<RenderBufferCustomDataRD>());
Ref<RenderBufferCustomDataRD> ret = data_buffers[p_name];

View file

@ -140,6 +140,7 @@ public:
void cleanup();
virtual void configure(RID p_render_target, const Size2i p_internal_size, const Size2i p_target_size, float p_fsr_sharpness, float p_texture_mipmap_bias, RS::ViewportMSAA p_msaa_3d, RenderingServer::ViewportScreenSpaceAA p_screen_space_aa, bool p_use_taa, bool p_use_debanding, uint32_t p_view_count) override;
void configure_for_reflections(const Size2i p_reflection_size);
virtual void set_fsr_sharpness(float p_fsr_sharpness) override;
virtual void set_texture_mipmap_bias(float p_texture_mipmap_bias) override;
virtual void set_use_debanding(bool p_use_debanding) override;

View file

@ -2930,7 +2930,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
scene_render->set_scene_pass(render_pass);
if (p_render_buffers.is_valid()) {
if (p_render_buffers.is_valid() && p_reflection_probe.is_null()) {
//no rendering code here, this is only to set up what needs to be done, request regions, etc.
scene_render->sdfgi_update(p_render_buffers, p_environment, p_camera_data->main_transform.origin); //update conditions for SDFGI (whether its used or not)
}
@ -3012,7 +3012,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
{ //sdfgi
cull.sdfgi.region_count = 0;
if (p_render_buffers.is_valid()) {
if (p_render_buffers.is_valid() && p_reflection_probe.is_null()) {
cull.sdfgi.cascade_light_count = 0;
uint32_t prev_cascade = 0xFFFFFFFF;
@ -3214,6 +3214,8 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
//render SDFGI
{
// Q: Should this whole block be skipped if we're rendering our reflection probe?
sdfgi_update_data.update_static = false;
if (cull.sdfgi.region_count > 0) {
@ -3239,7 +3241,7 @@ void RendererSceneCull::_render_scene(const RendererSceneRender::CameraData *p_c
}
}
if (p_render_buffers.is_valid()) {
if (p_render_buffers.is_valid() && p_reflection_probe.is_null()) {
sdfgi_update_data.directional_lights = &directional_lights;
sdfgi_update_data.positional_light_instances = scenario->dynamic_lights.ptr();
sdfgi_update_data.positional_light_count = scenario->dynamic_lights.size();
@ -3392,7 +3394,7 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
RendererSceneRender::CameraData camera_data;
camera_data.set_camera(xform, cm, false, false);
Ref<RenderSceneBuffers> render_buffers;
Ref<RenderSceneBuffers> render_buffers = RSG::light_storage->reflection_probe_atlas_get_render_buffers(scenario->reflection_atlas);
_render_scene(&camera_data, render_buffers, environment, RID(), RSG::light_storage->reflection_probe_get_cull_mask(p_instance->base), p_instance->scenario->self, RID(), shadow_atlas, reflection_probe->instance, p_step, mesh_lod_threshold, use_shadows);
} else {

View file

@ -31,6 +31,7 @@
#ifndef LIGHT_STORAGE_H
#define LIGHT_STORAGE_H
#include "render_scene_buffers.h"
#include "servers/rendering_server.h"
class RendererLightStorage {
@ -142,6 +143,7 @@ public:
virtual bool reflection_probe_instance_needs_redraw(RID p_instance) = 0;
virtual bool reflection_probe_instance_has_reflection(RID p_instance) = 0;
virtual bool reflection_probe_instance_begin_render(RID p_instance, RID p_reflection_atlas) = 0;
virtual Ref<RenderSceneBuffers> reflection_probe_atlas_get_render_buffers(RID p_reflection_atlas) = 0;
virtual bool reflection_probe_instance_postprocess_step(RID p_instance) = 0;
/* LIGHTMAP */