Add multiview/stereoscopic rendering support to the clustered forward renderer

This commit is contained in:
Bastiaan Olij 2021-05-26 15:50:10 +10:00
parent 62765fb7ca
commit e4b7a69bb6
6 changed files with 127 additions and 31 deletions

View File

@ -186,12 +186,11 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::clear() {
void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) { void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_color_buffer, RID p_depth_buffer, RID p_target_buffer, int p_width, int p_height, RS::ViewportMSAA p_msaa, uint32_t p_view_count) {
clear(); clear();
ERR_FAIL_COND_MSG(p_view_count != 1, "Multiple views is currently not supported in this renderer, please use the mobile renderer for VR support");
msaa = p_msaa; msaa = p_msaa;
width = p_width; width = p_width;
height = p_height; height = p_height;
view_count = p_view_count;
color = p_color_buffer; color = p_color_buffer;
depth = p_depth_buffer; depth = p_depth_buffer;
@ -202,20 +201,25 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
fb.push_back(p_color_buffer); fb.push_back(p_color_buffer);
fb.push_back(depth); fb.push_back(depth);
color_fb = RD::get_singleton()->framebuffer_create(fb); color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
} }
{ {
Vector<RID> fb; Vector<RID> fb;
fb.push_back(depth); fb.push_back(depth);
depth_fb = RD::get_singleton()->framebuffer_create(fb); depth_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
} }
} else { } else {
RD::TextureFormat tf; RD::TextureFormat tf;
if (view_count > 1) {
tf.texture_type = RD::TEXTURE_TYPE_2D_ARRAY;
} else {
tf.texture_type = RD::TEXTURE_TYPE_2D;
}
tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT; tf.format = RD::DATA_FORMAT_R16G16B16A16_SFLOAT;
tf.width = p_width; tf.width = p_width;
tf.height = p_height; tf.height = p_height;
tf.texture_type = RD::TEXTURE_TYPE_2D; tf.array_layers = view_count; // create a layer for every view
tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT; tf.usage_bits = RD::TEXTURE_USAGE_COLOR_ATTACHMENT_BIT | RD::TEXTURE_USAGE_CAN_COPY_FROM_BIT | RD::TEXTURE_USAGE_SAMPLING_BIT;
RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = { RD::TextureSamples ts[RS::VIEWPORT_MSAA_MAX] = {
@ -240,13 +244,13 @@ void RenderForwardClustered::RenderBufferDataForwardClustered::configure(RID p_c
fb.push_back(color_msaa); fb.push_back(color_msaa);
fb.push_back(depth_msaa); fb.push_back(depth_msaa);
color_fb = RD::get_singleton()->framebuffer_create(fb); color_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
} }
{ {
Vector<RID> fb; Vector<RID> fb;
fb.push_back(depth_msaa); fb.push_back(depth_msaa);
depth_fb = RD::get_singleton()->framebuffer_create(fb); depth_fb = RD::get_singleton()->framebuffer_create(fb, RenderingDevice::INVALID_ID, view_count);
} }
} }
} }
@ -416,22 +420,23 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
switch (p_pass_mode) { switch (p_pass_mode) {
case PASS_MODE_COLOR: { case PASS_MODE_COLOR: {
if (element_info.uses_lightmap) { if (element_info.uses_lightmap) {
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS; pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS;
} else { } else {
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS; pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_OPAQUE_PASS;
} }
} break; } break;
case PASS_MODE_COLOR_TRANSPARENT: { case PASS_MODE_COLOR_TRANSPARENT: {
if (element_info.uses_lightmap) { if (element_info.uses_lightmap) {
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS; pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS;
} else { } else {
if (element_info.uses_forward_gi) { if (element_info.uses_forward_gi) {
pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_FORWARD_GI; pipeline_specialization |= SceneShaderForwardClustered::SHADER_SPECIALIZATION_FORWARD_GI;
} }
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS; pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_TRANSPARENT_PASS;
} }
} break; } break;
case PASS_MODE_COLOR_SPECULAR: { case PASS_MODE_COLOR_SPECULAR: {
ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for specular pass");
if (element_info.uses_lightmap) { if (element_info.uses_lightmap) {
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR; pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR;
} else { } else {
@ -440,21 +445,26 @@ void RenderForwardClustered::_render_list_template(RenderingDevice::DrawListID p
} break; } break;
case PASS_MODE_SHADOW: case PASS_MODE_SHADOW:
case PASS_MODE_DEPTH: { case PASS_MODE_DEPTH: {
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS; pipeline_version = p_params->view_count > 1 ? SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW : SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS;
} break; } break;
case PASS_MODE_SHADOW_DP: { case PASS_MODE_SHADOW_DP: {
ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for shadow DP pass");
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_DP; pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_DP;
} break; } break;
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: { case PASS_MODE_DEPTH_NORMAL_ROUGHNESS: {
ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for depth/roughness pass");
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS; pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS;
} break; } break;
case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: { case PASS_MODE_DEPTH_NORMAL_ROUGHNESS_VOXEL_GI: {
ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for voxel GI pass");
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI; pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS_AND_VOXEL_GI;
} break; } break;
case PASS_MODE_DEPTH_MATERIAL: { case PASS_MODE_DEPTH_MATERIAL: {
ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for material pass");
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL; pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_MATERIAL;
} break; } break;
case PASS_MODE_SDF: { case PASS_MODE_SDF: {
ERR_FAIL_COND_MSG(p_params->view_count > 1, "Multiview not supported for SDF pass");
pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_SDF; pipeline_version = SceneShaderForwardClustered::PIPELINE_VERSION_DEPTH_PASS_WITH_SDF;
} break; } break;
} }
@ -604,6 +614,12 @@ void RenderForwardClustered::_setup_environment(const RenderDataRD *p_render_dat
RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.camera_matrix); RendererStorageRD::store_transform(p_render_data->cam_transform, scene_state.ubo.camera_matrix);
RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix); RendererStorageRD::store_transform(p_render_data->cam_transform.affine_inverse(), scene_state.ubo.inv_camera_matrix);
for (uint32_t v = 0; v < p_render_data->view_count; v++) {
projection = correction * p_render_data->view_projection[v];
RendererStorageRD::store_camera(projection, scene_state.ubo.projection_matrix_view[v]);
RendererStorageRD::store_camera(projection.inverse(), scene_state.ubo.inv_projection_matrix_view[v]);
}
scene_state.ubo.z_far = p_render_data->z_far; scene_state.ubo.z_far = p_render_data->z_far;
scene_state.ubo.z_near = p_render_data->z_near; scene_state.ubo.z_near = p_render_data->z_near;
@ -1200,8 +1216,6 @@ void RenderForwardClustered::_setup_lightmaps(const PagedArray<RID> &p_lightmaps
} }
void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) { void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Color &p_default_bg_color) {
ERR_FAIL_COND_MSG(p_render_data->view_count != 1, "Multiview is currently not supported in the clustered renderer. Please use the mobile renderer for VR.");
RenderBufferDataForwardClustered *render_buffer = nullptr; RenderBufferDataForwardClustered *render_buffer = nullptr;
if (p_render_data->render_buffers.is_valid()) { if (p_render_data->render_buffers.is_valid()) {
render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers); render_buffer = (RenderBufferDataForwardClustered *)render_buffers_get_data(p_render_data->render_buffers);
@ -1434,7 +1448,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID()); RID rp_uniform_set = _setup_render_pass_uniform_set(RENDER_LIST_OPAQUE, nullptr, RID());
bool finish_depth = using_ssao || using_sdfgi || using_voxelgi; bool finish_depth = using_ssao || using_sdfgi || using_voxelgi;
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold); RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, depth_pass_mode, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
_render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear); _render_list_with_threads(&render_list_params, depth_framebuffer, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, RD::FINAL_ACTION_READ, needs_pre_resolve ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_CLEAR, finish_depth ? RD::FINAL_ACTION_READ : RD::FINAL_ACTION_CONTINUE, needs_pre_resolve ? Vector<Color>() : depth_pass_clear);
RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_command_end_label();
@ -1492,7 +1506,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
} }
RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer; RID framebuffer = using_separate_specular ? opaque_specular_framebuffer : opaque_framebuffer;
RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold); RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].element_info.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, using_separate_specular ? PASS_MODE_COLOR_SPECULAR : PASS_MODE_COLOR, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
_render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0); _render_list_with_threads(&render_list_params, framebuffer, keep_color ? RD::INITIAL_ACTION_KEEP : RD::INITIAL_ACTION_CLEAR, will_continue_color ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, depth_pre_pass ? (continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP) : RD::INITIAL_ACTION_CLEAR, will_continue_depth ? RD::FINAL_ACTION_CONTINUE : RD::FINAL_ACTION_READ, c, 1.0, 0);
if (will_continue_color && using_separate_specular) { if (will_continue_color && using_separate_specular) {
// close the specular framebuffer, as it's no longer used // close the specular framebuffer, as it's no longer used
@ -1538,14 +1552,16 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
if (draw_sky || draw_sky_fog_only) { if (draw_sky || draw_sky_fog_only) {
RENDER_TIMESTAMP("Render Sky"); RENDER_TIMESTAMP("Render Sky");
CameraMatrix projection = p_render_data->cam_projection; RD::get_singleton()->draw_command_begin_label("Draw Sky");
if (p_render_data->reflection_probe.is_valid()) { if (p_render_data->reflection_probe.is_valid()) {
CameraMatrix correction; CameraMatrix correction;
correction.set_depth_correction(true); correction.set_depth_correction(true);
projection = correction * p_render_data->cam_projection; CameraMatrix projection = correction * p_render_data->cam_projection;
}
RD::get_singleton()->draw_command_begin_label("Draw Sky");
sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, 1, &projection, p_render_data->cam_transform, time); sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, 1, &projection, p_render_data->cam_transform, time);
} else {
sky.draw(env, can_continue_color, can_continue_depth, opaque_framebuffer, p_render_data->view_count, p_render_data->view_projection, p_render_data->cam_transform, time);
}
RD::get_singleton()->draw_command_end_label(); RD::get_singleton()->draw_command_end_label();
} }
@ -1599,7 +1615,7 @@ void RenderForwardClustered::_render_scene(RenderDataRD *p_render_data, const Co
_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); _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);
{ {
RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR_TRANSPARENT, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold); RenderListParameters render_list_params(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].element_info.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), false, PASS_MODE_COLOR_TRANSPARENT, render_buffer == nullptr, p_render_data->directional_light_soft_shadows, rp_uniform_set, get_debug_draw_mode() == RS::VIEWPORT_DEBUG_DRAW_WIREFRAME, Vector2(), p_render_data->lod_camera_plane, p_render_data->lod_distance_multiplier, p_render_data->screen_mesh_lod_threshold, p_render_data->view_count);
_render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ); _render_list_with_threads(&render_list_params, alpha_framebuffer, can_continue_color ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ, can_continue_depth ? RD::INITIAL_ACTION_CONTINUE : RD::INITIAL_ACTION_KEEP, RD::FINAL_ACTION_READ);
} }
@ -1649,6 +1665,7 @@ void RenderForwardClustered::_render_shadow_append(RID p_framebuffer, const Page
RenderDataRD render_data; RenderDataRD render_data;
render_data.cam_projection = p_projection; render_data.cam_projection = p_projection;
render_data.cam_transform = p_transform; render_data.cam_transform = p_transform;
render_data.view_projection[0] = p_projection;
render_data.z_far = p_zfar; render_data.z_far = p_zfar;
render_data.z_near = 0.0; render_data.z_near = 0.0;
render_data.cluster_size = 1; render_data.cluster_size = 1;
@ -1720,7 +1737,7 @@ void RenderForwardClustered::_render_shadow_end(uint32_t p_barrier) {
for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) { for (uint32_t i = 0; i < scene_state.shadow_passes.size(); i++) {
SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i]; SceneState::ShadowPass &shadow_pass = scene_state.shadow_passes[i];
RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER); RenderListParameters render_list_parameters(render_list[RENDER_LIST_SECONDARY].elements.ptr() + shadow_pass.element_from, render_list[RENDER_LIST_SECONDARY].element_info.ptr() + shadow_pass.element_from, shadow_pass.element_count, shadow_pass.flip_cull, shadow_pass.pass_mode, true, false, shadow_pass.rp_uniform_set, false, Vector2(), shadow_pass.camera_plane, shadow_pass.lod_distance_multiplier, shadow_pass.screen_mesh_lod_threshold, 1, shadow_pass.element_from, RD::BARRIER_MASK_NO_BARRIER);
_render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect); _render_list_with_threads(&render_list_parameters, shadow_pass.framebuffer, RD::INITIAL_ACTION_DROP, RD::FINAL_ACTION_DISCARD, shadow_pass.initial_depth_action, shadow_pass.final_depth_action, Vector<Color>(), 1.0, 0, shadow_pass.rect);
} }
@ -1738,6 +1755,7 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con
RenderDataRD render_data; RenderDataRD render_data;
render_data.cam_projection = p_cam_projection; render_data.cam_projection = p_cam_projection;
render_data.cam_transform = p_cam_transform; render_data.cam_transform = p_cam_transform;
render_data.view_projection[0] = p_cam_projection;
render_data.z_near = 0.0; render_data.z_near = 0.0;
render_data.z_far = p_cam_projection.get_z_far(); render_data.z_far = p_cam_projection.get_z_far();
render_data.cluster_size = 1; render_data.cluster_size = 1;
@ -1776,6 +1794,7 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform
RenderDataRD render_data; RenderDataRD render_data;
render_data.cam_projection = p_cam_projection; render_data.cam_projection = p_cam_projection;
render_data.cam_transform = p_cam_transform; render_data.cam_transform = p_cam_transform;
render_data.view_projection[0] = p_cam_projection;
render_data.cluster_size = 1; render_data.cluster_size = 1;
render_data.cluster_max_elements = 32; render_data.cluster_max_elements = 32;
render_data.instances = &p_instances; render_data.instances = &p_instances;

View File

@ -107,6 +107,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
RID color_specular_fb; RID color_specular_fb;
RID specular_only_fb; RID specular_only_fb;
int width, height; int width, height;
uint32_t view_count;
RID render_sdfgi_uniform_set; RID render_sdfgi_uniform_set;
void ensure_specular(); void ensure_specular();
@ -157,6 +158,7 @@ class RenderForwardClustered : public RendererSceneRenderRD {
bool reverse_cull = false; bool reverse_cull = false;
PassMode pass_mode = PASS_MODE_COLOR; PassMode pass_mode = PASS_MODE_COLOR;
bool no_gi = false; bool no_gi = false;
uint32_t view_count = 1;
RID render_pass_uniform_set; RID render_pass_uniform_set;
bool force_wireframe = false; bool force_wireframe = false;
Vector2 uv_offset; Vector2 uv_offset;
@ -168,13 +170,14 @@ class RenderForwardClustered : public RendererSceneRenderRD {
uint32_t barrier = RD::BARRIER_MASK_ALL; uint32_t barrier = RD::BARRIER_MASK_ALL;
bool use_directional_soft_shadow = false; bool use_directional_soft_shadow = false;
RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) { RenderListParameters(GeometryInstanceSurfaceDataCache **p_elements, RenderElementInfo *p_element_info, int p_element_count, bool p_reverse_cull, PassMode p_pass_mode, bool p_no_gi, bool p_use_directional_soft_shadows, RID p_render_pass_uniform_set, bool p_force_wireframe = false, const Vector2 &p_uv_offset = Vector2(), const Plane &p_lod_plane = Plane(), float p_lod_distance_multiplier = 0.0, float p_screen_mesh_lod_threshold = 0.0, uint32_t p_view_count = 1, uint32_t p_element_offset = 0, uint32_t p_barrier = RD::BARRIER_MASK_ALL) {
elements = p_elements; elements = p_elements;
element_info = p_element_info; element_info = p_element_info;
element_count = p_element_count; element_count = p_element_count;
reverse_cull = p_reverse_cull; reverse_cull = p_reverse_cull;
pass_mode = p_pass_mode; pass_mode = p_pass_mode;
no_gi = p_no_gi; no_gi = p_no_gi;
view_count = p_view_count;
render_pass_uniform_set = p_render_pass_uniform_set; render_pass_uniform_set = p_render_pass_uniform_set;
force_wireframe = p_force_wireframe; force_wireframe = p_force_wireframe;
uv_offset = p_uv_offset; uv_offset = p_uv_offset;
@ -221,6 +224,9 @@ class RenderForwardClustered : public RendererSceneRenderRD {
float camera_matrix[16]; float camera_matrix[16];
float inv_camera_matrix[16]; float inv_camera_matrix[16];
float projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
float inv_projection_matrix_view[RendererSceneRender::MAX_RENDER_VIEWS][16];
float viewport_size[2]; float viewport_size[2];
float screen_pixel_size[2]; float screen_pixel_size[2];

View File

@ -32,6 +32,7 @@
#include "core/config/project_settings.h" #include "core/config/project_settings.h"
#include "core/math/math_defs.h" #include "core/math/math_defs.h"
#include "render_forward_clustered.h" #include "render_forward_clustered.h"
#include "servers/rendering/renderer_rd/renderer_compositor_rd.h"
using namespace RendererSceneRenderImplementation; using namespace RendererSceneRenderImplementation;
@ -282,6 +283,12 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
SHADER_VERSION_LIGHTMAP_COLOR_PASS, SHADER_VERSION_LIGHTMAP_COLOR_PASS,
SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR, SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
SHADER_VERSION_LIGHTMAP_COLOR_PASS, SHADER_VERSION_LIGHTMAP_COLOR_PASS,
SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
SHADER_VERSION_COLOR_PASS_MULTIVIEW,
SHADER_VERSION_COLOR_PASS_MULTIVIEW,
SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
}; };
shader_version = shader_version_table[k]; shader_version = shader_version_table[k];
@ -297,7 +304,7 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
RD::PipelineDepthStencilState depth_stencil = depth_stencil_state; RD::PipelineDepthStencilState depth_stencil = depth_stencil_state;
RD::PipelineMultisampleState multisample_state; RD::PipelineMultisampleState multisample_state;
if (k == PIPELINE_VERSION_TRANSPARENT_PASS || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS) { if (k == PIPELINE_VERSION_TRANSPARENT_PASS || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS || k == PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW || k == PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW) {
if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) { if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE) {
multisample_state.enable_alpha_to_coverage = true; multisample_state.enable_alpha_to_coverage = true;
} else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) { } else if (alpha_antialiasing_mode == ALPHA_ANTIALIASING_ALPHA_TO_COVERAGE_AND_TO_ONE) {
@ -310,9 +317,9 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) {
if (depth_draw == DEPTH_DRAW_OPAQUE) { if (depth_draw == DEPTH_DRAW_OPAQUE) {
depth_stencil.enable_depth_write = false; //alpha does not draw depth depth_stencil.enable_depth_write = false; //alpha does not draw depth
} }
} else if (k == PIPELINE_VERSION_OPAQUE_PASS || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS) { } else if (k == PIPELINE_VERSION_OPAQUE_PASS || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS || k == PIPELINE_VERSION_OPAQUE_PASS_MULTIVIEW || k == PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW) {
blend_state = blend_state_opaque; blend_state = blend_state_opaque;
} else if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_DP) { } else if (k == PIPELINE_VERSION_DEPTH_PASS || k == PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW || k == PIPELINE_VERSION_DEPTH_PASS_DP) {
//none, leave empty //none, leave empty
} else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) { } else if (k == PIPELINE_VERSION_DEPTH_PASS_WITH_NORMAL_AND_ROUGHNESS) {
blend_state = blend_state_depth_normal_roughness; blend_state = blend_state_depth_normal_roughness;
@ -501,7 +508,18 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
shader_versions.push_back("\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS shader_versions.push_back("\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS
shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR shader_versions.push_back("\n#define MODE_MULTIPLE_RENDER_TARGETS\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR
// multiview versions of our shaders
shader_versions.push_back("\n#define USE_MULTIVIEW\n#define MODE_RENDER_DEPTH\n"); // SHADER_VERSION_DEPTH_PASS_MULTIVIEW
shader_versions.push_back("\n#define USE_MULTIVIEW\n"); // SHADER_VERSION_COLOR_PASS_MULTIVIEW
shader_versions.push_back("\n#define USE_MULTIVIEW\n#define USE_LIGHTMAP\n"); // SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW
shader.initialize(shader_versions, p_defines); shader.initialize(shader_versions, p_defines);
if (!RendererCompositorRD::singleton->is_xr_enabled()) {
shader.set_variant_enabled(SHADER_VERSION_DEPTH_PASS_MULTIVIEW, false);
shader.set_variant_enabled(SHADER_VERSION_COLOR_PASS_MULTIVIEW, false);
shader.set_variant_enabled(SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW, false);
}
} }
storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs); storage->shader_set_data_request_function(RendererStorageRD::SHADER_TYPE_3D, _create_shader_funcs);
@ -516,7 +534,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.renames["INV_CAMERA_MATRIX"] = "scene_data.inv_camera_matrix"; actions.renames["INV_CAMERA_MATRIX"] = "scene_data.inv_camera_matrix";
actions.renames["CAMERA_MATRIX"] = "scene_data.camera_matrix"; actions.renames["CAMERA_MATRIX"] = "scene_data.camera_matrix";
actions.renames["PROJECTION_MATRIX"] = "projection_matrix"; actions.renames["PROJECTION_MATRIX"] = "projection_matrix";
actions.renames["INV_PROJECTION_MATRIX"] = "scene_data.inv_projection_matrix"; actions.renames["INV_PROJECTION_MATRIX"] = "inv_projection_matrix";
actions.renames["MODELVIEW_MATRIX"] = "modelview"; actions.renames["MODELVIEW_MATRIX"] = "modelview";
actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal"; actions.renames["MODELVIEW_NORMAL_MATRIX"] = "modelview_normal";
@ -587,8 +605,7 @@ void SceneShaderForwardClustered::init(RendererStorageRD *p_storage, const Strin
actions.renames["CUSTOM3"] = "custom3_attrib"; actions.renames["CUSTOM3"] = "custom3_attrib";
actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB"; actions.renames["OUTPUT_IS_SRGB"] = "SHADER_IS_SRGB";
// not implemented but need these just in case code is in the shaders actions.renames["VIEW_INDEX"] = "ViewIndex";
actions.renames["VIEW_INDEX"] = "0";
actions.renames["VIEW_MONO_LEFT"] = "0"; actions.renames["VIEW_MONO_LEFT"] = "0";
actions.renames["VIEW_RIGHT"] = "1"; actions.renames["VIEW_RIGHT"] = "1";

View File

@ -55,6 +55,11 @@ public:
SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR, SHADER_VERSION_COLOR_PASS_WITH_SEPARATE_SPECULAR,
SHADER_VERSION_LIGHTMAP_COLOR_PASS, SHADER_VERSION_LIGHTMAP_COLOR_PASS,
SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR, SHADER_VERSION_LIGHTMAP_COLOR_PASS_WITH_SEPARATE_SPECULAR,
SHADER_VERSION_DEPTH_PASS_MULTIVIEW,
SHADER_VERSION_COLOR_PASS_MULTIVIEW,
SHADER_VERSION_LIGHTMAP_COLOR_PASS_MULTIVIEW,
SHADER_VERSION_MAX SHADER_VERSION_MAX
}; };
@ -71,6 +76,13 @@ public:
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS, PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS,
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR, PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_WITH_SEPARATE_SPECULAR,
PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS, PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS,
PIPELINE_VERSION_DEPTH_PASS_MULTIVIEW,
PIPELINE_VERSION_OPAQUE_PASS_MULTIVIEW,
PIPELINE_VERSION_TRANSPARENT_PASS_MULTIVIEW,
PIPELINE_VERSION_LIGHTMAP_OPAQUE_PASS_MULTIVIEW,
PIPELINE_VERSION_LIGHTMAP_TRANSPARENT_PASS_MULTIVIEW,
PIPELINE_VERSION_MAX PIPELINE_VERSION_MAX
}; };

