Shader Variants for Billboards even though they are not used

Avatar
  • updated
  • Not a bug

I tracked the shaders used in my project (through Project Settings -> Graphics first clear, then save after running the game), and I noticed that I get the newly introduced billboard variant, even though I'm not using it... or at least not actively.

Here is a part of the tracked shaders:

As you can see, I have the Billboard for Regular Polygon, Disc and Line, but not for Rect.

Things I'm using:

  • Regular Polygon with Transform Object
  • Rectangle with Transform Object
  • Disc with Transform and RectTransform Object
  • Line with RectTransform Object

Do you have an idea why I'm getting those variants/if I can disable this? I noticed that shader compiling creates noticable stutters when happening and cutting on the variants would be nice, especially if they are not used.

Reporting a bug? please specify Unity version:
2020.2.3f1
Reporting a bug? please specify Shapes version:
3.0.0
Reporting a bug? please specify Render Pipeline:
URP
Pinned replies
Avatar
Freya Holmér
  • Answer
  • Not a bug

right now I believe they should all compile regardless of which branches you use, which I recall I had to use due to some other issue that happened when they were lazily loaded

The stutters are kinda because it's designed to load shaders as you run into them, I feel like this shouldn't be related to variants though

you might want to warm them up when loading your app to prevent that from happening during gameplay?

https://docs.unity3d.com/ScriptReference/Shader.WarmupAllShaders.html

Avatar
Freya Holmér
  • Answer
  • Not a bug

right now I believe they should all compile regardless of which branches you use, which I recall I had to use due to some other issue that happened when they were lazily loaded

The stutters are kinda because it's designed to load shaders as you run into them, I feel like this shouldn't be related to variants though

you might want to warm them up when loading your app to prevent that from happening during gameplay?

https://docs.unity3d.com/ScriptReference/Shader.WarmupAllShaders.html

Avatar
Johannes Deml

I can't quite follow: When are they lazily loaded? In the editor or also in the build?

Sure, I know why stuttering happens and also know about prewarming, but I see a clear relation to variants. Since variants are their own shader programs they each take their own time to be compiled, therefore the compile time grows by a factor of two, if I have two variants of a shader (at at least that's what my understanding is, correct me if I'm wrong). Therefore, if I don't use one of the two variants, it would be nice to not need to compile it.

If you're telling me the lazy load only happens in the editor, that's fine as well. Then I know that I don't need to prewarm the shader on the device.

Avatar
Freya Holmér

I feel like there are three things I'm getting mixed up:
1. compiling shaders in the editor causing long compile times

2. Unity lazy-loading shaders at runtime causing stuttering

3. excluding shader variants (at runtime or in editor?)


so, uh, I'll just write some words on each!

1. generally, shader variants shouldn't be an issue in editor unless you are modifying shaders a lot. There is a shader cache that basically makes this a one-time-only compile, and then you should be fine after that. Shapes intentionally has all the shader variants compiled (in editor) in order to have everything ready when swapping keywords and such. Now, if you're talking about a *build* compile time rather than shader compile time in editor, then right now doing that is rather complicated (see point #3)

2. at runtime, I believe Unity will by default not pre-load shaders unless they are referenced, so if a new shader has to render, it will have a bit of a spike/stutter when loading, which might be noticeable especially on low end devices. If you want to make sure all shaders are loaded, then you might want to use WarmupAllShaders during the initial loading of the game/build (as in, not in editor)

3. currently I'm not sure what options Unity gives you when it comes to excluding Shader variants, at least not when shaders are set to compile all variants as it is (which Shapes does). The reason for this is that Shapes allows you to draw from code, so I can't predict what shaders are referenced or not, so it has to have everything loaded and ready. Now, it is possible to move individual .shader files that you specifically don't use in your project out of the resources folder, but this will literally break using those shaders in Shapes, and I don't know if anything will work if you leave those out, unless I specifically create support for excluding certain shaders for shorted build times

Avatar
Johannes Deml

Thanks for your in depth reply. Sorry for not being too clear, I see that my question was not precise enough.

So my "problem" is: I want to find out which shaders I need to prewarm in the build to avoid stutters. For getting all shaders I need to prewarm, I usually track the shaders in the editor and generate the ShaderVariantCollection from that. Now I was quite surprised to see, that there are Billboard shader variants included in the tracked shaders, even though I don't use them (at least not actively).

My question now is: Do I need to prewarm the billboard shader variants, since they are used for e.g. Caps or something similar, or will they not be used in the build.

The variants adding to the build size is actually an interesting point, but I feel like that's not that big of a problem (at least for me).

From your answer I understand, that the shaders will be loaded in the editor to enable quick switching (awesome feature, didn't think of that), so I guess the answer to my question is: If I don't have any components set to billboard, no matter if they are inside transforms or inside RectTransforms, they will not be compiled in runtime and therefore I can remove them from my ShaderVariantCollection, that I want to preload.

Am I correct with this assumption? :)

Avatar
Freya Holmér
Quote from Johannes Deml

Thanks for your in depth reply. Sorry for not being too clear, I see that my question was not precise enough.

So my "problem" is: I want to find out which shaders I need to prewarm in the build to avoid stutters. For getting all shaders I need to prewarm, I usually track the shaders in the editor and generate the ShaderVariantCollection from that. Now I was quite surprised to see, that there are Billboard shader variants included in the tracked shaders, even though I don't use them (at least not actively).

My question now is: Do I need to prewarm the billboard shader variants, since they are used for e.g. Caps or something similar, or will they not be used in the build.

The variants adding to the build size is actually an interesting point, but I feel like that's not that big of a problem (at least for me).

From your answer I understand, that the shaders will be loaded in the editor to enable quick switching (awesome feature, didn't think of that), so I guess the answer to my question is: If I don't have any components set to billboard, no matter if they are inside transforms or inside RectTransforms, they will not be compiled in runtime and therefore I can remove them from my ShaderVariantCollection, that I want to preload.

Am I correct with this assumption? :)

you can probably remove the variants that you don't use yeah, there are no hidden/sneaky ways that Shapes uses variants apart from what you would expect it to. however, I don't know if you can skip compiling some of the branches if you use one of the branches inside the same .shader file. I recall there being a difference between #pragma multi_compile vs shader_feature, where shader_feature compiles on the fly, while multi_compile compiles all branches. (I use multi_compile)

so the real answer is I have no idea! try it I suppose :) nothing should break by excluding branches you don't use at least