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

Apply reprojection in multiview for our cluster lookup #78499

Merged
merged 1 commit into from
Jun 21, 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
Original file line number Diff line number Diff line change
Expand Up @@ -1451,6 +1451,11 @@ void RenderForwardClustered::_pre_opaque_render(RenderDataRD *p_render_data, boo
RD::get_singleton()->barrier(RD::BARRIER_MASK_ALL_BARRIERS, RD::BARRIER_MASK_ALL_BARRIERS);

if (current_cluster_builder) {
// Note: when rendering stereoscopic (multiview) we are using our combined frustum projection to create
// our cluster data. We use reprojection in the shader to adjust for our left/right eye.
// This only works as we don't filter our cluster by depth buffer.
// If we ever make this optimisation we should make it optional and only use it in mono.
// What we win by filtering out a few lights, we loose by having to do the work double for stereo.
current_cluster_builder->begin(p_render_data->scene_data->cam_transform, p_render_data->scene_data->cam_projection, !p_render_data->reflection_probe.is_valid());
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,10 @@ void fragment_shader(in SceneData scene_data) {
#ifdef USE_MULTIVIEW
vec3 eye_offset = scene_data.eye_offset[ViewIndex].xyz;
vec3 view = -normalize(vertex_interp - eye_offset);

// UV in our combined frustum space is used for certain screen uv processes where it's
// overkill to render separate left and right eye views
vec2 combined_uv = (combined_projected.xy / combined_projected.w) * 0.5 + 0.5;
#else
vec3 eye_offset = vec3(0.0, 0.0, 0.0);
vec3 view = -normalize(vertex_interp);
Expand Down Expand Up @@ -921,8 +925,7 @@ 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);
vec4 volumetric_fog = volumetric_fog_process(combined_uv, -vertex.z);
#else
vec4 volumetric_fog = volumetric_fog_process(screen_uv, -vertex.z);
#endif
Expand Down Expand Up @@ -952,7 +955,11 @@ void fragment_shader(in SceneData scene_data) {

#ifndef MODE_RENDER_DEPTH

#ifdef USE_MULTIVIEW
uvec2 cluster_pos = uvec2(combined_uv.xy / scene_data.screen_pixel_size) >> implementation_data.cluster_shift;
#else
uvec2 cluster_pos = uvec2(gl_FragCoord.xy) >> implementation_data.cluster_shift;
#endif
uint cluster_offset = (implementation_data.cluster_width * cluster_pos.y + cluster_pos.x) * (implementation_data.max_cluster_element_count_div_32 + 32);

uint cluster_z = uint(clamp((-vertex.z / scene_data.z_far) * 32.0, 0.0, 31.0));
Expand Down