Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice
  4. Dismiss Notice

Resolved Problem with getting custom pass shader in build.

Discussion in 'Scripting' started by szpinak9, Sep 4, 2020.

  1. szpinak9

    szpinak9

    Joined:
    Mar 22, 2020
    Posts:
    8
    Hello!
    I want to make selection system that indicates selection by outlining the object. I decided to use custom pass from this site https://docs.unity3d.com/Packages/c...s.high-definition@7.1/manual/Custom-Pass.html.
    There are two scripts at the bottom of this site which I'm using:

    1. Outline custom pass script

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering.HighDefinition;
    3. using UnityEngine.Rendering;
    4. using UnityEngine.Experimental.Rendering;
    5.  
    6. class Outline : CustomPass
    7. {
    8.     public LayerMask outlineLayer = 0;
    9.     [ColorUsage(false, true)]
    10.     public Color outlineColor = Color.black;
    11.     public float threshold = 1;
    12.  
    13.     // To make sure the shader will ends up in the build, we keep it's reference in the custom pass
    14.     [SerializeField]
    15.     Shader outlineShader;
    16.  
    17.     Material fullscreenOutline;
    18.     MaterialPropertyBlock outlineProperties;
    19.     ShaderTagId[] shaderTags;
    20.     RTHandle outlineBuffer;
    21.  
    22.     protected override void Setup(ScriptableRenderContext renderContext, CommandBuffer cmd)
    23.     {
    24.         //outlineShader = Shader.Find("Hidden/Outline"); // I know it's bad so i don't use it
    25.         //outlineShader = Resources.Load<Shader>("OutlineShader"); //Doesn't work either
    26.         //outlineShader = Resources.Load<Shader>("Hidden/Outline"); //Doesn't work either
    27.         fullscreenOutline = CoreUtils.CreateEngineMaterial(outlineShader);
    28.         outlineProperties = new MaterialPropertyBlock();
    29.  
    30.         // List all the materials that will be replaced in the frame
    31.         shaderTags = new ShaderTagId[3]
    32.        {
    33.             new ShaderTagId("Forward"),
    34.             new ShaderTagId("ForwardOnly"),
    35.             new ShaderTagId("SRPDefaultUnlit"),
    36.         };
    37.  
    38.         outlineBuffer = RTHandles.Alloc(
    39.             Vector2.one, TextureXR.slices, dimension: TextureXR.dimension,
    40.             colorFormat: GraphicsFormat.B10G11R11_UFloatPack32,
    41.             useDynamicScale: true, name: "Outline Buffer"
    42.         );
    43.     }
    44.  
    45.     void DrawOutlineMeshes(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera hdCamera, CullingResults cullingResult)
    46.     {
    47.         var result = new RendererListDesc(shaderTags, cullingResult, hdCamera.camera)
    48.         {
    49.             // We need the lighting render configuration to support rendering lit objects
    50.             rendererConfiguration = PerObjectData.LightProbe | PerObjectData.LightProbeProxyVolume | PerObjectData.Lightmaps,
    51.             renderQueueRange = RenderQueueRange.all,
    52.             sortingCriteria = SortingCriteria.BackToFront,
    53.             excludeObjectMotionVectors = false,
    54.             layerMask = outlineLayer,
    55.         };
    56.  
    57.         CoreUtils.SetRenderTarget(cmd, outlineBuffer, ClearFlag.Color);
    58.         HDUtils.DrawRendererList(renderContext, cmd, RendererList.Create(result));
    59.     }
    60.  
    61.     protected override void Execute(ScriptableRenderContext renderContext, CommandBuffer cmd, HDCamera camera, CullingResults cullingResult)
    62.     {
    63.         DrawOutlineMeshes(renderContext, cmd, camera, cullingResult);
    64.  
    65.         SetCameraRenderTarget(cmd);
    66.  
    67.         outlineProperties.SetColor("_OutlineColor", outlineColor);
    68.         outlineProperties.SetTexture("_OutlineBuffer", outlineBuffer);
    69.         outlineProperties.SetFloat("_Threshold", threshold);
    70.         CoreUtils.DrawFullScreen(cmd, fullscreenOutline, outlineProperties, shaderPassId: 0);
    71.     }
    72.  
    73.     protected override void Cleanup()
    74.     {
    75.         CoreUtils.Destroy(fullscreenOutline);
    76.         outlineBuffer.Release();
    77.     }
    78. }
    2. Outline Shader

    Code (CSharp):
    1. Shader "Hidden/Outline"
    2. {
    3.     HLSLINCLUDE
    4.  
    5. #pragma vertex Vert
    6.  
    7. #pragma target 4.5
    8. #pragma only_renderers d3d11 ps4 xboxone vulkan metal switch
    9.  
    10. #include "Packages/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/RenderPass/CustomPass/CustomPassCommon.hlsl"
    11.  
    12.         TEXTURE2D_X(_OutlineBuffer);
    13.     float4 _OutlineColor;
    14.     float _Threshold;
    15.  
    16. #define v2 1.41421
    17. #define c45 0.707107
    18. #define c225 0.9238795
    19. #define s225 0.3826834
    20.  
    21. #define MAXSAMPLES 8
    22.     // Neighbour pixel positions
    23.     static float2 samplingPositions[MAXSAMPLES] =
    24.     {
    25.         float2(1,  1),
    26.         float2(0,  1),
    27.         float2(-1,  1),
    28.         float2(-1,  0),
    29.         float2(-1, -1),
    30.         float2(0, -1),
    31.         float2(1, -1),
    32.         float2(1, 0),
    33.     };
    34.  
    35.     float4 FullScreenPass(Varyings varyings) : SV_Target
    36.     {
    37.         UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(varyings);
    38.  
    39.         float depth = LoadCameraDepth(varyings.positionCS.xy);
    40.         PositionInputs posInput = GetPositionInput(varyings.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
    41.         float4 color = float4(0.0, 0.0, 0.0, 0.0);
    42.         float luminanceThreshold = max(0.000001, _Threshold * 0.01);
    43.  
    44.         // Load the camera color buffer at the mip 0 if we're not at the before rendering injection point
    45.         if (_CustomPassInjectionPoint != CUSTOMPASSINJECTIONPOINT_BEFORE_RENDERING)
    46.             color = float4(CustomPassSampleCameraColor(posInput.positionNDC.xy, 0), 1);
    47.  
    48.         // When sampling RTHandle texture, always use _RTHandleScale.xy to scale your UVs first.
    49.         float2 uv = posInput.positionNDC.xy * _RTHandleScale.xy;
    50.         float4 outline = SAMPLE_TEXTURE2D_X_LOD(_OutlineBuffer, s_linear_clamp_sampler, uv, 0);
    51.         outline.a = 0;
    52.  
    53.         if (Luminance(outline.rgb) < luminanceThreshold)
    54.         {
    55.             float3 o = float3(_ScreenSize.zw, 0);
    56.  
    57.             for (int i = 0; i < MAXSAMPLES; i++)
    58.             {
    59.                 float2 uvN = uv + _ScreenSize.zw * samplingPositions[i];
    60.                 float4 neighbour = SAMPLE_TEXTURE2D_X_LOD(_OutlineBuffer, s_linear_clamp_sampler, uvN, 0);
    61.  
    62.                 if (Luminance(neighbour) > luminanceThreshold)
    63.                 {
    64.                     outline.rgb = _OutlineColor.rgb;
    65.                     outline.a = 1;
    66.                     break;
    67.                 }
    68.             }
    69.         }
    70.  
    71.         return outline;
    72.     }
    73.  
    74.         ENDHLSL
    75.  
    76.         SubShader
    77.     {
    78.         Pass
    79.         {
    80.             Name "Custom Pass 0"
    81.  
    82.             ZWrite Off
    83.             ZTest Always
    84.             Blend SrcAlpha OneMinusSrcAlpha
    85.             Cull Off
    86.  
    87.             HLSLPROGRAM
    88.                 #pragma fragment FullScreenPass
    89.             ENDHLSL
    90.         }
    91.     }
    92.     Fallback Off
    93. }
    The problem is that the outline shader doesn't work in the final build of the game. I erased shader.find from the code, I serialized shader field and even made it public for test. I also put my shader in the resource folder and in always included shaders. It works in developement build, but when I'm making normal build it doesn't work.
    1.jpg
    2.jpg
     
    Last edited: Sep 4, 2020
  2. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    You should see your assigned outline shader in your scene in your custom pass outline script here:
    Code (CSharp):
    1.   // To make sure the shader will ends up in the build, we keep it's reference in the custom pass
    2.     [SerializeField]
    3.     Shader outlineShader;
    And you shouldnt place this shader in the Resources folder, simply put it into your assets in a folder named shader or something like that. All assets in the resouces folder must be loaded by hand and will not automatically loaded by Unity.
     
    Last edited: Sep 4, 2020
  3. szpinak9

    szpinak9

    Joined:
    Mar 22, 2020
    Posts:
    8
    I know it is assigned properly. I put it in resource folder just for testing purposes. It doesn't work with shader placed in asset folder. And only in normal build.

    3.jpg
     
    Last edited: Sep 4, 2020
  4. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    Try to check if the shader is loaded by call Shader.Find via script:
    https://docs.unity3d.com/ScriptReference/Shader.Find.html

    or if the shader is loaded but not work in the expected way (some platforms dont support this shader if you try to run your build onto a different plattform).

    Also you could try to create a material with this shader and reference it in your scene (but not a nice solution).
     
    Last edited: Sep 4, 2020
  5. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    Place this script into your scene. Create a build and then look into the logs of your build:
    https://docs.unity3d.com/Manual/LogFiles.html

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. public class CheckShaderIsLoaded: MonoBehaviour
    4. {
    5.     void Start()
    6.     {
    7.         // Try to find the shader
    8.         Shader myShader = Shader.Find("Hidden/Outline");
    9.         if (myShader==null) {Debug.Log("Shader -Hidden/Outline- isnt loaded!");}
    10.         else {Debug.Log("Shader -Hidden/Outline- is loaded!");}
    11.     }
    12. }
     
    Last edited: Sep 4, 2020
  6. szpinak9

    szpinak9

    Joined:
    Mar 22, 2020
    Posts:
    8
    Thank you for your answer, but I don't know how to get logs from standalone non-developement build
     
  7. szpinak9

    szpinak9

    Joined:
    Mar 22, 2020
    Posts:
    8
    Ok I passed if this shader is loaded into UI because i didnt know how you use debug.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.UI;
    3. public class CheckShaderIsLoaded : MonoBehaviour
    4. {
    5.     public Text tekstTestowy;
    6.  
    7.     void Start()
    8.     {
    9.         // Try to find the shader
    10.         Shader myShader = Shader.Find("Hidden/Outline");
    11.         if (myShader == null)
    12.         {
    13.             tekstTestowy.text = "Not loaded";
    14.         }
    15.         else
    16.         {
    17.             tekstTestowy.text = "Loaded";
    18.         }
    19.     }
    20. }
    3.jpg
    Screenshot is taken from build of the game. This box is supposed to be outlined.
     
  8. Zer0Cool

    Zer0Cool

    Joined:
    Oct 24, 2014
    Posts:
    203
    So the shader is loaded but not work in the expected way and or we have another problem with the hdrp pipeline in the build. Do you run the build on the same pc / environment as the unity editor, because the shader isnt working on all gpu's or directx derivates?

    Additionally i would check if the setup of the hdrp project is correct, some hints can be found here:
    https://blogs.unity3d.com/2020/01/0...-render-pipeline-for-high-end-visualizations/
     
    Last edited: Sep 4, 2020
  9. szpinak9

    szpinak9

    Joined:
    Mar 22, 2020
    Posts:
    8
    Ok I got it working by changing color buffer mode to R16G16B16A16 and lit shader mode to "both". It increases build times but i think i can manage that.

    1.jpg

    And it's working in normal build now !
    2.png

    Thank you very much for your help and for this very helpful article.
    Greetings
     
    sabint likes this.
  10. sabint

    sabint

    Joined:
    Apr 19, 2014
    Posts:
    26
    @szpinak9 thanks a lot! I was also struggling to get custom passes in the build (worked perfectly in editor). Switching shader mode to "both" fixed it for me as well.