Shader variants for RPM avatar missing when loaded in addressable scene
Opened this issue · 2 comments
I’ve encountered an issue with shader variants when loading GLTF objects into an addressable scene: some materials look wrong (no transparency, wrong lighting...).
After investigating, I discovered that the necessary shader variant was missing, causing Unity to apply a fallback shader. To troubleshoot, I enabled strictShaderVariantMatching in the Project Settings/Player, which resulted in numerous ‘Shader Shader Graphs/glTF-pbrMetallicRoughness, subshader 0, pass 0, stage pixel: variant SHADOWS_SHADOWMASK _ADDITIONAL_LIGHTS _MAIN_LIGHT_SHADOWS_CASCADE _SHADOWS_SOFT _SURFACE_TYPE_TRANSPARENT not found.’ errors.
I confirmed that glTFastShaderVariantsURP.shadervariants is included in the PreloadedShaders array, so I was puzzled by this issue. Loading an object into a built-in scene worked as expected. However, loading the same object into a scene loaded from Unity Addressables resulted in missing shader variants.
I’ve created a test project to demonstrate this issue: https://github.com/dnnkeeper/UnityRPMLoadingTest
After discussion in forum I managed to pin down that ShaderGraphMaterialGenerator is unable to find suitable shader using Shader.Find method because shader is loaded with the Addressable system.
I replaced Shader.Find method with this code, and my issue was resolved after I added glTF-pbrMetallicRoughness.shadergraph as Shader Graphs/glTF-pbrMetallicRoughness to addressable group
protected static Shader FindShader(string shaderName, ICodeLogger logger)
{
var shaderLoading = Addressables.LoadAssetAsync<Shader>(shaderName);
Shader shader = shaderLoading.WaitForCompletion();
if (shader != null)
{
return shader;
}
shader = Shader.Find(shaderName);
if (shader == null)
{
logger?.Error(LogCode.ShaderMissing, shaderName);
}
return shader;
}
It seems that GLTF package needs to reference the Addressable system and use this loading method when this system is present.
@BorisDex Thanks for reporting and putting in the effort to pin it down!
I think this would be a meaningful addition, given it's wrapped in a version define and documented properly.
After giving it some more thought we concluded that it's probably a better solution to create an injection point for FindShader
. Users are then able to implement their own shader lookup solution without introducing fixed heuristics for Addressables.
I cannot offer a timeline yet.