diff --git a/NEW_RELEASE_NOTES.md b/NEW_RELEASE_NOTES.md index c0d28cb1b7..63c08d6cc6 100644 --- a/NEW_RELEASE_NOTES.md +++ b/NEW_RELEASE_NOTES.md @@ -9,3 +9,4 @@ appropriate header in [RELEASE_NOTES.md](./RELEASE_NOTES.md). ## Release notes for next branch cut - Update CMake minimum version to 3.22.1 +- material: Add a material parameter to control shadow far attenuation (b/436680157) diff --git a/docs_src/src_markdeep/Materials.md.html b/docs_src/src_markdeep/Materials.md.html index 93ee299864..53b8793254 100644 --- a/docs_src/src_markdeep/Materials.md.html +++ b/docs_src/src_markdeep/Materials.md.html @@ -1217,6 +1217,23 @@ material { } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +### General: shadowFarAttenuation + +Type +: `boolean` + +Value +: `true` or `false`. Defaults to `true`. + +Description +: When set to `false`, the directional light shadow is no longer attenuated at near the far plane. + +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ JSON +material { + shadowFarAttenuation : true +} +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + ### General: quality Type diff --git a/libs/filamat/include/filamat/MaterialBuilder.h b/libs/filamat/include/filamat/MaterialBuilder.h index b71fb1f182..c33ad580e0 100644 --- a/libs/filamat/include/filamat/MaterialBuilder.h +++ b/libs/filamat/include/filamat/MaterialBuilder.h @@ -535,6 +535,9 @@ public: //! Enable / disable the cheapest linear fog, disabled by default. MaterialBuilder& linearFog(bool enabled) noexcept; + //! Enable / disable shadow far attenuation, enabled by default. + MaterialBuilder& shadowFarAttenuation(bool enabled) noexcept; + //! Enable / disable multi-bounce ambient occlusion, disabled by default on mobile. MaterialBuilder& multiBounceAmbientOcclusion(bool multiBounceAO) noexcept; @@ -958,6 +961,7 @@ private: bool mFlipUV = true; bool mLinearFog = false; + bool mShadowFarAttenuation = true; bool mMultiBounceAO = false; bool mMultiBounceAOSet = false; diff --git a/libs/filamat/src/MaterialBuilder.cpp b/libs/filamat/src/MaterialBuilder.cpp index e5dfe2d35d..2e1736350d 100644 --- a/libs/filamat/src/MaterialBuilder.cpp +++ b/libs/filamat/src/MaterialBuilder.cpp @@ -549,6 +549,11 @@ MaterialBuilder& MaterialBuilder::linearFog(bool const enabled) noexcept { return *this; } +MaterialBuilder& MaterialBuilder::shadowFarAttenuation(bool const enabled) noexcept { + mShadowFarAttenuation = enabled; + return *this; +} + MaterialBuilder& MaterialBuilder::customSurfaceShading(bool const customSurfaceShading) noexcept { mCustomSurfaceShading = customSurfaceShading; return *this; @@ -719,6 +724,7 @@ void MaterialBuilder::prepareToBuild(MaterialInfo& info) noexcept { info.clearCoatIorChange = mClearCoatIorChange; info.flipUV = mFlipUV; info.linearFog = mLinearFog; + info.shadowFarAttenuation = mShadowFarAttenuation; info.requiredAttributes = mRequiredAttributes; info.blendingMode = mBlendingMode; info.postLightingBlendingMode = mPostLightingBlendingMode; diff --git a/libs/filamat/src/shaders/CodeGenerator.cpp b/libs/filamat/src/shaders/CodeGenerator.cpp index 1d8e4aacd8..abec5c6b22 100644 --- a/libs/filamat/src/shaders/CodeGenerator.cpp +++ b/libs/filamat/src/shaders/CodeGenerator.cpp @@ -252,6 +252,8 @@ utils::io::sstream& CodeGenerator::generateCommonProlog(utils::io::sstream& out, if (stage == ShaderStage::FRAGMENT) { CodeGenerator::generateDefine(out, "FILAMENT_LINEAR_FOG", material.linearFog); + CodeGenerator:generateDefine(out, "FILAMENT_SHADOW_FAR_ATTENUATION", + material.shadowFarAttenuation); CodeGenerator::generateDefine(out, "MATERIAL_HAS_CUSTOM_DEPTH", material.userMaterialHasCustomDepth); } diff --git a/libs/filamat/src/shaders/MaterialInfo.h b/libs/filamat/src/shaders/MaterialInfo.h index 1bd3ce2737..5f0f9e98e4 100644 --- a/libs/filamat/src/shaders/MaterialInfo.h +++ b/libs/filamat/src/shaders/MaterialInfo.h @@ -45,6 +45,7 @@ struct UTILS_PUBLIC MaterialInfo { bool clearCoatIorChange; bool flipUV; bool linearFog; + bool shadowFarAttenuation; bool multiBounceAO; bool multiBounceAOSet; bool specularAOSet; diff --git a/libs/filament-matp/src/ParametersProcessor.cpp b/libs/filament-matp/src/ParametersProcessor.cpp index d10f1c680f..489d4ad2c8 100644 --- a/libs/filament-matp/src/ParametersProcessor.cpp +++ b/libs/filament-matp/src/ParametersProcessor.cpp @@ -1190,6 +1190,11 @@ static bool processLinearFog(MaterialBuilder& builder, const JsonishValue& value return true; } +static bool processShadowFarAttenuation(MaterialBuilder& builder, const JsonishValue& value) { + builder.shadowFarAttenuation(value.toJsonBool()->getBool()); + return true; +} + static bool processMultiBounceAO(MaterialBuilder& builder, const JsonishValue& value) { builder.multiBounceAmbientOcclusion(value.toJsonBool()->getBool()); return true; @@ -1411,6 +1416,7 @@ ParametersProcessor::ParametersProcessor() { mParameters["stereoscopicType"] = { &processStereoscopicType, Type::STRING }; mParameters["useDefaultDepthVariant"] = { &processUseDefaultDepthVariant, Type::BOOL }; mParameters["linearFog"] = { &processLinearFog, Type::BOOL }; + mParameters["shadowFarAttenuation"] = { &processShadowFarAttenuation, Type::BOOL }; } bool ParametersProcessor::process(MaterialBuilder& builder, const JsonishObject& jsonObject) { diff --git a/shaders/src/surface_light_directional.fs b/shaders/src/surface_light_directional.fs index fe054e0774..994b9d33d9 100644 --- a/shaders/src/surface_light_directional.fs +++ b/shaders/src/surface_light_directional.fs @@ -61,12 +61,14 @@ void evaluateDirectionalLight(const MaterialInputs material, #if defined(MATERIAL_HAS_SHADOW_STRENGTH) applyShadowStrength(visibility, material.shadowStrength); #endif +#if defined (FILAMENT_SHADOW_FAR_ATTENUATION) // shadow far attenuation highp vec3 v = getWorldPosition() - getWorldCameraPosition(); // (viewFromWorld * v).z == dot(transpose(viewFromWorld), v) highp float z = dot(transpose(getViewFromWorldMatrix())[2].xyz, v); highp vec2 p = frameUniforms.shadowFarAttenuationParams; visibility = 1.0 - ((1.0 - visibility) * saturate(p.x - z * z * p.y)); +#endif } if ((frameUniforms.directionalShadows & 0x2) != 0 && visibility > 0.0) { if ((object_uniforms_flagsChannels & FILAMENT_OBJECT_CONTACT_SHADOWS_BIT) != 0) { diff --git a/shaders/src/surface_shading_unlit.fs b/shaders/src/surface_shading_unlit.fs index 88b1bd258e..c9ccbdc869 100644 --- a/shaders/src/surface_shading_unlit.fs +++ b/shaders/src/surface_shading_unlit.fs @@ -50,12 +50,14 @@ vec4 evaluateMaterial(const MaterialInputs material) { #if defined(MATERIAL_HAS_SHADOW_STRENGTH) applyShadowStrength(visibility, material.shadowStrength); #endif +#if defined (FILAMENT_SHADOW_FAR_ATTENUATION) // shadow far attenuation highp vec3 v = getWorldPosition() - getWorldCameraPosition(); // (viewFromWorld * v).z == dot(transpose(viewFromWorld), v) highp float z = dot(transpose(getViewFromWorldMatrix())[2].xyz, v); highp vec2 p = frameUniforms.shadowFarAttenuationParams; visibility = 1.0 - ((1.0 - visibility) * saturate(p.x - z * z * p.y)); +#endif } if ((frameUniforms.directionalShadows & 0x2) != 0 && visibility > 0.0) { if ((object_uniforms_flagsChannels & FILAMENT_OBJECT_CONTACT_SHADOWS_BIT) != 0) {