From 77fcf4d260a178bcdd0c29392dc78612ffe43f2b Mon Sep 17 00:00:00 2001 From: Mathias Agopian Date: Mon, 14 Nov 2022 23:38:59 -0800 Subject: [PATCH] don't store the light direction in the shadowmap structure We already have it in the Light structure. --- RELEASE_NOTES.md | 2 ++ filament/src/ShadowMapManager.cpp | 2 -- .../include/filament/MaterialEnums.h | 2 +- .../include/private/filament/UibStructs.h | 7 ++----- shaders/src/common_lighting.fs | 3 ++- shaders/src/common_shadowing.glsl | 6 +++--- shaders/src/common_types.glsl | 5 ++--- shaders/src/getters.fs | 3 +-- shaders/src/light_directional.fs | 2 +- shaders/src/light_punctual.fs | 3 ++- shaders/src/shading_unlit.fs | 2 +- shaders/src/shadowing.fs | 21 +++++++------------ 12 files changed, 25 insertions(+), 33 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index dd02dcf8e2..95108b9387 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -5,6 +5,8 @@ A new header is inserted each time a *tag* is created. ## main branch +- engine: optimize per-shadow UBO [⚠️ **Recompile Materials**] + ## v1.29.0 - gltfio: calculate primitive's AABB correctly. diff --git a/filament/src/ShadowMapManager.cpp b/filament/src/ShadowMapManager.cpp index c97d144c1c..66186f96df 100644 --- a/filament/src/ShadowMapManager.cpp +++ b/filament/src/ShadowMapManager.cpp @@ -681,7 +681,6 @@ void ShadowMapManager::prepareSpotShadowMap(ShadowMap& shadowMap, const double f = shadowMap.getCamera().getCullingFar(); s.shadows[shadowIndex].layer = shadowMap.getLayer(); s.shadows[shadowIndex].lightFromWorldMatrix = shaderParameters.lightSpace; - s.shadows[shadowIndex].direction = direction; s.shadows[shadowIndex].normalBias = normalBias * wsTexelSizeAtOneMeter; s.shadows[shadowIndex].lightFromWorldZ = shaderParameters.lightFromWorldZ; s.shadows[shadowIndex].texelSizeAtOneMeter = wsTexelSizeAtOneMeter; @@ -763,7 +762,6 @@ void ShadowMapManager::preparePointShadowMap(ShadowMap& shadowMap, const double f = shadowMap.getCamera().getCullingFar(); s.shadows[shadowIndex].layer = shadowMap.getLayer(); s.shadows[shadowIndex].lightFromWorldMatrix = shaderParameters.lightSpace; - s.shadows[shadowIndex].direction = {}; // no direction of point lights s.shadows[shadowIndex].normalBias = normalBias * wsTexelSizeAtOneMeter; s.shadows[shadowIndex].lightFromWorldZ = shaderParameters.lightFromWorldZ; s.shadows[shadowIndex].texelSizeAtOneMeter = wsTexelSizeAtOneMeter; diff --git a/libs/filabridge/include/filament/MaterialEnums.h b/libs/filabridge/include/filament/MaterialEnums.h index 00d5154d1f..0393f8370c 100644 --- a/libs/filabridge/include/filament/MaterialEnums.h +++ b/libs/filabridge/include/filament/MaterialEnums.h @@ -27,7 +27,7 @@ namespace filament { // update this when a new version of filament wouldn't work with older materials -static constexpr size_t MATERIAL_VERSION = 29; +static constexpr size_t MATERIAL_VERSION = 30; /** * Supported shading models diff --git a/libs/filabridge/include/private/filament/UibStructs.h b/libs/filabridge/include/private/filament/UibStructs.h index 2d13ca2098..8ba8f0a00b 100644 --- a/libs/filabridge/include/private/filament/UibStructs.h +++ b/libs/filabridge/include/private/filament/UibStructs.h @@ -248,17 +248,14 @@ struct ShadowUib { // NOLINT(cppcoreguidelines-pro-type-member-init) static constexpr std::string_view _name{ "ShadowUniforms" }; struct alignas(16) ShadowData { math::mat4f lightFromWorldMatrix; // 64 - math::float3 direction; // 12 - float normalBias; // 4 math::float4 lightFromWorldZ; // 16 - + math::float4 reserved0; // 12 float texelSizeAtOneMeter; // 4 float bulbRadiusLs; // 4 float nearOverFarMinusNear; // 4 + float normalBias; // 4 bool elvsm; // 4 - uint32_t layer; // 4 - uint32_t reserved0; // 4 uint32_t reserved1; // 4 uint32_t reserved2; // 4 }; diff --git a/shaders/src/common_lighting.fs b/shaders/src/common_lighting.fs index 6aa419be26..d4ff748948 100644 --- a/shaders/src/common_lighting.fs +++ b/shaders/src/common_lighting.fs @@ -2,8 +2,9 @@ struct Light { vec4 colorIntensity; // rgb, pre-exposed intensity vec3 l; float attenuation; - vec3 worldPosition; + highp vec3 worldPosition; float NoL; + highp vec3 direction; float zLight; bool castsShadows; bool contactShadows; diff --git a/shaders/src/common_shadowing.glsl b/shaders/src/common_shadowing.glsl index 96562ea4bb..f882347313 100644 --- a/shaders/src/common_shadowing.glsl +++ b/shaders/src/common_shadowing.glsl @@ -12,11 +12,11 @@ */ highp vec4 computeLightSpacePosition(highp vec3 p, const highp vec3 n, - const highp vec3 l, const float b, const highp mat4 lightFromWorldMatrix) { + const highp vec3 dir, const float b, const highp mat4 lightFromWorldMatrix) { #if !defined(VARIANT_HAS_VSM) - highp float NoL = saturate(dot(n, l)); - highp float sinTheta = sqrt(1.0 - NoL * NoL); + highp float cosTheta = saturate(dot(n, dir)); + highp float sinTheta = sqrt(1.0 - cosTheta * cosTheta); p += n * (sinTheta * b); #endif diff --git a/shaders/src/common_types.glsl b/shaders/src/common_types.glsl index ffc1314132..e88f8e8bf0 100644 --- a/shaders/src/common_types.glsl +++ b/shaders/src/common_types.glsl @@ -2,15 +2,14 @@ // UBOs, which is is the case here. struct ShadowData { highp mat4 lightFromWorldMatrix; - highp vec3 direction; - float normalBias; highp vec4 lightFromWorldZ; + highp vec4 reserved0; float texelSizeAtOneMeter; float bulbRadiusLs; float nearOverFarMinusNear; + float normalBias; bool elvsm; uint layer; - uint reserved0; uint reserved1; uint reserved2; }; diff --git a/shaders/src/getters.fs b/shaders/src/getters.fs index f684dd8be7..f08685419f 100644 --- a/shaders/src/getters.fs +++ b/shaders/src/getters.fs @@ -94,9 +94,8 @@ highp vec3 getNormalizedViewportCoord2() { } #if defined(VARIANT_HAS_SHADOWING) && defined(VARIANT_HAS_DYNAMIC_LIGHTING) -highp vec4 getSpotLightSpacePosition(uint index, highp float zLight) { +highp vec4 getSpotLightSpacePosition(uint index, highp vec3 dir, highp float zLight) { highp mat4 lightFromWorldMatrix = shadowUniforms.shadows[index].lightFromWorldMatrix; - highp vec3 dir = shadowUniforms.shadows[index].direction; // for spotlights, the bias depends on z float bias = shadowUniforms.shadows[index].normalBias * zLight; diff --git a/shaders/src/light_directional.fs b/shaders/src/light_directional.fs index bad61669f2..2c4dc4b907 100644 --- a/shaders/src/light_directional.fs +++ b/shaders/src/light_directional.fs @@ -56,7 +56,7 @@ void evaluateDirectionalLight(const MaterialInputs material, bool cascadeHasVisibleShadows = bool(frameUniforms.cascades & ((1u << cascade) << 8u)); bool hasDirectionalShadows = bool(frameUniforms.directionalShadows & 1u); if (hasDirectionalShadows && cascadeHasVisibleShadows) { - highp vec4 shadowPosition = getShadowPosition(true, 0u, cascade, 0.0f); + highp vec4 shadowPosition = getShadowPosition(cascade); visibility = shadow(true, light_shadowMap, cascade, shadowPosition, 0.0f); } if ((frameUniforms.directionalShadows & 0x2u) != 0u && visibility > 0.0) { diff --git a/shaders/src/light_punctual.fs b/shaders/src/light_punctual.fs index 23a0e60497..cc3cf072b3 100644 --- a/shaders/src/light_punctual.fs +++ b/shaders/src/light_punctual.fs @@ -150,6 +150,7 @@ Light getLight(const uint lightIndex) { light.colorIntensity.w = computePreExposedIntensity(intensity, frameUniforms.exposure); light.l = normalize(posToLight); light.attenuation = getDistanceAttenuation(posToLight, positionFalloff.w); + light.direction = direction; light.NoL = saturate(dot(shading_normal, light.l)); light.worldPosition = positionFalloff.xyz; light.channels = channels; @@ -219,7 +220,7 @@ void evaluatePunctualLights(const MaterialInputs material, light.zLight = dot(shadowUniforms.shadows[shadowIndex].lightFromWorldZ, vec4(getWorldPosition(), 1.0)); } - highp vec4 shadowPosition = getShadowPosition(false, shadowIndex, 0u, light.zLight); + highp vec4 shadowPosition = getShadowPosition(shadowIndex, light.direction, light.zLight); visibility = shadow(false, light_shadowMap, shadowIndex, shadowPosition, light.zLight); } diff --git a/shaders/src/shading_unlit.fs b/shaders/src/shading_unlit.fs index 32adb16a9b..d4fd556e08 100644 --- a/shaders/src/shading_unlit.fs +++ b/shaders/src/shading_unlit.fs @@ -50,7 +50,7 @@ vec4 evaluateMaterial(const MaterialInputs material) { bool cascadeHasVisibleShadows = bool(frameUniforms.cascades & ((1u << cascade) << 8u)); bool hasDirectionalShadows = bool(frameUniforms.directionalShadows & 1u); if (hasDirectionalShadows && cascadeHasVisibleShadows) { - highp vec4 shadowPosition = getShadowPosition(true, 0u, cascade, 0.0f); + highp vec4 shadowPosition = getShadowPosition(cascade); visibility = shadow(true, light_shadowMap, cascade, shadowPosition, 0.0f); } if ((frameUniforms.directionalShadows & 0x2u) != 0u && visibility > 0.0) { diff --git a/shaders/src/shadowing.fs b/shaders/src/shadowing.fs index 9a1a95ada7..bcc459e405 100644 --- a/shaders/src/shadowing.fs +++ b/shaders/src/shadowing.fs @@ -477,22 +477,17 @@ float ShadowSample_VSM(const bool ELVSM, const mediump sampler2DArray shadowMap, */ // get texture coordinate for directional and spot shadow maps -highp vec4 getShadowPosition(const bool DIRECTIONAL, - const uint index, const uint cascade, const highp float zLight) { - highp vec4 p; - // This conditional is resolved at compile time - if (DIRECTIONAL) { #if defined(VARIANT_HAS_DIRECTIONAL_LIGHTING) - p = getCascadeLightSpacePosition(cascade); -#endif - } else { -#if defined(VARIANT_HAS_DYNAMIC_LIGHTING) - p = getSpotLightSpacePosition(index, zLight); -#endif - } - return p; +highp vec4 getShadowPosition(const uint cascade) { + return getCascadeLightSpacePosition(cascade); } +#endif +#if defined(VARIANT_HAS_DYNAMIC_LIGHTING) +highp vec4 getShadowPosition(const uint index, const highp vec3 dir, const highp float zLight) { + return getSpotLightSpacePosition(index, dir, zLight); +} +#endif uint getPointLightFace(const highp vec3 r) { highp vec4 tc;