Add a new material param, stereoscopicType (#7613)

* Add a new material param, stereoscopicType

This new parameter allows us to specify which implementation of
stereoscopic rendering Filament uses for the material.

This change just includes material parameter addition and shader code
changes, so it doesn't affect the current rendering behavior.

These changes will follow as separate commits.
- render pipeline changes
- material parameter override via matc parameter
- material document update
This commit is contained in:
Sungun Park
2024-02-28 14:14:44 -08:00
committed by GitHub
parent af8f38d83c
commit 57fff3a636
8 changed files with 44 additions and 4 deletions

View File

@@ -243,6 +243,7 @@ public:
using Precision = filament::backend::Precision;
using CullingMode = filament::backend::CullingMode;
using FeatureLevel = filament::backend::FeatureLevel;
using StereoscopicType = filament::backend::StereoscopicType;
enum class VariableQualifier : uint8_t {
OUT
@@ -521,6 +522,9 @@ public:
//! Specifies how transparent objects should be rendered (default is DEFAULT).
MaterialBuilder& transparencyMode(TransparencyMode mode) noexcept;
//! Specify the stereoscopic type (default is INSTANCED)
MaterialBuilder& stereoscopicType(StereoscopicType stereoscopicType) noexcept;
/**
* Enable / disable custom surface shading. Custom surface shading requires the LIT
* shading model. In addition, the following function must be defined in the fragment
@@ -829,6 +833,7 @@ private:
Interpolation mInterpolation = Interpolation::SMOOTH;
VertexDomain mVertexDomain = VertexDomain::OBJECT;
TransparencyMode mTransparencyMode = TransparencyMode::DEFAULT;
StereoscopicType mStereoscopicType = StereoscopicType::INSTANCED;
filament::AttributeBitset mRequiredAttributes;

View File

@@ -498,6 +498,11 @@ MaterialBuilder& MaterialBuilder::transparencyMode(TransparencyMode mode) noexce
return *this;
}
MaterialBuilder& MaterialBuilder::stereoscopicType(StereoscopicType stereoscopicType) noexcept {
mStereoscopicType = stereoscopicType;
return *this;
}
MaterialBuilder& MaterialBuilder::reflectionMode(ReflectionMode mode) noexcept {
mReflectionMode = mode;
return *this;
@@ -632,6 +637,7 @@ void MaterialBuilder::prepareToBuild(MaterialInfo& info) noexcept {
info.vertexDomainDeviceJittered = mVertexDomainDeviceJittered;
info.featureLevel = mFeatureLevel;
info.groupSize = mGroupSize;
info.stereoscopicType = mStereoscopicType;
// This is determined via static analysis of the glsl after prepareToBuild().
info.userMaterialHasCustomDepth = false;

View File

@@ -181,6 +181,15 @@ utils::io::sstream& CodeGenerator::generateProlog(utils::io::sstream& out, Shade
}
generateDefine(out, "FILAMENT_EFFECTIVE_VERSION", effective_version);
switch (material.stereoscopicType) {
case StereoscopicType::INSTANCED:
generateDefine(out, "FILAMENT_STEREO_INSTANCED", true);
break;
case StereoscopicType::MULTIVIEW:
generateDefine(out, "FILAMENT_STEREO_MULTIVIEW", true);
break;
}
if (stage == ShaderStage::VERTEX) {
CodeGenerator::generateDefine(out, "FLIP_UV_ATTRIBUTE", material.flipUV);
CodeGenerator::generateDefine(out, "LEGACY_MORPHING", material.useLegacyMorphing);

View File

@@ -68,6 +68,7 @@ struct UTILS_PUBLIC MaterialInfo {
filament::SamplerBindingMap samplerBindings;
filament::ShaderQuality quality;
filament::backend::FeatureLevel featureLevel;
filament::backend::StereoscopicType stereoscopicType;
filament::math::uint3 groupSize;
using BufferContainer = utils::FixedCapacityVector<filament::BufferInterfaceBlock const*>;

View File

@@ -25,8 +25,12 @@ highp mat4 getViewFromClipMatrix() {
/** @public-api */
highp mat4 getClipFromWorldMatrix() {
#if defined(VARIANT_HAS_STEREO)
#if defined(FILAMENT_STEREO_INSTANCED)
int eye = instance_index % CONFIG_STEREO_EYE_COUNT;
return frameUniforms.clipFromWorldMatrix[eye];
#elif defined(FILAMENT_STEREO_MULTIVIEW)
return frameUniforms.clipFromWorldMatrix[gl_ViewID_OVR];
#endif
#else
return frameUniforms.clipFromWorldMatrix[0];
#endif

View File

@@ -23,7 +23,7 @@ void main() {
logical_instance_index = instance_index;
#endif
#if defined(VARIANT_HAS_STEREO)
#if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_INSTANCED)
#if !defined(FILAMENT_HAS_FEATURE_INSTANCING)
#error Instanced stereo not supported at this feature level
#endif
@@ -215,7 +215,7 @@ void main() {
// this must happen before we compensate for vulkan below
vertex_position = position;
#if defined(VARIANT_HAS_STEREO)
#if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_INSTANCED)
// We're transforming a vertex whose x coordinate is within the range (-w to w).
// To move it to the correct portion of the viewport, we need to modify the x coordinate.
// It's important to do this after computing vertex_position.
@@ -253,7 +253,7 @@ void main() {
// some PowerVR drivers crash when gl_Position is written more than once
gl_Position = position;
#if defined(VARIANT_HAS_STEREO)
#if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_INSTANCED)
// Fragment shaders filter out the stereo variant, so we need to set instance_index here.
instance_index = logical_instance_index;
#endif

View File

@@ -34,7 +34,7 @@ LAYOUT_LOCATION(11) VARYING highp vec4 vertex_lightSpacePosition;
// Note that fragColor is an output and is not declared here; see main.fs and depth_main.fs
#if defined(VARIANT_HAS_STEREO)
#if defined(VARIANT_HAS_STEREO) && defined(FILAMENT_STEREO_INSTANCED)
#if defined(GL_ES) && defined(FILAMENT_GLSLANG)
// On ES, gl_ClipDistance is not a built-in, so we have to rely on EXT_clip_cull_distance
// However, this extension is not supported by glslang, so we instead write to

View File

@@ -796,6 +796,20 @@ static bool processGroupSizes(MaterialBuilder& builder, const JsonishValue& v) {
return true;
}
static bool processStereoscopicType(MaterialBuilder& builder, const JsonishValue& value) {
static const std::unordered_map<std::string, MaterialBuilder::StereoscopicType> strToEnum{
{ "instanced", MaterialBuilder::StereoscopicType::INSTANCED },
{ "multiview", MaterialBuilder::StereoscopicType::MULTIVIEW },
};
auto jsonString = value.toJsonString();
if (!isStringValidEnum(strToEnum, jsonString->getString())) {
return logEnumIssue("stereoscopicType", *jsonString, strToEnum);
}
builder.stereoscopicType(stringToEnum(strToEnum, jsonString->getString()));
return true;
}
static bool processOutput(MaterialBuilder& builder, const JsonishObject& jsonObject) noexcept {
const JsonishValue* nameValue = jsonObject.getValue("name");
@@ -1214,6 +1228,7 @@ ParametersProcessor::ParametersProcessor() {
mParameters["customSurfaceShading"] = { &processCustomSurfaceShading, Type::BOOL };
mParameters["featureLevel"] = { &processFeatureLevel, Type::NUMBER };
mParameters["groupSize"] = { &processGroupSizes, Type::ARRAY };
mParameters["stereoscopicType"] = { &processStereoscopicType, Type::STRING };
}
bool ParametersProcessor::process(MaterialBuilder& builder, const JsonishObject& jsonObject) {