Merge pull request #71455 from BastiaanOlij/fix_stereo_screen_depth
Make screen texture and depth texture work in Multiview
This commit is contained in:
commit
4b0363312e
15 changed files with 103 additions and 23 deletions
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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) */
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
Loading…
Reference in a new issue