Merge pull request #71455 from BastiaanOlij/fix_stereo_screen_depth

Make screen texture and depth texture work in Multiview
This commit is contained in:
Rémi Verschelde 2023-01-26 01:11:02 +01:00
commit 4b0363312e
No known key found for this signature in database
GPG key ID: C3336907360768E1
15 changed files with 103 additions and 23 deletions

View file

@ -192,7 +192,7 @@ void ShaderGLES3::_build_variant_code(StringBuilder &builder, uint32_t p_variant
builder.append("#define ViewIndex gl_ViewID_OVR\n");
builder.append("#define MAX_VIEWS 2\n");
builder.append("#else\n");
builder.append("#define ViewIndex 0\n");
builder.append("#define ViewIndex uint(0)\n");
builder.append("#define MAX_VIEWS 1\n");
builder.append("#endif\n");

View file

@ -565,9 +565,15 @@ uniform highp samplerCubeShadow positional_shadow; // texunit:-4
#ifdef USE_MULTIVIEW
uniform highp sampler2DArray depth_buffer; // texunit:-6
uniform highp sampler2DArray color_buffer; // texunit:-5
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
#else
uniform highp sampler2D depth_buffer; // texunit:-6
uniform highp sampler2D color_buffer; // texunit:-5
vec2 multiview_uv(vec2 uv) {
return uv;
}
#endif
uniform highp mat4 world_transform;
@ -925,8 +931,12 @@ void main() {
vec3 vertex = vertex_interp;
#ifdef USE_MULTIVIEW
vec3 view = -normalize(vertex_interp - multiview_data.eye_offset[ViewIndex].xyz);
mat4 projection_matrix = multiview_data.projection_matrix_view[ViewIndex];
mat4 inv_projection_matrix = multiview_data.inv_projection_matrix_view[ViewIndex];
#else
vec3 view = -normalize(vertex_interp);
mat4 projection_matrix = scene_data.projection_matrix;
mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
#endif
highp mat4 model_matrix = world_transform;
vec3 albedo = vec3(1.0);

View file

@ -1635,8 +1635,8 @@ MaterialStorage::MaterialStorage() {
actions.renames["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz";
actions.renames["VIEW_INDEX"] = "ViewIndex";
actions.renames["VIEW_MONO_LEFT"] = "0";
actions.renames["VIEW_RIGHT"] = "1";
actions.renames["VIEW_MONO_LEFT"] = "uint(0)";
actions.renames["VIEW_RIGHT"] = "uint(1)";
//for light
actions.renames["VIEW"] = "view";
@ -1718,6 +1718,8 @@ MaterialStorage::MaterialStorage() {
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
actions.check_multiview_samplers = true;
shaders.compiler_scene.initialize(actions);
}

View file

@ -717,6 +717,8 @@ void SceneShaderForwardClustered::init(const String p_defines) {
actions.global_buffer_array_variable = "global_shader_uniforms.data";
actions.instance_uniform_index_variable = "instances.data[instance_index_interp].instance_uniforms_ofs";
actions.check_multiview_samplers = true; // make sure we check sampling multiview textures
compiler.initialize(actions);
}

View file

@ -609,6 +609,7 @@ void SceneShaderForwardMobile::init(const String p_defines) {
actions.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs";
actions.apply_luminance_multiplier = true; // apply luminance multiplier to screen texture
actions.check_multiview_samplers = true; // make sure we check sampling multiview textures
compiler.initialize(actions);
}

View file

@ -253,6 +253,11 @@ void RendererSceneRenderRD::_render_buffers_copy_screen_texture(const RenderData
Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
ERR_FAIL_COND(rb.is_null());
if (!rb->has_internal_texture()) {
// We're likely rendering reflection probes where we can't use our backbuffers.
return;
}
RD::get_singleton()->draw_command_begin_label("Copy screen texture");
rb->allocate_blur_textures();
@ -292,6 +297,11 @@ void RendererSceneRenderRD::_render_buffers_copy_depth_texture(const RenderDataR
Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
ERR_FAIL_COND(rb.is_null());
if (!rb->has_depth_texture()) {
// We're likely rendering reflection probes where we can't use our backbuffers.
return;
}
RD::get_singleton()->draw_command_begin_label("Copy depth texture");
// note, this only creates our back depth texture if we haven't already created it.

View file

@ -118,13 +118,13 @@ layout(location = 10) out flat uint instance_index_interp;
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif // has_VK_KHR_multiview
vec3 normal_roughness_uv(vec2 uv) {
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
#else // USE_MULTIVIEW
// Set to zero, not supported in non stereo
#define ViewIndex 0
vec2 normal_roughness_uv(vec2 uv) {
vec2 multiview_uv(vec2 uv) {
return uv;
}
#endif //USE_MULTIVIEW
@ -550,13 +550,13 @@ layout(location = 10) in flat uint instance_index_interp;
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif // has_VK_KHR_multiview
vec3 normal_roughness_uv(vec2 uv) {
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
#else // USE_MULTIVIEW
// Set to zero, not supported in non stereo
#define ViewIndex 0
vec2 normal_roughness_uv(vec2 uv) {
vec2 multiview_uv(vec2 uv) {
return uv;
}
#endif //USE_MULTIVIEW

View file

@ -271,15 +271,16 @@ layout(r32ui, set = 1, binding = 13) uniform restrict uimage3D geom_facing_grid;
#define multiviewSampler sampler2D
#else
layout(set = 1, binding = 10) uniform texture2D depth_buffer;
layout(set = 1, binding = 11) uniform texture2D color_buffer;
#ifdef USE_MULTIVIEW
layout(set = 1, binding = 10) uniform texture2DArray depth_buffer;
layout(set = 1, binding = 11) uniform texture2DArray color_buffer;
layout(set = 1, binding = 12) uniform texture2DArray normal_roughness_buffer;
layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer;
layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer;
#define multiviewSampler sampler2DArray
#else // USE_MULTIVIEW
layout(set = 1, binding = 10) uniform texture2D depth_buffer;
layout(set = 1, binding = 11) uniform texture2D color_buffer;
layout(set = 1, binding = 12) uniform texture2D normal_roughness_buffer;
layout(set = 1, binding = 14) uniform texture2D ambient_buffer;
layout(set = 1, binding = 15) uniform texture2D reflection_buffer;

View file

@ -112,9 +112,15 @@ layout(location = 9) out highp float dp_clip;
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
#else
// Set to zero, not supported in non stereo
#define ViewIndex 0
vec2 multiview_uv(vec2 uv) {
return uv;
}
#endif //USE_MULTIVIEW
invariant gl_Position;
@ -523,9 +529,15 @@ layout(location = 9) highp in float dp_clip;
// !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0
#endif
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
#else
// Set to zero, not supported in non stereo
#define ViewIndex 0
vec2 multiview_uv(vec2 uv) {
return uv;
}
#endif //USE_MULTIVIEW
//defines to keep compatibility with vertex

View file

@ -154,8 +154,15 @@ layout(set = 1, binding = 5) uniform highp texture2D directional_shadow_atlas;
// this needs to change to providing just the lightmap we're using..
layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES];
#ifdef USE_MULTIVIEW
layout(set = 1, binding = 9) uniform highp texture2DArray depth_buffer;
layout(set = 1, binding = 10) uniform mediump texture2DArray color_buffer;
#define multiviewSampler sampler2DArray
#else
layout(set = 1, binding = 9) uniform highp texture2D depth_buffer;
layout(set = 1, binding = 10) uniform mediump texture2D color_buffer;
#define multiviewSampler sampler2D
#endif // USE_MULTIVIEW
/* Set 2 Skeleton & Instancing (can change per item) */

View file

@ -1464,7 +1464,6 @@ bool LightStorage::reflection_probe_instance_begin_render(RID p_instance, RID p_
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));
}

View file

@ -490,6 +490,16 @@ Ref<RenderBufferCustomDataRD> RenderSceneBuffersRD::get_custom_data(const String
// Depth texture
bool RenderSceneBuffersRD::has_depth_texture() {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RID depth = texture_storage->render_target_get_override_depth(render_target);
if (depth.is_valid()) {
return true;
} else {
return has_texture(RB_SCOPE_BUFFERS, RB_TEX_DEPTH);
}
}
RID RenderSceneBuffersRD::get_depth_texture() {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RID depth = texture_storage->render_target_get_override_depth(render_target);

View file

@ -185,6 +185,9 @@ public:
// For our internal textures we provide some easy access methods.
_FORCE_INLINE_ bool has_internal_texture() const {
return has_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR);
}
_FORCE_INLINE_ RID get_internal_texture() const {
return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR);
}
@ -192,6 +195,7 @@ public:
return get_texture_slice(RB_SCOPE_BUFFERS, RB_TEX_COLOR, p_layer, 0);
}
bool has_depth_texture();
RID get_depth_texture();
RID get_depth_texture(const uint32_t p_layer);

View file

@ -1173,9 +1173,10 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
code += "(";
// if normal roughness texture is used, we will add logic to automatically switch between
// if color backbuffer, depth backbuffer or normal roughness texture is used,
// we will add logic to automatically switch between
// sampler2D and sampler2D array and vec2 UV and vec3 UV.
bool normal_roughness_texture_used = false;
bool multiview_uv_needed = false;
for (int i = 1; i < onode->arguments.size(); i++) {
if (i > 1) {
@ -1220,8 +1221,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
}
String node_code = _dump_node_code(onode->arguments[i], p_level, r_gen_code, p_actions, p_default_actions, p_assigning);
if (!RS::get_singleton()->is_low_end() && is_texture_func && i == 1) {
//need to map from texture to sampler in order to sample when using Vulkan GLSL
if (is_texture_func && i == 1) {
// If we're doing a texture lookup we need to check our texture argument
StringName texture_uniform;
bool correct_texture_uniform = false;
@ -1240,8 +1241,10 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
break;
}
if (correct_texture_uniform) {
if (correct_texture_uniform && !RS::get_singleton()->is_low_end()) {
// Need to map from texture to sampler in order to sample when using Vulkan GLSL.
String sampler_name;
bool is_depth_texture = false;
bool is_normal_roughness_texture = false;
if (actions.custom_samplers.has(texture_uniform)) {
@ -1251,6 +1254,8 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[texture_uniform];
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) {
is_screen_texture = true;
} else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
is_depth_texture = true;
} else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) {
is_normal_roughness_texture = true;
}
@ -1281,23 +1286,39 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
}
String data_type_name = "";
if (is_normal_roughness_texture) {
if (actions.check_multiview_samplers && (is_screen_texture || is_depth_texture || is_normal_roughness_texture)) {
data_type_name = "multiviewSampler";
normal_roughness_texture_used = true;
multiview_uv_needed = true;
} else {
data_type_name = ShaderLanguage::get_datatype_name(onode->arguments[i]->get_datatype());
}
code += data_type_name + "(" + node_code + ", " + sampler_name + ")";
} else if (actions.check_multiview_samplers && correct_texture_uniform && RS::get_singleton()->is_low_end()) {
// Texture function on low end hardware (i.e. OpenGL).
// We just need to know if the texture supports multiview.
if (shader->uniforms.has(texture_uniform)) {
const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[texture_uniform];
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) {
multiview_uv_needed = true;
} else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_DEPTH_TEXTURE) {
multiview_uv_needed = true;
} else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) {
multiview_uv_needed = true;
}
}
code += node_code;
} else {
code += node_code;
}
} else {
if (normal_roughness_texture_used && i == 2) {
// UV coordinate after using normal roughness texture.
node_code = "normal_roughness_uv(" + node_code + ".xy)";
}
} else if (multiview_uv_needed && i == 2) {
// UV coordinate after using color, depth or normal roughness texture.
node_code = "multiview_uv(" + node_code + ".xy)";
code += node_code;
} else {
code += node_code;
}
}

View file

@ -101,6 +101,7 @@ public:
String instance_uniform_index_variable;
uint32_t base_varying_index = 0;
bool apply_luminance_multiplier = false;
bool check_multiview_samplers = false;
};
private: