Compare commits

...

2 Commits

Author SHA1 Message Date
Sungun Park
cf75b4489b feedback 2025-02-04 13:41:42 -08:00
Sungun Park
923ac98ea8 Add multiview_data for multiview information
Add a varying variable `multiview_data` for both surface and
post-processing shaders. Currently this only works as intended in
surface shader, and additional implementation to facilitate it for
post-processing will be following.

The `multiview_data` contains multiview information like whether
multiview is enabled for the current material and what the eye index is
in that case. This variable is globally available including fragment
shaders so that it can be referenced in user shaders in .material files.
Also this allows us to indirectly reference the constant variables such
as `gl_ViewID_OVR` and `gl_ViewIndex` in a platform-agnostic way.

Make the preprocessor `MATERIAL_FEATURE_LEVEL` available for both
surface and post-processing shaders, it used to be only available for
surface shader, and this will be referenced in post-processing shaders
later to support multiview for post-processing.
2025-02-03 19:48:20 -08:00
9 changed files with 39 additions and 21 deletions

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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[filament_multiview_data.y];
#else
return frameUniforms.clipFromWorldMatrix[0];
#endif

View File

@@ -0,0 +1,16 @@
//------------------------------------------------------------------------------
// Common Varyings
//------------------------------------------------------------------------------
// The `filament_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.
// `MATERIAL_FEATURE_LEVEL > 0` is used as a workaround instead of `defined(VARIANT_HAS_STEREO)` to
// make this line available for post-processing where we cannot use VARIANT_HAS_STEREO. The
// downside of this approach is that `flat VARYING` is used for non-STE shaders as well.
#if MATERIAL_FEATURE_LEVEL > 0 && defined(FILAMENT_STEREO_MULTIVIEW)
LAYOUT_LOCATION(12) flat VARYING ivec2 filament_multiview_data;
#else
ivec2 filament_multiview_data = ivec2(0, 0);
#endif

View File

@@ -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(filament_multiview_data.y);
#endif
return 0;
}

View File

@@ -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
filament_multiview_data = ivec2(1, int(multiview_view_index));
#else
filament_multiview_data = ivec2(0, 0);
#endif
initObjectUniforms();
// Initialize the inputs to sensible default values, see surface_material_inputs.vs

View File

@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------
// Varyings
// Surface Varyings
//------------------------------------------------------------------------------
LAYOUT_LOCATION(4) VARYING highp vec4 vertex_worldPosition;