mirror of
https://github.com/godotengine/godot.git
synced 2024-11-25 13:43:15 +00:00
Fix volumetric fog in stereo by projection vertex in combined space
This commit is contained in:
parent
116f783db7
commit
66272ea26e
@ -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());
|
||||
@ -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;
|
||||
|
@ -139,26 +139,27 @@ private:
|
||||
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
|
||||
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 - 164
|
||||
float volumetric_fog_inv_length; // 4 - 168
|
||||
float volumetric_fog_detail_spread; // 4 - 172
|
||||
float volumetric_fog_sky_affect; // 4 - 176
|
||||
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 - 180
|
||||
float fog_sky_affect; // 4 - 184
|
||||
float fog_density; // 4 - 188
|
||||
float fog_sun_scatter; // 4 - 192
|
||||
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 - 204
|
||||
float fog_aerial_perspective; // 4 - 208
|
||||
float fog_light_color[3]; // 12 - 332
|
||||
float fog_aerial_perspective; // 4 - 336
|
||||
|
||||
float z_far; // 4 - 212
|
||||
uint32_t directional_light_count; // 4 - 216
|
||||
uint32_t pad1; // 4 - 220
|
||||
uint32_t pad2; // 4 - 224
|
||||
float z_far; // 4 - 340
|
||||
uint32_t directional_light_count; // 4 - 344
|
||||
uint32_t pad1; // 4 - 348
|
||||
uint32_t pad2; // 4 - 352
|
||||
};
|
||||
|
||||
UBO ubo;
|
||||
@ -295,7 +296,7 @@ public:
|
||||
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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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];
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
@ -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;
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user