mirror of
https://github.com/godotengine/godot.git
synced 2024-11-10 22:23:07 +00:00
Cleanup and improve sky render
This commit is contained in:
parent
291add339f
commit
e886a7af81
@ -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;
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user