diff --git a/filament/src/details/Material.cpp b/filament/src/details/Material.cpp index c5d6b83f42e..5f641eb167f 100644 --- a/filament/src/details/Material.cpp +++ b/filament/src/details/Material.cpp @@ -605,10 +605,13 @@ void FMaterial::createAndCacheProgram(Program&& p, Variant variant) const noexce FEngine const& engine = mEngine; DriverApi& driverApi = mEngine.getDriverApi(); - // Check if the default material has this program cached - if (mMaterialDomain == MaterialDomain::SURFACE && + bool const isSharedVariant = + (mMaterialDomain == MaterialDomain::SURFACE) && !mIsDefaultMaterial && !mHasCustomDepthShader && - Variant::isValidDepthVariant(variant)) { + Variant::isValidDepthVariant(variant); + + // Check if the default material has this program cached + if (isSharedVariant) { FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); if (pDefaultMaterial) { auto program = pDefaultMaterial->mCachedPrograms[variant.key]; @@ -627,9 +630,7 @@ void FMaterial::createAndCacheProgram(Program&& p, Variant variant) const noexce // If the default material doesn't already have this program cached, and all caching conditions // are met (Surface Domain and no custom depth shader), cache it now. // New Materials will inherit these program automatically. - if (mMaterialDomain == MaterialDomain::SURFACE && - !mIsDefaultMaterial && !mHasCustomDepthShader && - Variant::isValidDepthVariant(variant)) { + if (isSharedVariant) { FMaterial const* const pDefaultMaterial = engine.getDefaultMaterial(); if (pDefaultMaterial && !pDefaultMaterial->mCachedPrograms[variant.key]) { // set the tag to the default material name @@ -1076,6 +1077,21 @@ void FMaterial::processPushConstants(FEngine& engine, MaterialParser const* pars } void FMaterial::precacheDepthVariants(FEngine& engine) { + // pre-cache all depth variants inside the default material. Note that this should be + // entirely optional; if we remove this pre-caching, these variants will be populated + // later, when/if needed by createAndCacheProgram(). Doing it now potentially uses more + // memory and increases init time, but reduces hiccups during the first frame. + if (UTILS_UNLIKELY(mIsDefaultMaterial)) { + auto const allDepthVariants = VariantUtils::getDepthVariants(); + for (auto const variant: allDepthVariants) { + assert_invariant(Variant::isValidDepthVariant(variant)); + if (hasVariant(variant)) { + prepareProgram(variant); + } + } + return; + } + // if possible pre-cache all depth variants from the default material if (mMaterialDomain == MaterialDomain::SURFACE && !mIsDefaultMaterial &&