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 << '\n';
out << SHADERS_COMMON_DEFINES_GLSL_DATA; out << SHADERS_COMMON_DEFINES_GLSL_DATA;
CodeGenerator::generateDefine(out, "MATERIAL_FEATURE_LEVEL", uint32_t(mFeatureLevel));
if (material.featureLevel == FeatureLevel::FEATURE_LEVEL_0 && if (material.featureLevel == FeatureLevel::FEATURE_LEVEL_0 &&
(mFeatureLevel > FeatureLevel::FEATURE_LEVEL_0 (mFeatureLevel > FeatureLevel::FEATURE_LEVEL_0
|| mTargetLanguage == TargetLanguage::SPIRV)) { || mTargetLanguage == TargetLanguage::SPIRV)) {
@@ -485,7 +487,7 @@ io::sstream& CodeGenerator::generateCommonVariable(io::sstream& out, ShaderStage
return out; 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, const AttributeBitset& attributes, Interpolation interpolation,
MaterialBuilder::PushConstantList const& pushConstants) const { MaterialBuilder::PushConstantList const& pushConstants) const {
auto const& attributeDatabase = MaterialBuilder::getAttributeDatabase(); auto const& attributeDatabase = MaterialBuilder::getAttributeDatabase();
@@ -517,6 +519,7 @@ io::sstream& CodeGenerator::generateSurfaceShaderInputs(io::sstream& out, Shader
} }
out << "\n"; out << "\n";
out << SHADERS_COMMON_VARYINGS_GLSL_DATA;
out << SHADERS_SURFACE_VARYINGS_GLSL_DATA; out << SHADERS_SURFACE_VARYINGS_GLSL_DATA;
return out; return out;
} }
@@ -1073,6 +1076,7 @@ io::sstream& CodeGenerator::generateSurfaceMaterial(io::sstream& out, ShaderStag
} }
io::sstream& CodeGenerator::generatePostProcessInputs(io::sstream& out, ShaderStage stage) { io::sstream& CodeGenerator::generatePostProcessInputs(io::sstream& out, ShaderStage stage) {
out << SHADERS_COMMON_VARYINGS_GLSL_DATA;
if (stage == ShaderStage::VERTEX) { if (stage == ShaderStage::VERTEX) {
out << SHADERS_POST_PROCESS_INPUTS_VS_DATA; out << SHADERS_POST_PROCESS_INPUTS_VS_DATA;
} else if (stage == ShaderStage::FRAGMENT) { } else if (stage == ShaderStage::FRAGMENT) {

View File

@@ -109,7 +109,7 @@ public:
const MaterialBuilder::CustomVariable& variable, size_t index); const MaterialBuilder::CustomVariable& variable, size_t index);
// generate declarations for non-custom "in" variables // 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, const filament::AttributeBitset& attributes, filament::Interpolation interpolation,
MaterialBuilder::PushConstantList const& pushConstants) const; MaterialBuilder::PushConstantList const& pushConstants) const;
static utils::io::sstream& generatePostProcessInputs(utils::io::sstream& out, ShaderStage stage); 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'; out << '\n';
CodeGenerator::generateDefine(out, "MATERIAL_FEATURE_LEVEL", uint32_t(featureLevel));
CodeGenerator::generateDefine(out, "MATERIAL_HAS_SHADOW_MULTIPLIER", CodeGenerator::generateDefine(out, "MATERIAL_HAS_SHADOW_MULTIPLIER",
material.hasShadowMultiplier); material.hasShadowMultiplier);
@@ -436,7 +435,7 @@ std::string ShaderGenerator::createSurfaceVertexProgram(ShaderModel shaderModel,
[](MaterialBuilder::PushConstant const& constant) { [](MaterialBuilder::PushConstant const& constant) {
return constant.stage == ShaderStage::VERTEX; return constant.stage == ShaderStage::VERTEX;
}); });
cg.generateSurfaceShaderInputs(vs, ShaderStage::VERTEX, attributes, interpolation, cg.generateSurfaceInputs(vs, ShaderStage::VERTEX, attributes, interpolation,
vertexPushConstants); vertexPushConstants);
CodeGenerator::generateSurfaceTypes(vs, ShaderStage::VERTEX); CodeGenerator::generateSurfaceTypes(vs, ShaderStage::VERTEX);
@@ -546,7 +545,7 @@ std::string ShaderGenerator::createSurfaceFragmentProgram(ShaderModel shaderMode
[](MaterialBuilder::PushConstant const& constant) { [](MaterialBuilder::PushConstant const& constant) {
return constant.stage == ShaderStage::FRAGMENT; return constant.stage == ShaderStage::FRAGMENT;
}); });
cg.generateSurfaceShaderInputs(fs, ShaderStage::FRAGMENT, material.requiredAttributes, interpolation, cg.generateSurfaceInputs(fs, ShaderStage::FRAGMENT, material.requiredAttributes, interpolation,
fragmentPushConstants); fragmentPushConstants);
CodeGenerator::generateSurfaceTypes(fs, ShaderStage::FRAGMENT); CodeGenerator::generateSurfaceTypes(fs, ShaderStage::FRAGMENT);

View File

@@ -21,6 +21,7 @@ set(SHADERS
src/surface_material.fs src/surface_material.fs
src/common_math.glsl src/common_math.glsl
src/common_shading.fs src/common_shading.fs
src/common_varyings.glsl
src/surface_shadowing.glsl src/surface_shadowing.glsl
src/surface_types.glsl src/surface_types.glsl
src/surface_depth_main.fs src/surface_depth_main.fs

View File

@@ -28,13 +28,7 @@ highp mat4 getClipFromWorldMatrix() {
int eye = instance_index % CONFIG_STEREO_EYE_COUNT; int eye = instance_index % CONFIG_STEREO_EYE_COUNT;
return frameUniforms.clipFromWorldMatrix[eye]; return frameUniforms.clipFromWorldMatrix[eye];
#elif defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW) #elif defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW)
return frameUniforms.clipFromWorldMatrix[filament_multiview_data.y];
#if defined(TARGET_VULKAN_ENVIRONMENT)
return frameUniforms.clipFromWorldMatrix[gl_ViewIndex];
#else
return frameUniforms.clipFromWorldMatrix[gl_ViewID_OVR];
#endif // TARGET_VULKAN_ENVIRONMENT
#else #else
return frameUniforms.clipFromWorldMatrix[0]; return frameUniforms.clipFromWorldMatrix[0];
#endif #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) #if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_INSTANCED)
return instance_index % CONFIG_STEREO_EYE_COUNT; return instance_index % CONFIG_STEREO_EYE_COUNT;
#elif defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW) #elif defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_MULTIVIEW)
return int(filament_multiview_data.y);
#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
#endif #endif
return 0; return 0;
} }

View File

@@ -31,6 +31,17 @@ void main() {
logical_instance_index = instance_index / CONFIG_STEREO_EYE_COUNT; logical_instance_index = instance_index / CONFIG_STEREO_EYE_COUNT;
#endif #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(); initObjectUniforms();
// Initialize the inputs to sensible default values, see surface_material_inputs.vs // 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; LAYOUT_LOCATION(4) VARYING highp vec4 vertex_worldPosition;