Make screen texture and depth texture work in Multiview

This commit is contained in:
Bastiaan Olij 2023-01-15 16:07:59 +11:00
parent eaf306e0b1
commit 85c478e170
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 ViewIndex gl_ViewID_OVR\n");
builder.append("#define MAX_VIEWS 2\n"); builder.append("#define MAX_VIEWS 2\n");
builder.append("#else\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("#define MAX_VIEWS 1\n");
builder.append("#endif\n"); builder.append("#endif\n");

View File

@ -565,9 +565,15 @@ uniform highp samplerCubeShadow positional_shadow; // texunit:-4
#ifdef USE_MULTIVIEW #ifdef USE_MULTIVIEW
uniform highp sampler2DArray depth_buffer; // texunit:-6 uniform highp sampler2DArray depth_buffer; // texunit:-6
uniform highp sampler2DArray color_buffer; // texunit:-5 uniform highp sampler2DArray color_buffer; // texunit:-5
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
#else #else
uniform highp sampler2D depth_buffer; // texunit:-6 uniform highp sampler2D depth_buffer; // texunit:-6
uniform highp sampler2D color_buffer; // texunit:-5 uniform highp sampler2D color_buffer; // texunit:-5
vec2 multiview_uv(vec2 uv) {
return uv;
}
#endif #endif
uniform highp mat4 world_transform; uniform highp mat4 world_transform;
@ -924,8 +930,12 @@ void main() {
vec3 vertex = vertex_interp; vec3 vertex = vertex_interp;
#ifdef USE_MULTIVIEW #ifdef USE_MULTIVIEW
vec3 view = -normalize(vertex_interp - multiview_data.eye_offset[ViewIndex].xyz); 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 #else
vec3 view = -normalize(vertex_interp); vec3 view = -normalize(vertex_interp);
mat4 projection_matrix = scene_data.projection_matrix;
mat4 inv_projection_matrix = scene_data.inv_projection_matrix;
#endif #endif
highp mat4 model_matrix = world_transform; highp mat4 model_matrix = world_transform;
vec3 albedo = vec3(1.0); 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["NODE_POSITION_VIEW"] = "(model_matrix * scene_data.view_matrix)[3].xyz";
actions.renames["VIEW_INDEX"] = "ViewIndex"; actions.renames["VIEW_INDEX"] = "ViewIndex";
actions.renames["VIEW_MONO_LEFT"] = "0"; actions.renames["VIEW_MONO_LEFT"] = "uint(0)";
actions.renames["VIEW_RIGHT"] = "1"; actions.renames["VIEW_RIGHT"] = "uint(1)";
//for light //for light
actions.renames["VIEW"] = "view"; actions.renames["VIEW"] = "view";
@ -1718,6 +1718,8 @@ MaterialStorage::MaterialStorage() {
actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP; actions.default_filter = ShaderLanguage::FILTER_LINEAR_MIPMAP;
actions.default_repeat = ShaderLanguage::REPEAT_ENABLE; actions.default_repeat = ShaderLanguage::REPEAT_ENABLE;
actions.check_multiview_samplers = true;
shaders.compiler_scene.initialize(actions); 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.global_buffer_array_variable = "global_shader_uniforms.data";
actions.instance_uniform_index_variable = "instances.data[instance_index_interp].instance_uniforms_ofs"; 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); 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.instance_uniform_index_variable = "draw_call.instance_uniforms_ofs";
actions.apply_luminance_multiplier = true; // apply luminance multiplier to screen texture 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); 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; Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
ERR_FAIL_COND(rb.is_null()); 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"); RD::get_singleton()->draw_command_begin_label("Copy screen texture");
rb->allocate_blur_textures(); 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; Ref<RenderSceneBuffersRD> rb = p_render_data->render_buffers;
ERR_FAIL_COND(rb.is_null()); 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"); 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. // 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! // !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0 #define ViewIndex 0
#endif // has_VK_KHR_multiview #endif // has_VK_KHR_multiview
vec3 normal_roughness_uv(vec2 uv) { vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex); return vec3(uv, ViewIndex);
} }
#else // USE_MULTIVIEW #else // USE_MULTIVIEW
// Set to zero, not supported in non stereo // Set to zero, not supported in non stereo
#define ViewIndex 0 #define ViewIndex 0
vec2 normal_roughness_uv(vec2 uv) { vec2 multiview_uv(vec2 uv) {
return uv; return uv;
} }
#endif //USE_MULTIVIEW #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! // !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0 #define ViewIndex 0
#endif // has_VK_KHR_multiview #endif // has_VK_KHR_multiview
vec3 normal_roughness_uv(vec2 uv) { vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex); return vec3(uv, ViewIndex);
} }
#else // USE_MULTIVIEW #else // USE_MULTIVIEW
// Set to zero, not supported in non stereo // Set to zero, not supported in non stereo
#define ViewIndex 0 #define ViewIndex 0
vec2 normal_roughness_uv(vec2 uv) { vec2 multiview_uv(vec2 uv) {
return uv; return uv;
} }
#endif //USE_MULTIVIEW #endif //USE_MULTIVIEW

View File

