When I build bundles using the Addressables system, and go into Play Mode using the packed bundles, materials that use the Spine-Skeleton-URP (Universal Render Pipeline/Spine/Skeleton) do not work.
This happens both for when I instantiate SkeletonAnimation Prefabs from AssetReference, or when I load SkeletonDataAsset and put it into a SkeletonAnimation prefab and re-initialize the skeleton.
The resulting mesh shows up invisible but I can see the gizmo bones.
The aforementioned material, prefab, and shader are all packed into the same bundle. I tested it on a single scene, with only those assets packed, and the issue still persists.
The strange thing is that this only happens in an existing project, and I can't seem to find the exact root cause that's unique to that project. I created a brand new project, added URP, Spine, Addressables, all with the same settings, and built the bundles in the same exact way, and cannot replicate the issue.
The issue won't occur if I enable GPU instancing on the material. Or, the catch-all is that I set Instancing Variants to Keep All (from Strip Unused) in Graphics Settings. This at least shows me that this specific shader is getting stripped (though it appears in the bundle), but that is not the case for newly created projects, and I don't understand why...
Anyone have any idea on a particular setting that I may have missed?
Ah figured it out. Will post my findings later. 🙂
So here's the root cause based on my findings:
When using URP and the Lighting -> Additional Lights -> Cast Shadows feature is enabled in the active URP asset, all Forward Pass variants of the Universal Render Pipeline/Spine/Skeleton shader get stripped out as "invalid variants" by this snippet in the URP/Editor/ShaderPreprocessor.cs:
bool StripInvalidVariants(ShaderCompilerData compilerData)
bool isMainShadowNoCascades = compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadows);
bool isMainShadowCascades = compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsCascades);
bool isMainShadowScreen = compilerData.shaderKeywordSet.IsEnabled(m_MainLightShadowsScreen);
bool isMainShadow = isMainShadowNoCascades || isMainShadowCascades || isMainShadowScreen;
bool isAdditionalShadow = compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightShadows);
if (isAdditionalShadow && !(compilerData.shaderKeywordSet.IsEnabled(m_AdditionalLightsPixel) || compilerData.shaderKeywordSet.IsEnabled(m_ClusteredRendering) || compilerData.shaderKeywordSet.IsEnabled(m_DeferredStencil)))
return true; // <
bool isShadowVariant = isMainShadow || isAdditionalShadow;
if (!isShadowVariant && compilerData.shaderKeywordSet.IsEnabled(m_SoftShadows))
The rest gets stripped out for having unused features (in my case).
The Spine-Skeleton-URP.shader Forward Pass uses the following URP keywords:
// Universal Pipeline keywords
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS
#pragma multi_compile _ _MAIN_LIGHT_SHADOWS_CASCADE
#pragma multi_compile _ _ADDITIONAL_LIGHT_SHADOWS
#pragma multi_compile _ _SHADOWS_SOFT
Because of the way the condition is structured, when the _ADDITIONAL_LIGHT_SHADOWS feature is enabled, the variants get considered, but ultimately stripped as invalid for not having any of the other three keywords. When _ADDITIONAL_LIGHT_SHADOWS feature is disabled, some variants of the shader get to skip this step, and successfully end up in the asset bundle build.
I'm not sure if this is by design on the part of the Spine-Skeleton-URP shader, but getting the shader stripped out when URP features are added (rather than removed) did make the issue difficult to trace.