From e15b9a5175b0730a1cfb3fa23f7254e1f5bd8672 Mon Sep 17 00:00:00 2001 From: Eliza Velasquez Date: Fri, 29 Sep 2023 14:00:40 -0700 Subject: [PATCH] Revert "Remove now-redundant feature level 0 materials" This reverts most of commit 9a6b8bf24e729c95b057aab0582310636e996cbe. The hello triangle sample remains unreverted. The original commit inadvertently broke screen space reflections, and perhaps other features when the default material was used. The source of the issue is that MaterialBuilder.cpp (correctly) filters out variants that aren't supported in feature level 0 materials, including screen space reflections. Unfortunately, while the "feature level 0 compatibility" feature itself was intended to make creating duplicate materials like this redundant in client code, unfortunately, it seems the best solution for resolving this issue is to simply keep these redundant materials in the core. To elaborate: clients should expect that feature level 0 materials that they create work on /all/ feature levels /exactly/ or /close to exactly/ identically. This includes restricting more advanced features that theoretically could be available on a higher feature level, like SSR. It's already true that if a user would like to optionally opt-in to a more advanced material which takes advantage of more advanced features, they would have to maintain two separate versions of that material: one for feature level 3 and one for feature level 1. It should be no different in this case. However, the materials built into the engine core are an exception to this expectation. Given that feature level 0 was tacked on after the fact with fewer features, there must /by necessity/ have been a new material introduced for both the default material and the default skybox specifically for feature level 0 with fewer features than extant client apps expected to be included by default. I imagine if filament were to be rebuilt from the ground up, this exception wouldn't exist. However, the end result is this somewhat messy redundancy. --- filament/CMakeLists.txt | 22 ++++++++ filament/src/details/Engine.cpp | 17 +++--- filament/src/details/Skybox.cpp | 9 +++- filament/src/materials/defaultMaterial.mat | 3 +- filament/src/materials/defaultMaterial0.mat | 12 +++++ filament/src/materials/skybox.mat | 10 +--- filament/src/materials/skybox0.mat | 60 +++++++++++++++++++++ 7 files changed, 116 insertions(+), 17 deletions(-) create mode 100644 filament/src/materials/defaultMaterial0.mat create mode 100644 filament/src/materials/skybox0.mat diff --git a/filament/CMakeLists.txt b/filament/CMakeLists.txt index e9973e7393a..b65e3cca9ba 100644 --- a/filament/CMakeLists.txt +++ b/filament/CMakeLists.txt @@ -245,6 +245,11 @@ set(MATERIAL_SRCS src/materials/vsmMipmap.mat ) +set(MATERIAL_ES2_SRCS + src/materials/defaultMaterial0.mat + src/materials/skybox0.mat +) + # Embed the binary resource blob for materials. get_resgen_vars(${RESOURCE_DIR} materials) list(APPEND PRIVATE_HDRS ${RESGEN_HEADER}) @@ -310,6 +315,23 @@ foreach (mat_src ${MATERIAL_SRCS}) list(APPEND MATERIAL_BINS ${output_path}) endforeach() +if (IS_MOBILE_TARGET AND FILAMENT_SUPPORTS_OPENGL) + foreach (mat_src ${MATERIAL_ES2_SRCS}) + get_filename_component(localname "${mat_src}" NAME_WE) + get_filename_component(fullname "${mat_src}" ABSOLUTE) + set(output_path "${MATERIAL_DIR}/${localname}.filamat") + + add_custom_command( + OUTPUT ${output_path} + COMMAND matc -a opengl -p ${MATC_TARGET} ${MATC_OPT_FLAGS} -o ${output_path} ${fullname} + MAIN_DEPENDENCY ${fullname} + DEPENDS matc + COMMENT "Compiling material ${mat_src} to ${output_path}" + ) + list(APPEND MATERIAL_BINS ${output_path}) + endforeach () +endif () + # Additional dependencies on included files for materials add_custom_command( diff --git a/filament/src/details/Engine.cpp b/filament/src/details/Engine.cpp index bf54ac44225..3e50fc71352 100644 --- a/filament/src/details/Engine.cpp +++ b/filament/src/details/Engine.cpp @@ -322,17 +322,22 @@ void FEngine::init() { driverApi.update3DImage(mDummyZeroTexture, 0, 0, 0, 0, 1, 1, 1, { zeroes, 4, Texture::Format::RGBA, Texture::Type::UBYTE }); - FMaterial::DefaultMaterialBuilder defaultMaterialBuilder; - defaultMaterialBuilder.package( - MATERIALS_DEFAULTMATERIAL_DATA, MATERIALS_DEFAULTMATERIAL_SIZE); - mDefaultMaterial = downcast(defaultMaterialBuilder.build(*const_cast(this))); - #ifdef FILAMENT_TARGET_MOBILE - if (UTILS_LIKELY(mActiveFeatureLevel > FeatureLevel::FEATURE_LEVEL_0)) + if (UTILS_UNLIKELY(mActiveFeatureLevel == FeatureLevel::FEATURE_LEVEL_0)) { + FMaterial::DefaultMaterialBuilder defaultMaterialBuilder; + defaultMaterialBuilder.package( + MATERIALS_DEFAULTMATERIAL0_DATA, MATERIALS_DEFAULTMATERIAL0_SIZE); + mDefaultMaterial = downcast(defaultMaterialBuilder.build(*const_cast(this))); + } else #endif { mDefaultColorGrading = downcast(ColorGrading::Builder().build(*this)); + FMaterial::DefaultMaterialBuilder defaultMaterialBuilder; + defaultMaterialBuilder.package( + MATERIALS_DEFAULTMATERIAL_DATA, MATERIALS_DEFAULTMATERIAL_SIZE); + mDefaultMaterial = downcast(defaultMaterialBuilder.build(*const_cast(this))); + float3 dummyPositions[1] = {}; short4 dummyTangents[1] = {}; mDummyMorphTargetBuffer->setPositionsAt(*this, 0, dummyPositions, 1, 0); diff --git a/filament/src/details/Skybox.cpp b/filament/src/details/Skybox.cpp index 7130d0dfe26..969eccdb455 100644 --- a/filament/src/details/Skybox.cpp +++ b/filament/src/details/Skybox.cpp @@ -118,7 +118,14 @@ FSkybox::FSkybox(FEngine& engine, const Builder& builder) noexcept FMaterial const* FSkybox::createMaterial(FEngine& engine) { Material::Builder builder; - builder.package(MATERIALS_SKYBOX_DATA, MATERIALS_SKYBOX_SIZE); +#ifdef FILAMENT_TARGET_MOBILE + if (UTILS_UNLIKELY(engine.getActiveFeatureLevel() == Engine::FeatureLevel::FEATURE_LEVEL_0)) { + builder.package(MATERIALS_SKYBOX0_DATA, MATERIALS_SKYBOX0_SIZE); + } else +#endif + { + builder.package(MATERIALS_SKYBOX_DATA, MATERIALS_SKYBOX_SIZE); + } auto material = builder.build(engine); return downcast(material); } diff --git a/filament/src/materials/defaultMaterial.mat b/filament/src/materials/defaultMaterial.mat index 7ee4e0e279a..c7db4eb0daa 100644 --- a/filament/src/materials/defaultMaterial.mat +++ b/filament/src/materials/defaultMaterial.mat @@ -1,7 +1,6 @@ material { name : "Filament Default Material", - shadingModel : unlit, - featureLevel : 0 + shadingModel : unlit } fragment { diff --git a/filament/src/materials/defaultMaterial0.mat b/filament/src/materials/defaultMaterial0.mat new file mode 100644 index 00000000000..914d29c3d1d --- /dev/null +++ b/filament/src/materials/defaultMaterial0.mat @@ -0,0 +1,12 @@ +material { + name : "Filament Default Material", + shadingModel : unlit, + featureLevel: 0 +} + +fragment { + void material(inout MaterialInputs material) { + prepareMaterial(material); + material.baseColor.rgb = vec3(0.8); + } +} diff --git a/filament/src/materials/skybox.mat b/filament/src/materials/skybox.mat index 4ac76a7feb5..1d36108a275 100644 --- a/filament/src/materials/skybox.mat +++ b/filament/src/materials/skybox.mat @@ -25,8 +25,7 @@ material { depthWrite : false, shadingModel : unlit, variantFilter : [ skinning, shadowReceiver, vsm ], - culling : none, - featureLevel : 0 + culling: none } fragment { @@ -36,15 +35,10 @@ fragment { if (materialParams.constantColor != 0) { sky = materialParams.color; } else { - #if MATERIAL_FEATURE_LEVEL == 0 - sky = vec4(textureCube(materialParams_skybox, variable_eyeDirection.xyz).rgb, 1.0); - #else - // textureLod() at 0.0 is more performant than texture(). sky = vec4(textureLod(materialParams_skybox, variable_eyeDirection.xyz, 0.0).rgb, 1.0); - #endif sky.rgb *= frameUniforms.iblLuminance; } - if (materialParams.showSun != 0 && frameUniforms.sun.w >= 0.0) { + if (materialParams.showSun != 0 && frameUniforms.sun.w >= 0.0f) { vec3 direction = normalize(variable_eyeDirection.xyz); // Assume the sun is a sphere vec3 sun = frameUniforms.lightColorIntensity.rgb * diff --git a/filament/src/materials/skybox0.mat b/filament/src/materials/skybox0.mat new file mode 100644 index 00000000000..2891e32f4b3 --- /dev/null +++ b/filament/src/materials/skybox0.mat @@ -0,0 +1,60 @@ +material { + name : Skybox, + parameters : [ + { + type : int, + name : showSun + }, + { + type : int, + name : constantColor + }, + { + type : samplerCubemap, + name : skybox + }, + { + type : float4, + name : color + } + ], + variables : [ + eyeDirection + ], + vertexDomain : device, + depthWrite : false, + shadingModel : unlit, + variantFilter : [ skinning, shadowReceiver, vsm ], + culling: none, + featureLevel: 0 +} + +fragment { + void material(inout MaterialInputs material) { + prepareMaterial(material); + vec4 sky; + if (materialParams.constantColor != 0) { + sky = materialParams.color; + } else { + sky = vec4(textureCube(materialParams_skybox, variable_eyeDirection.xyz).rgb, 1.0); + sky.rgb *= frameUniforms.iblLuminance; + } + if (materialParams.showSun != 0 && frameUniforms.sun.w >= 0.0) { + vec3 direction = normalize(variable_eyeDirection.xyz); + // Assume the sun is a sphere + vec3 sun = frameUniforms.lightColorIntensity.rgb * + (frameUniforms.lightColorIntensity.a * (4.0 * PI)); + float cosAngle = dot(direction, frameUniforms.lightDirection); + float x = (cosAngle - frameUniforms.sun.x) * frameUniforms.sun.z; + float gradient = pow(1.0 - saturate(x), frameUniforms.sun.w); + sky.rgb = sky.rgb + gradient * sun; + } + material.baseColor = sky; + } +} + +vertex { + void materialVertex(inout MaterialVertexInputs material) { + material.eyeDirection.xyz = material.worldPosition.xyz; + } +}