Search Unity

Question can IPreprocessShaders check SubShader LOD?

Discussion in 'Shaders' started by funkyCoty, Oct 28, 2020.

  1. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    I have several custom surface shaders defined with LODs, like this:

    SubShader{ LOD 400 }
    SubShader{ LOD 500 }
    SubShader{ LOD 600 }

    On PC, I let users change their Shader.globalMaximumLOD, works great. On Consoles, it just means a lot of memory wasted on book keeping these shader variants. I figured I could strip them, via IPreprocessShaders, but there does not seem to be a clear path.

    Is there some way to do this?
     
    Last edited: Oct 28, 2020
  2. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    Hi!
    I don't think there's a way to do that right now.
    I'll write this down as a feature request :)
     
  3. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    Damn, I see. Hopefully it can be done relatively soon, kinda desperately grasping at ways to lower runtime memory with shaders (we have a lot).

    Any tips for ways I could go about something similar? My next idea was adding tags to sub shaders, but there doesn't seem to be a way to strip by tags either.

    edit: I think for now I'm just going to refactor things to not use SubShaders, and instead just use a multi_compile. In our case this seems feasible.
     
    Last edited: Oct 28, 2020
  4. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    Yes, using multi_compile for this is a good alternative for now.
     
    funkyCoty likes this.
  5. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    It works for our game thankfully. However, I can still see some valid use cases. For example, what if I want to toggle tessellation on one .shader file via subshader LODs, and want to strip out the tessellation variants from the build? My current solution for that is actually just making two .shader files, not very elegant, but its an okay workaround.
     
  6. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    As I said - feature request added :)
     
    funkyCoty likes this.
  7. alphabin

    alphabin

    Joined:
    Jun 10, 2015
    Posts:
    2
    Has this feature been released?
     
  8. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
  9. alphabin

    alphabin

    Joined:
    Jun 10, 2015
    Posts:
    2
    Last edited: Mar 7, 2022
  10. RINNUXEI

    RINNUXEI

    Joined:
    Sep 3, 2015
    Posts:
    32
    Hey, just want to know can I manually strip shader variants that generated by subshaders that have a specific tag? Currently, the ShaderCompilerData provided by IPreprocessShaders.OnProcessShader only allows me to check shader keywords.
     
  11. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
  12. RINNUXEI

    RINNUXEI

    Joined:
    Sep 3, 2015
    Posts:
    32
    Hi thank you for the reply.

    I checked that API, but it seems it needs a ShaderData object, which although can be created by a Shader object, how can I then strip shader variants from that shader object? As I understand, IPreprocessShaders.OnProcessShader provides a list of ShaderCompilerData, from which we can remove unnecessary ShaderCompilerData to strip shader variants, but how can we do it with the shader object itself?
     
  13. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    OnProcessShader
    has three parameters. You can create a
    ShaderData
    object from the first one, get the subshader index from the second one (
    snippet.pass.SubshaderIndex
    ) and check the tags of this subshader. Then you know whether it's currently processing a subshader with the tag you're interested in or not.
     
  14. RINNUXEI

    RINNUXEI

    Joined:
    Sep 3, 2015
    Posts:
    32
    Thank you very much for the detail.

    So when I know it's currently processing a subshader with the tag I'm interested in, then I just set the third parameter, which is the list of ShaderCompilerData to an empty list? What I want to do is to strip shader variants generated by that subshader. I thought OnProcessShader is called per shader, and the shader variants generated by other subshaders, which I won't strip are also in that list. Is the OnProcessShader actually called per subshader, or is there any other misunderstandings?
     
  15. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,014
    Yes.
    It can be called multiple times per shader stage of a specific pass, depending on the number of variants.
     
    RINNUXEI likes this.
  16. RINNUXEI

    RINNUXEI

    Joined:
    Sep 3, 2015
    Posts:
    32
    I see it. Thanks, aleksandrk! Your help is very much appreciated.
     
    aleksandrk likes this.