Search Unity

Question How to include correct shaders variants for a Post-Processing Custom Effect into a build? (Solved)

Discussion in 'Shaders' started by vladstorm, Dec 29, 2022.

  1. vladstorm

    vladstorm

    Joined:
    Oct 4, 2021
    Posts:
    9
    Hi,

    I wrote a Post-Processing (PP) custom effect for a Built-in RP. Unity 2022.2
    The effect has multiple shaders with multiple shader_feature in each - which are switching via shader keywords saved in PP volume params.
    Everything works in the Editor.

    but when I'm making a build - it doesnt include correct shader variants.
    It only includes 1st shader with all shader_features disabled.
    It was working in old versions of unity automatically. That the correct shader variants from PP were included in the build.
    How can I tell unity which shader variants to include (shaders along with keywords)?
    Or are there other things I can do to make keywords behave the same with shader_features in the build.
     
  2. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
  3. vladstorm

    vladstorm

    Joined:
    Oct 4, 2021
    Posts:
    9
    @burningmime thank you for the reply

    adding all my shaders into Always Included Shaders didn't work unfortunately.
    Unity starts to treat shader_feature as multi_compile and ends up adding all the shader variants, which are 40K in total in my case.

    I'll check out IPreprocessShaders.OnProcessShader . Hopefully I can pull out all the keywords from the serialized PP Volume component and use it for specifying which shaders along with which keywords to include in the build.
    It used to be done automatically by PP. Not sure if it was changed or has to be done differently now.
     
  4. vladstorm

    vladstorm

    Joined:
    Oct 4, 2021
    Posts:
    9
    So I wrote my own
    IPreprocessShaders

    And I realised that
    OnProcessShader()
    doesn't receive any keywords from my shader. Altho the shader itself is included.

    Code (CSharp):
    1. Debug.Log("OnProcessShader shader:" + shader.name + " data count: " + data.Count);
    2. for (int i = 0; i < data.Count; ++i) {
    3.    ShaderKeyword[] sk = data[i].shaderKeywordSet.GetShaderKeywords();
    4.    Debug.Log("data ["+i+"] shaderKeywordSet count " + sk.Length);
    5. }
    6.  
    7. //output
    8. //data count: 1
    9. //shaderKeywordSet count: 0
    My shader is a custom Post-Processing Shader for Built-in Render Pipeline, I'm using Unity 2022.2. And I'm using
    shader_features


    Code (CSharp):
    1. Shader "Hidden/Custom_Shader"{
    2. HLSLINCLUDE
    3.    #include "Packages/com.unity.postprocessing/PostProcessing/Shaders/StdLib.hlsl"
    4.    #pragma shader_feature _PALETTE
    5. ...
    6. }

    Why
    OnProcessShader
    doesn't receive
    shader_feature 
    keywords???
    Maybe they are stripped somewhere earlier?
     
    Last edited: Jan 2, 2023
  5. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,023
    Hi!
    shader_feature
    is intended to be used with materials. This means that all keyword combinations for these directives come from material usage only. If there are no materials, you only get one (default) variant.
    multi_compile
    is intended for manually switching variants. By default it includes all variants; these can be filtered using the OnProcessShader callback.
     
  6. vladstorm

    vladstorm

    Joined:
    Oct 4, 2021
    Posts:
    9
    @aleksandrk
    I'm using
    shader_feature
    with materials indeed. I create Material based on my Shader in my post-processing vfx script in runtime.

    >you only get one (default) variant.
    how this default variant is defined?

    I'm fine with using 1 variant of the shader in the build with correct keywords. The problem is that the variant is chosen with the wrong keywords. Is there a way to tell unity which keywords to use to choose this default variant?
     
  7. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,023
    That's the issue - variants from
    shader_feature
    are based on the materials present in the build itself, not something that you create at runtime.
     
  8. aleksandrk

    aleksandrk

    Unity Technologies

    Joined:
    Jul 3, 2017
    Posts:
    3,023
    If you only need one variant, you can manually create a material, set it up with correct keywords and make sure it's included in the build (i.e. referenced by at least one object in at least one scene).
     
  9. vladstorm

    vladstorm

    Joined:
    Oct 4, 2021
    Posts:
    9
    @aleksandrk thank you for the info. That worked. I ended up just creating materials and keeping them in
    Resources
    folder. Then I modified their keywords in a script, and apparently the correct shader variants were included in the build.
    Didn't even need to use
    IPreprocessShaders
    . Also didn't need to add those materials in the scene just FYI
     
    aleksandrk likes this.