View File

@ -99,6 +99,18 @@ layout(location = 8) out float dp_clip;
layout(location = 9) out flat uint instance_index_interp; layout(location = 9) out flat uint instance_index_interp;
#ifdef USE_MULTIVIEW
#ifdef has_VK_KHR_multiview
#define ViewIndex gl_ViewIndex
#else // has_VK_KHR_multiview
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif // has_VK_KHR_multiview
#else // USE_MULTIVIEW
// Set to zero, not supported in non stereo
#define ViewIndex 0
#endif //USE_MULTIVIEW
invariant gl_Position; invariant gl_Position;
#GLOBALS #GLOBALS
@ -244,7 +256,13 @@ void main() {
vec4 position; vec4 position;
#endif #endif
#ifdef USE_MULTIVIEW
mat4 projection_matrix = scene_data.projection_matrix_view[ViewIndex];
mat4 inv_projection_matrix = scene_data.inv_projection_matrix_view[ViewIndex];
#else
mat4 projection_matrix = scene_data.projection_matrix; mat4 projection_matrix = scene_data.projection_matrix;
mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
#endif //USE_MULTIVIEW
//using world coordinates //using world coordinates
#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED) #if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
@ -421,10 +439,26 @@ layout(location = 8) in float dp_clip;
layout(location = 9) in flat uint instance_index_interp; layout(location = 9) in flat uint instance_index_interp;
#ifdef USE_MULTIVIEW
#ifdef has_VK_KHR_multiview
#define ViewIndex gl_ViewIndex
#else // has_VK_KHR_multiview
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif // has_VK_KHR_multiview
#else // USE_MULTIVIEW
// Set to zero, not supported in non stereo
#define ViewIndex 0
#endif //USE_MULTIVIEW
//defines to keep compatibility with vertex //defines to keep compatibility with vertex
#define world_matrix instances.data[instance_index].transform #define world_matrix instances.data[instance_index].transform
#ifdef USE_MULTIVIEW
#define projection_matrix scene_data.projection_matrix_view[ViewIndex]
#else
#define projection_matrix scene_data.projection_matrix #define projection_matrix scene_data.projection_matrix
#endif
#if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE) #if defined(ENABLE_SSS) && defined(ENABLE_TRANSMITTANCE)
//both required for transmittance to be enabled //both required for transmittance to be enabled

View File

@ -2,6 +2,7 @@
#define ROUGHNESS_MAX_LOD 5 #define ROUGHNESS_MAX_LOD 5
#define MAX_VOXEL_GI_INSTANCES 8 #define MAX_VOXEL_GI_INSTANCES 8
#define MAX_VIEWS 2
#if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic) #if defined(has_GL_KHR_shader_subgroup_ballot) && defined(has_GL_KHR_shader_subgroup_arithmetic)
@ -12,6 +13,10 @@
#endif #endif
#if defined(USE_MULTIVIEW) && defined(has_VK_KHR_multiview)
#extension GL_EXT_multiview : enable
#endif
#include "cluster_data_inc.glsl" #include "cluster_data_inc.glsl"
#include "decal_data_inc.glsl" #include "decal_data_inc.glsl"
@ -169,10 +174,13 @@ sdfgi;
layout(set = 1, binding = 0, std140) uniform SceneData { layout(set = 1, binding = 0, std140) uniform SceneData {
mat4 projection_matrix; mat4 projection_matrix;
mat4 inv_projection_matrix; mat4 inv_projection_matrix;
mat4 camera_matrix; mat4 camera_matrix;
mat4 inv_camera_matrix; mat4 inv_camera_matrix;
// only used for multiview
mat4 projection_matrix_view[MAX_VIEWS];
mat4 inv_projection_matrix_view[MAX_VIEWS];
vec2 viewport_size; vec2 viewport_size;
vec2 screen_pixel_size; vec2 screen_pixel_size;