diff --git a/libs/filamat/src/shaders/CodeGenerator.cpp b/libs/filamat/src/shaders/CodeGenerator.cpp index 4b41e7974d..e4478057d1 100644 --- a/libs/filamat/src/shaders/CodeGenerator.cpp +++ b/libs/filamat/src/shaders/CodeGenerator.cpp @@ -365,6 +365,8 @@ utils::io::sstream& CodeGenerator::generateCommonProlog(utils::io::sstream& out, out << '\n'; out << SHADERS_COMMON_DEFINES_GLSL_DATA; + CodeGenerator::generateDefine(out, "MATERIAL_FEATURE_LEVEL", uint32_t(mFeatureLevel)); + if (material.featureLevel == FeatureLevel::FEATURE_LEVEL_0 && (mFeatureLevel > FeatureLevel::FEATURE_LEVEL_0 || mTargetLanguage == TargetLanguage::SPIRV)) { @@ -485,7 +487,7 @@ io::sstream& CodeGenerator::generateCommonVariable(io::sstream& out, ShaderStage return out; } -io::sstream& CodeGenerator::generateSurfaceShaderInputs(io::sstream& out, ShaderStage stage, +io::sstream& CodeGenerator::generateSurfaceInputs(io::sstream& out, ShaderStage stage, const AttributeBitset& attributes, Interpolation interpolation, MaterialBuilder::PushConstantList const& pushConstants) const { auto const& attributeDatabase = MaterialBuilder::getAttributeDatabase(); @@ -517,6 +519,7 @@ io::sstream& CodeGenerator::generateSurfaceShaderInputs(io::sstream& out, Shader } out << "\n"; + out << SHADERS_COMMON_VARYINGS_GLSL_DATA; out << SHADERS_SURFACE_VARYINGS_GLSL_DATA; return out; } @@ -1073,6 +1076,7 @@ io::sstream& CodeGenerator::generateSurfaceMaterial(io::sstream& out, ShaderStag } io::sstream& CodeGenerator::generatePostProcessInputs(io::sstream& out, ShaderStage stage) { + out << SHADERS_COMMON_VARYINGS_GLSL_DATA; if (stage == ShaderStage::VERTEX) { out << SHADERS_POST_PROCESS_INPUTS_VS_DATA; } else if (stage == ShaderStage::FRAGMENT) { diff --git a/libs/filamat/src/shaders/CodeGenerator.h b/libs/filamat/src/shaders/CodeGenerator.h index 4bc7bc8f29..0ab019b9d4 100644 --- a/libs/filamat/src/shaders/CodeGenerator.h +++ b/libs/filamat/src/shaders/CodeGenerator.h @@ -109,7 +109,7 @@ public: const MaterialBuilder::CustomVariable& variable, size_t index); // generate declarations for non-custom "in" variables - utils::io::sstream& generateSurfaceShaderInputs(utils::io::sstream& out, ShaderStage stage, + utils::io::sstream& generateSurfaceInputs(utils::io::sstream& out, ShaderStage stage, const filament::AttributeBitset& attributes, filament::Interpolation interpolation, MaterialBuilder::PushConstantList const& pushConstants) const; static utils::io::sstream& generatePostProcessInputs(utils::io::sstream& out, ShaderStage stage); diff --git a/libs/filamat/src/shaders/ShaderGenerator.cpp b/libs/filamat/src/shaders/ShaderGenerator.cpp index 8b011598c7..afe337ea54 100644 --- a/libs/filamat/src/shaders/ShaderGenerator.cpp +++ b/libs/filamat/src/shaders/ShaderGenerator.cpp @@ -81,7 +81,6 @@ void ShaderGenerator::generateSurfaceMaterialVariantDefines(utils::io::sstream& } out << '\n'; - CodeGenerator::generateDefine(out, "MATERIAL_FEATURE_LEVEL", uint32_t(featureLevel)); CodeGenerator::generateDefine(out, "MATERIAL_HAS_SHADOW_MULTIPLIER", material.hasShadowMultiplier); @@ -436,7 +435,7 @@ std::string ShaderGenerator::createSurfaceVertexProgram(ShaderModel shaderModel, [](MaterialBuilder::PushConstant const& constant) { return constant.stage == ShaderStage::VERTEX; }); - cg.generateSurfaceShaderInputs(vs, ShaderStage::VERTEX, attributes, interpolation, + cg.generateSurfaceInputs(vs, ShaderStage::VERTEX, attributes, interpolation, vertexPushConstants); CodeGenerator::generateSurfaceTypes(vs, ShaderStage::VERTEX); @@ -546,7 +545,7 @@ std::string ShaderGenerator::createSurfaceFragmentProgram(ShaderModel shaderMode [](MaterialBuilder::PushConstant const& constant) { return constant.stage == ShaderStage::FRAGMENT; }); - cg.generateSurfaceShaderInputs(fs, ShaderStage::FRAGMENT, material.requiredAttributes, interpolation, + cg.generateSurfaceInputs(fs, ShaderStage::FRAGMENT, material.requiredAttributes, interpolation, fragmentPushConstants); CodeGenerator::generateSurfaceTypes(fs, ShaderStage::FRAGMENT); diff --git a/shaders/CMakeLists.txt b/shaders/CMakeLists.txt index 7109c239c2..ba5cc1ef27 100644 --- a/shaders/CMakeLists.txt +++ b/shaders/CMakeLists.txt @@ -21,6 +21,7 @@ set(SHADERS src/surface_material.fs src/common_math.glsl src/common_shading.fs + src/common_varyings.glsl src/surface_shadowing.glsl src/surface_types.glsl src/surface_depth_main.fs diff --git a/shaders/src/common_getters.glsl b/shaders/src/common_getters.glsl index 95ea0799f2..40ecc81d2f 100644 --- a/shaders/src/common_getters.glsl +++ b/shaders/src/common_getters.glsl @@ -28,13 +28,7 @@ highp mat4 getClipFromWorldMatrix() { int eye = instance_index % CONFIG_STEREO_EYE_COUNT; return frameUniforms.clipFromWorldMatrix[eye]; #elif defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW) - -#if defined(TARGET_VULKAN_ENVIRONMENT) - return frameUniforms.clipFromWorldMatrix[gl_ViewIndex]; -#else - return frameUniforms.clipFromWorldMatrix[gl_ViewID_OVR]; -#endif // TARGET_VULKAN_ENVIRONMENT - + return frameUniforms.clipFromWorldMatrix[multiview_data.y]; #else return frameUniforms.clipFromWorldMatrix[0]; #endif diff --git a/shaders/src/common_varyings.glsl b/shaders/src/common_varyings.glsl new file mode 100644 index 0000000000..8a1a69cb26 --- /dev/null +++ b/shaders/src/common_varyings.glsl @@ -0,0 +1,13 @@ +//------------------------------------------------------------------------------ +// Common Varyings +//------------------------------------------------------------------------------ + +// The `multiview_data` variable is to pass the current state of multiview set in the vertex shader +// to the fragment shader. `x` means whether multiview is used, `y` means the current view index. +// Neither the multiview feature nor the `flat` keyword is supported in FL0. So, for FL0, declare +// it as a non-flat and non-varying variable and set it to zeros as a placeholder. +#if MATERIAL_FEATURE_LEVEL > 0 +LAYOUT_LOCATION(99) flat VARYING ivec2 multiview_data; +#else +ivec2 multiview_data = ivec2(0, 0); +#endif diff --git a/shaders/src/surface_getters.vs b/shaders/src/surface_getters.vs index a9b8c293ac..5dd35687b3 100644 --- a/shaders/src/surface_getters.vs +++ b/shaders/src/surface_getters.vs @@ -284,14 +284,7 @@ int getEyeIndex() { #if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_INSTANCED) return instance_index % CONFIG_STEREO_EYE_COUNT; #elif defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW) - -#if defined(TARGET_VULKAN_ENVIRONMENT) - return int(gl_ViewIndex); -#else - // gl_ViewID_OVR is of uint type, which needs an explicit conversion. - return int(gl_ViewID_OVR); -#endif // TARGET_VULKAN_ENVIRONMENT - + return int(multiview_data.y); #endif return 0; } diff --git a/shaders/src/surface_main.vs b/shaders/src/surface_main.vs index c8882de005..3078dead9a 100644 --- a/shaders/src/surface_main.vs +++ b/shaders/src/surface_main.vs @@ -31,6 +31,17 @@ void main() { logical_instance_index = instance_index / CONFIG_STEREO_EYE_COUNT; #endif +#if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW) +# if defined(TARGET_VULKAN_ENVIRONMENT) + int multiview_view_index = int(gl_ViewIndex); +# else + int multiview_view_index = int(gl_ViewID_OVR); +# endif // TARGET_VULKAN_ENVIRONMENT + multiview_data = ivec2(1, int(multiview_view_index)); +#else + multiview_data = ivec2(0, 0); +#endif + initObjectUniforms(); // Initialize the inputs to sensible default values, see surface_material_inputs.vs diff --git a/shaders/src/surface_varyings.glsl b/shaders/src/surface_varyings.glsl index 7c1432ef98..7de7b1e275 100644 --- a/shaders/src/surface_varyings.glsl +++ b/shaders/src/surface_varyings.glsl @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Varyings +// Surface Varyings //------------------------------------------------------------------------------ LAYOUT_LOCATION(4) VARYING highp vec4 vertex_worldPosition;