If you use AssetBundles, Unity might compile duplicate shaders. For example, if materials in two AssetBundles reference the same shaderA program that runs on the GPU. More info
See in Glossary, Unity might include a copy of the compiled shader in each AssetBundle. This can increase the memory and storage space your project uses, and break draw call batching.
To avoid duplicate shaders, add your shaders to an AssetBundle, and at runtime make sure you load the shaders AssetBundle first.
Use one of the following approaches:
Follow these steps:
Create a file that contains a list of the shader variants your built application uses.
If you target DirectX 12, Vulkan, Metal, or WebGPU, create a .graphicsState file. For more information, refer to Trace and manage PSO data collections.
Otherwise, create a .shaderVariants file. Refer to create a shader variant collection.
The list of shader variants provides the build pipeline with the information it needs to compile the shader variants your application uses. Otherwise, the build pipeline might strip shader variants you need, and materials might render using the bright pink error shader at runtime.
Assign the generated .graphicsState file or .shadervariants file to an AssetBundle.
Assign all your .shader assets to the same AssetBundle.
Assign your materials to either the shaders AssetBundle or other AssetBundles. In other AssetBundles, Unity detects the referenced .shader assets in the first AssetBundle, and doesn’t include duplicate shaders.
Build your project. At build time, Unity uses the information from the .graphicsState file or .shadervariants file to make sure it compiles all the shader variants your application uses.
At runtime, load and instantiate the AssetBundle containing the shaders first. Then load and instantiate the AssetBundles that contain materials.
For information on avoiding Unity including duplicate shaders from both your AssetBundles and your scenes, refer to Avoiding asset duplication.
Depending on how many shaders you have, putting all your shaders into a single AssetBundle might use a lot of memory at runtime. Shaders might also stay in memory when they’re no longer needed, because you can’t partially unload an AssetBundle.
To avoid this, create a separate AssetBundle for each group of shaders you use together. For example, an AssetBundle for each scene or each environment type.
For example:
.graphicsState file or .shadervariants file to an AssetBundle..shader assets to the same AssetBundle.