@ -271,15 +271,16 @@ layout(r32ui, set = 1, binding = 13) uniform restrict uimage3D geom_facing_grid;
#define multiviewSampler sampler2D #define multiviewSampler sampler2D
#else #else
layout(set = 1, binding = 10) uniform texture2D depth_buffer;
layout(set = 1, binding = 11) uniform texture2D color_buffer;
#ifdef USE_MULTIVIEW #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 = 12) uniform texture2DArray normal_roughness_buffer;
layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer; layout(set = 1, binding = 14) uniform texture2DArray ambient_buffer;
layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer; layout(set = 1, binding = 15) uniform texture2DArray reflection_buffer;
#define multiviewSampler sampler2DArray #define multiviewSampler sampler2DArray
#else // USE_MULTIVIEW #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 = 12) uniform texture2D normal_roughness_buffer;
layout(set = 1, binding = 14) uniform texture2D ambient_buffer; layout(set = 1, binding = 14) uniform texture2D ambient_buffer;
layout(set = 1, binding = 15) uniform texture2D reflection_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! // !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0 #define ViewIndex 0
#endif #endif
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
#else #else
// Set to zero, not supported in non stereo // Set to zero, not supported in non stereo
#define ViewIndex 0 #define ViewIndex 0
vec2 multiview_uv(vec2 uv) {
return uv;
}
#endif //USE_MULTIVIEW #endif //USE_MULTIVIEW
invariant gl_Position; 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! // !BAS! This needs to become an input once we implement our fallback!
#define ViewIndex 0 #define ViewIndex 0
#endif #endif
vec3 multiview_uv(vec2 uv) {
return vec3(uv, ViewIndex);
}
#else #else
// Set to zero, not supported in non stereo // Set to zero, not supported in non stereo
#define ViewIndex 0 #define ViewIndex 0
vec2 multiview_uv(vec2 uv) {
return uv;
}
#endif //USE_MULTIVIEW #endif //USE_MULTIVIEW
//defines to keep compatibility with vertex //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.. // this needs to change to providing just the lightmap we're using..
layout(set = 1, binding = 6) uniform texture2DArray lightmap_textures[MAX_LIGHTMAP_TEXTURES]; 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 = 9) uniform highp texture2D depth_buffer;
layout(set = 1, binding = 10) uniform mediump texture2D color_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) */ /* 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); fb.push_back(atlas->depth_buffer);
atlas->depth_fb = RD::get_singleton()->framebuffer_create(fb); atlas->depth_fb = RD::get_singleton()->framebuffer_create(fb);
atlas->render_buffers->cleanup();
atlas->render_buffers->configure_for_reflections(Size2i(atlas->size, atlas->size)); 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 // 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() { RID RenderSceneBuffersRD::get_depth_texture() {
RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton(); RendererRD::TextureStorage *texture_storage = RendererRD::TextureStorage::get_singleton();
RID depth = texture_storage->render_target_get_override_depth(render_target); 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. // 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 { _FORCE_INLINE_ RID get_internal_texture() const {
return get_texture(RB_SCOPE_BUFFERS, RB_TEX_COLOR); 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); 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();
RID get_depth_texture(const uint32_t p_layer); 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 += "("; 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. // 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++) { for (int i = 1; i < onode->arguments.size(); i++) {
if (i > 1) { 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); 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) { if (is_texture_func && i == 1) {
//need to map from texture to sampler in order to sample when using Vulkan GLSL // If we're doing a texture lookup we need to check our texture argument
StringName texture_uniform; StringName texture_uniform;
bool correct_texture_uniform = false; bool correct_texture_uniform = false;
@ -1240,8 +1241,10 @@ String ShaderCompiler::_dump_node_code(const SL::Node *p_node, int p_level, Gene
break; 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; String sampler_name;
bool is_depth_texture = false;
bool is_normal_roughness_texture = false; bool is_normal_roughness_texture = false;
if (actions.custom_samplers.has(texture_uniform)) { 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]; const ShaderLanguage::ShaderNode::Uniform &u = shader->uniforms[texture_uniform];
if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) { if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_SCREEN_TEXTURE) {
is_screen_texture = true; 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) { } else if (u.hint == ShaderLanguage::ShaderNode::Uniform::HINT_NORMAL_ROUGHNESS_TEXTURE) {
is_normal_roughness_texture = true; 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 = ""; 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"; data_type_name = "multiviewSampler";
normal_roughness_texture_used = true; multiview_uv_needed = true;
} else { } else {
data_type_name = ShaderLanguage::get_datatype_name(onode->arguments[i]->get_datatype()); data_type_name = ShaderLanguage::get_datatype_name(onode->arguments[i]->get_datatype());
} }
code += data_type_name + "(" + node_code + ", " + sampler_name + ")"; 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 { } else {
code += node_code; code += node_code;
} }
} else { } else if (multiview_uv_needed && i == 2) {
if (normal_roughness_texture_used && i == 2) { // UV coordinate after using color, depth or normal roughness texture.
// UV coordinate after using normal roughness texture. node_code = "multiview_uv(" + node_code + ".xy)";
node_code = "normal_roughness_uv(" + node_code + ".xy)";
}
code += node_code;
} else {
code += node_code; code += node_code;
} }
} }

View File

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