Hi guys. I'm writing a minecraft-like voxel generator and renderer using pure ECS. Each chunk is 16x16 and is its own entity with its own renderer, which are instantiated from a prefab which is constructed at runtime in a bootstrapper. The issue I ran into at first, was that the build would crash upon startup. I looked at the log and it mentioned about argumentnullexception regarding the shader, and I figured out the shader is not included in the build. So I did some googling and was told to put the shader (URP Lit) in the always include shader list in graphics settings. When I do that, the build takes a bit before erroring out, mentioning a too-high shader variant count of over 1 million - 7 million. The "game" works perfectly fine in play mode, and I don't know what I'm doing wrong.
#Insane Shader Variant count
1 messages · Page 1 of 1 (latest)
URP shaders have lots of variants, and the manual warns against throwing such shaders into always included shaders.
You should instead have the resource (Shader or a prepared Material) referenced somewhere in the build. The reference can be anything from a serialized field in a ScriptableObject/MonoBehaviour in one of the scenes to a baked reference in a subscene, either directly in a managed component or via a UnityObjectRef. It would be best if this was made useful and actually fed into the thing that ultimately uses your shader/material. You can also use a shader variant collection (add it to the preloaded shaders section in graphics settings) to ensure required necessary shader variants are available in the build, which also means you can use Shader.Find without referencing the resource directly.
Attaching the shader to a scriptableobject, referenced by a monobehaviour in the scene did work, thank you.
Ultimately, my goal is to do away with subscenes/baking entirely and gameobjects/monobehaviours if possible for this project and was wondering if there was a purely ecs workflow for this. Or if going for that is even feasible/something I should be doing.
Clearly you'll need to store resources somewhere in the build. If not in subscenes or normal scenes, there's always Resources, Addressables, or custom AssetBundle management for UnityEngine.Object-derived content. You could add an entity prefab to a build with IEntitySceneBuildAdditions independent of having a subscene, but otherwise - for "purely ECS" - serialization generally wants a subscene to know what the build needs.
thus-far i've been loading my textures just through Resources.load in my bootstrapper
I played around a bit and was able to get it to work by making a coy of the sahder im using, adding it to my resources, and loading it through resources.load.
Is there a way I can load the shader like this without making a bespoke copy of my own?
thanks for all the advice btw
Add any object that holds a reference to it, same as when you're referencing content from within a scene.
I think I found a medium I'm happy with: ScriptableObject in my resources that holds the shader reference. Thanks again for the help.
Shader Variant Collections doesn't necessarily ensure they're available, it just loads them at startup
If it's still not available for whatever reason it will just error then instead
https://docs.unity3d.com/Manual/shader-variant-collections.html
A shader variant collection is effectively a list of shader variants. Use shader variant collections to prewarm shader variants, or to ensure that shader variants that are required at runtime but not referenced in a scene are not excluded (“stripped”) from your build.
It works the same as if they're referenced, but referenced shaders are still sometimes missing for whatever mysterious reason unity wants them to