Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Fix volumetric fog in stereo by projection vertex in combined space #78436

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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions servers/rendering/renderer_rd/environment/sky.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1014,7 +1014,7 @@ SkyRD::~SkyRD() {
RD::get_singleton()->free(index_buffer); //array gets freed as dependency
}

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) {
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 Projection &p_cam_projection, 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());
Expand Down Expand Up @@ -1212,11 +1212,19 @@ void SkyRD::setup_sky(RID p_env, Ref<RenderSceneBuffersRD> p_render_buffers, con

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
sky_scene_state.cam_projection = p_cam_projection; // 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]);
Projection view_inv_projection = p_view_projections[i].inverse();
if (p_view_count > 1) {
RendererRD::MaterialStorage::store_camera(p_cam_projection * view_inv_projection, sky_scene_state.ubo.combined_reprojection[i]);
} else {
Projection ident;
RendererRD::MaterialStorage::store_camera(ident, sky_scene_state.ubo.combined_reprojection[i]);
}

RendererRD::MaterialStorage::store_camera(view_inv_projection, 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;
Expand Down
43 changes: 22 additions & 21 deletions servers/rendering/renderer_rd/environment/sky.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,26 +139,27 @@ class SkyRD {
public:
struct SkySceneState {
struct UBO {
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 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

uint32_t fog_enabled; // 4 - 180
float fog_sky_affect; // 4 - 184
float fog_density; // 4 - 188
float fog_sun_scatter; // 4 - 192

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
float combined_reprojection[RendererSceneRender::MAX_RENDER_VIEWS][16]; // 2 x 64 - 128
float view_inv_projections[RendererSceneRender::MAX_RENDER_VIEWS][16]; // 2 x 64 - 256
float view_eye_offsets[RendererSceneRender::MAX_RENDER_VIEWS][4]; // 2 x 16 - 288

uint32_t volumetric_fog_enabled; // 4 - 292
float volumetric_fog_inv_length; // 4 - 296
float volumetric_fog_detail_spread; // 4 - 300
float volumetric_fog_sky_affect; // 4 - 304

uint32_t fog_enabled; // 4 - 308
float fog_sky_affect; // 4 - 312
float fog_density; // 4 - 316
float fog_sun_scatter; // 4 - 320

float fog_light_color[3]; // 12 - 332
float fog_aerial_perspective; // 4 - 336

float z_far; // 4 - 340
uint32_t directional_light_count; // 4 - 344
uint32_t pad1; // 4 - 348
uint32_t pad2; // 4 - 352
};

UBO ubo;
Expand Down Expand Up @@ -295,7 +296,7 @@ class SkyRD {
void set_texture_format(RD::DataFormat p_texture_format);
~SkyRD();

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 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 Projection &p_cam_projection, 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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1800,9 +1800,9 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
correction.set_depth_correction(true);
Projection projection = correction * p_render_data->scene_data->cam_projection;

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);
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, projection, 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.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, p_render_data->scene_data->cam_projection, screen_size, this);
}

sky_energy_multiplier *= bg_energy_multiplier;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -856,9 +856,9 @@ void RenderForwardMobile::_render_scene(RenderDataRD *p_render_data, const Color
correction.set_depth_correction(true);
Projection projection = correction * p_render_data->scene_data->cam_projection;

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);
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, projection, 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.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, p_render_data->scene_data->cam_projection, screen_size, this);
}

sky_energy_multiplier *= bg_energy_multiplier;
Expand Down
6 changes: 6 additions & 0 deletions servers/rendering/renderer_rd/shaders/environment/sky.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ layout(set = 0, binding = 1, std430) restrict readonly buffer GlobalShaderUnifor
global_shader_uniforms;

layout(set = 0, binding = 2, std140) uniform SkySceneData {
mat4 combined_reprojection[2];
mat4 view_inv_projections[2];
vec4 view_eye_offsets[2];

Expand Down Expand Up @@ -169,7 +170,12 @@ vec3 interleaved_gradient_noise(vec2 pos) {
#endif

vec4 volumetric_fog_process(vec2 screen_uv) {
#ifdef USE_MULTIVIEW
vec4 reprojected = sky_scene_data.combined_reprojection[ViewIndex] * (vec4(screen_uv * 2.0 - 1.0, 1.0, 1.0) * sky_scene_data.z_far);
vec3 fog_pos = vec3(reprojected.xy / reprojected.w, 1.0) * 0.5 + 0.5;
#else
vec3 fog_pos = vec3(screen_uv, 1.0);
#endif

return texture(sampler3D(volumetric_fog_texture, material_samplers[SAMPLER_LINEAR_CLAMP]), fog_pos);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ layout(location = 10) out flat uint instance_index_interp;
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
layout(location = 11) out vec4 combined_projected;
#else // USE_MULTIVIEW
// Set to zero, not supported in non stereo
#define ViewIndex 0
Expand Down Expand Up @@ -313,6 +314,7 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
#endif

#ifdef USE_MULTIVIEW
mat4 combined_projection = scene_data.projection_matrix;
mat4 projection_matrix = scene_data.projection_matrix_view[ViewIndex];
mat4 inv_projection_matrix = scene_data.inv_projection_matrix_view[ViewIndex];
vec3 eye_offset = scene_data.eye_offset[ViewIndex].xyz;
Expand Down Expand Up @@ -434,6 +436,10 @@ void vertex_shader(in uint instance_index, in bool is_multimesh, in uint multime
gl_Position = projection_matrix * vec4(vertex_interp, 1.0);
#endif

#ifdef USE_MULTIVIEW
combined_projected = combined_projection * vec4(vertex_interp, 1.0);
#endif

#ifdef MOTION_VECTORS
screen_pos = gl_Position;
#endif
Expand Down Expand Up @@ -557,6 +563,7 @@ layout(location = 10) in flat uint instance_index_interp;
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
layout(location = 11) in vec4 combined_projected;
#else // USE_MULTIVIEW
// Set to zero, not supported in non stereo
#define ViewIndex 0
Expand Down Expand Up @@ -913,7 +920,12 @@ void fragment_shader(in SceneData scene_data) {
}

if (implementation_data.volumetric_fog_enabled) {
#ifdef USE_MULTIVIEW
vec2 center_uv = (combined_projected.xy / combined_projected.w) * 0.5 + 0.5;
vec4 volumetric_fog = volumetric_fog_process(center_uv, -vertex.z);
#else
vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z);
#endif
if (scene_data.fog_enabled) {
//must use the full blending equation here to blend fogs
vec4 res;
Expand Down