Search Unity

Apply effect to objects on specific layer using stencil [SOLVED]

Discussion in 'Universal Render Pipeline' started by keenanwoodall, Mar 5, 2020.

  1. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    [edit] Here's the solution

    I'm working on some visuals that need to be drawn on top of everything, but would like it to look different where it should be occluded. An example would be to invert the colors when behind something. So it's not occluded - just drawn differently. (all with URP)

    To start, I'm not even worrying about drawing the occluded parts differently and just want to see if I can apply an effect to a specific layer using the stencil buffer. I removed the specific layer from the forward renderer's default layer mask and had it drawn always on top via a RenderObjects feature. This, of course, is how I think it should work out. I'm just basing this logic on intuition as renderer features and stencil shaders are new to me.

    upload_2020-3-5_11-7-7.png

    2020-03-05_11-04-53.gif
    The text/sprites are on the Silhouette layer, and they are get drawn on top correctly thanks to the Render Objects feature.

    To try and make use of the stencil value, I made a custom blit render feature using this tutorial. From what I understand, it just blits the camera's color texture to a temp texture using a material and then blits it back (without a material) to the original color texture. I added this new feature to the renderer, after the Render Objects feature.

    If you want the blit code, here it is.
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.Universal;
    4.  
    5. public class BlitFeature : ScriptableRendererFeature
    6. {
    7.     class BlitPass : ScriptableRenderPass
    8.     {
    9.       // used to label this pass in Unity's Frame Debug utility
    10.       string profilerTag;
    11.  
    12.       Material material;
    13.       RenderTargetIdentifier cameraColorTarget;
    14.       RenderTargetHandle tempTexture;
    15.  
    16.       public BlitPass(string profilerTag, RenderPassEvent renderPassEvent, Material material)
    17.       {
    18.         this.profilerTag = profilerTag;
    19.         this.renderPassEvent = renderPassEvent;
    20.         this.material = material;
    21.       }
    22.  
    23.       // This isn't part of the ScriptableRenderPass class and is our own addition.
    24.       // For this custom pass we need the camera's color target, so that gets passed in.
    25.       public void Setup(RenderTargetIdentifier cameraColorTarget)
    26.       {
    27.         this.cameraColorTarget = cameraColorTarget;
    28.       }
    29.  
    30.       // called each frame before Execute, use it to set up things the pass will need
    31.       public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
    32.       {
    33.         // create a temporary render texture that matches the camera
    34.         cmd.GetTemporaryRT(tempTexture.id, cameraTextureDescriptor);
    35.       }
    36.  
    37.       // Execute is called for every eligible camera every frame. It's not called at the moment that
    38.       // rendering is actually taking place, so don't directly execute rendering commands here.
    39.       // Instead use the methods on ScriptableRenderContext to set up instructions.
    40.       // RenderingData provides a bunch of (not very well documented) information about the scene
    41.       // and what's being rendered.
    42.       public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    43.       {
    44.         // fetch a command buffer to use
    45.         CommandBuffer cmd = CommandBufferPool.Get(profilerTag);
    46.         cmd.Clear();
    47.  
    48.         // the actual content of our custom render pass!
    49.         // we apply our material while blitting to a temporary texture
    50.         cmd.Blit(cameraColorTarget, tempTexture.Identifier(), material, 0);
    51.  
    52.         // ...then blit it back again
    53.         cmd.Blit(tempTexture.Identifier(), cameraColorTarget);
    54.  
    55.         // don't forget to tell ScriptableRenderContext to actually execute the commands
    56.         context.ExecuteCommandBuffer(cmd);
    57.  
    58.         // tidy up after ourselves
    59.         cmd.Clear();
    60.         CommandBufferPool.Release(cmd);
    61.       }
    62.  
    63.       // called after Execute, use it to clean up anything allocated in Configure
    64.       public override void FrameCleanup(CommandBuffer cmd)
    65.       {
    66.         cmd.ReleaseTemporaryRT(tempTexture.id);
    67.       }
    68.     }
    69.  
    70.     [System.Serializable]
    71.     public class Settings
    72.     {
    73.         // we're free to put whatever we want here, public fields will be exposed in the inspector
    74.         public bool Enabled = true;
    75.         public RenderPassEvent Event = RenderPassEvent.AfterRendering;
    76.         public Material Material;
    77.     }
    78.  
    79.     // MUST be named "settings" (lowercase) to be shown in the Render Features inspector
    80.     public Settings settings = new Settings();
    81.  
    82.     private RenderTargetHandle rtHandle;
    83.     private BlitPass pass;
    84.  
    85.     public override void Create()
    86.     {
    87.         pass = new BlitPass
    88.         (
    89.             "Blit Pass",
    90.             settings.Event,
    91.             settings.Material
    92.         );
    93.     }
    94.  
    95.     // called every frame once per camera
    96.     public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    97.     {
    98.         if (!settings.Enabled)
    99.         {
    100.             // we can do nothing this frame if we want
    101.             return;
    102.         }
    103.  
    104.         // Gather up and pass any extra information our pass will need.
    105.         // In this case we're getting the camera's color buffer target
    106.         var cameraColorTarget = renderer.cameraColorTarget;
    107.         pass.Setup(cameraColorTarget);
    108.  
    109.         // Ask the renderer to add our pass.
    110.         // Could queue up multiple passes and/or pick passes to use
    111.         renderer.EnqueuePass(pass);
    112.     }
    113. }

    My thinking was that objects on the "Silhouette" layer will get rendered normally with the Render Objects feature while also writing to the stencil buffer and then I could use the blit feature with a shader that only applies its effect where the stencil has the right value (which should only be where the Silhouette objects are, thanks to the render objects feature)

    To test the blit, I made a super simple shader in shader graph that inverts the colors.
    upload_2020-3-5_11-1-38.png

    I made a material with the shader and added it to the blit feature and it worked!
    2020-03-05_11-11-07.gif

    Then, because I don't know how to write text shaders, I copied the generated code from the invert shader into a new shader text file and added this snippet near the top

    Code (CSharp):
    1. Stencil {
    2.   Ref 1
    3.   Comp Equal
    4. }
    I've not used stencils before, but from what I could tell this should make the shader discard fragments where the stencil value is not 1.

    Here's the full shader if you like, although like I said, it's just the generated shader graph code + the stencil snippet
    Code (CSharp):
    1. Shader "Unlit/StencilBlit"
    2. {
    3.     Properties
    4.     {
    5.         [NoScaleOffset]_MainTex("Texture2D", 2D) = "white" {}
    6.     }
    7.     SubShader
    8.     {
    9.         Tags
    10.         {
    11.             "RenderPipeline"="UniversalPipeline"
    12.             "RenderType"="Opaque"
    13.             "Queue"="Geometry"
    14.         }
    15.      
    16.         Stencil {
    17.             Ref 1
    18.             Comp Equal
    19.         }
    20.      
    21.         Pass
    22.         {
    23.             Name "Pass"
    24.             Tags
    25.             {
    26.                 // LightMode: <None>
    27.             }
    28.        
    29.             // Render State
    30.             Blend One Zero, One Zero
    31.             Cull Back
    32.             ZTest LEqual
    33.             ZWrite On
    34.             // ColorMask: <None>
    35.          
    36.      
    37.             HLSLPROGRAM
    38.             #pragma vertex vert
    39.             #pragma fragment frag
    40.      
    41.             // Debug
    42.             // <None>
    43.      
    44.             // --------------------------------------------------
    45.             // Pass
    46.      
    47.             // Pragmas
    48.             #pragma prefer_hlslcc gles
    49.             #pragma exclude_renderers d3d11_9x
    50.             #pragma target 2.0
    51.             #pragma multi_compile_instancing
    52.      
    53.             // Keywords
    54.             #pragma multi_compile _ LIGHTMAP_ON
    55.             #pragma multi_compile _ DIRLIGHTMAP_COMBINED
    56.             #pragma shader_feature _ _SAMPLE_GI
    57.             // GraphKeywords: <None>
    58.          
    59.             // Defines
    60.             #define _AlphaClip 1
    61.             #define ATTRIBUTES_NEED_NORMAL
    62.             #define ATTRIBUTES_NEED_TANGENT
    63.             #define ATTRIBUTES_NEED_TEXCOORD0
    64.             #define VARYINGS_NEED_TEXCOORD0
    65.             #define SHADERPASS_UNLIT
    66.      
    67.             // Includes
    68.             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
    69.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    70.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
    71.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
    72.      
    73.             // --------------------------------------------------
    74.             // Graph
    75.      
    76.             // Graph Properties
    77.             CBUFFER_START(UnityPerMaterial)
    78.             CBUFFER_END
    79.             TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _MainTex_TexelSize;
    80.             SAMPLER(_SampleTexture2D_8906C27D_Sampler_3_Linear_Repeat);
    81.      
    82.             // Graph Functions
    83.          
    84.             void Unity_InvertColors_float4(float4 In, float4 InvertColors, out float4 Out)
    85.             {
    86.                 Out = abs(InvertColors - In);
    87.             }
    88.      
    89.             // Graph Vertex
    90.             // GraphVertex: <None>
    91.          
    92.             // Graph Pixel
    93.             struct SurfaceDescriptionInputs
    94.             {
    95.                 float4 uv0;
    96.             };
    97.          
    98.             struct SurfaceDescription
    99.             {
    100.                 float3 Color;
    101.                 float Alpha;
    102.                 float AlphaClipThreshold;
    103.             };
    104.          
    105.             SurfaceDescription SurfaceDescriptionFunction(SurfaceDescriptionInputs IN)
    106.             {
    107.                 SurfaceDescription surface = (SurfaceDescription)0;
    108.                 float4 _SampleTexture2D_8906C27D_RGBA_0 = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv0.xy);
    109.                 float _SampleTexture2D_8906C27D_R_4 = _SampleTexture2D_8906C27D_RGBA_0.r;
    110.                 float _SampleTexture2D_8906C27D_G_5 = _SampleTexture2D_8906C27D_RGBA_0.g;
    111.                 float _SampleTexture2D_8906C27D_B_6 = _SampleTexture2D_8906C27D_RGBA_0.b;
    112.                 float _SampleTexture2D_8906C27D_A_7 = _SampleTexture2D_8906C27D_RGBA_0.a;
    113.                 float4 _InvertColors_75584340_Out_1;
    114.                 float4 _InvertColors_75584340_InvertColors = float4 (1
    115.             , 1, 1, 0);    Unity_InvertColors_float4(_SampleTexture2D_8906C27D_RGBA_0, _InvertColors_75584340_InvertColors, _InvertColors_75584340_Out_1);
    116.                 surface.Color = (_InvertColors_75584340_Out_1.xyz);
    117.                 surface.Alpha = 1;
    118.                 surface.AlphaClipThreshold = 0.5;
    119.                 return surface;
    120.             }
    121.      
    122.             // --------------------------------------------------
    123.             // Structs and Packing
    124.      
    125.             // Generated Type: Attributes
    126.             struct Attributes
    127.             {
    128.                 float3 positionOS : POSITION;
    129.                 float3 normalOS : NORMAL;
    130.                 float4 tangentOS : TANGENT;
    131.                 float4 uv0 : TEXCOORD0;
    132.                 #if UNITY_ANY_INSTANCING_ENABLED
    133.                 uint instanceID : INSTANCEID_SEMANTIC;
    134.                 #endif
    135.             };
    136.      
    137.             // Generated Type: Varyings
    138.             struct Varyings
    139.             {
    140.                 float4 positionCS : SV_Position;
    141.                 float4 texCoord0;
    142.                 #if UNITY_ANY_INSTANCING_ENABLED
    143.                 uint instanceID : CUSTOM_INSTANCE_ID;
    144.                 #endif
    145.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    146.                 FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;
    147.                 #endif
    148.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    149.                 uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;
    150.                 #endif
    151.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    152.                 uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;
    153.                 #endif
    154.             };
    155.          
    156.             // Generated Type: PackedVaryings
    157.             struct PackedVaryings
    158.             {
    159.                 float4 positionCS : SV_Position;
    160.                 #if UNITY_ANY_INSTANCING_ENABLED
    161.                 uint instanceID : CUSTOM_INSTANCE_ID;
    162.                 #endif
    163.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    164.                 uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;
    165.                 #endif
    166.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    167.                 uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;
    168.                 #endif
    169.                 float4 interp00 : TEXCOORD0;
    170.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    171.                 FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;
    172.                 #endif
    173.             };
    174.          
    175.             // Packed Type: Varyings
    176.             PackedVaryings PackVaryings(Varyings input)
    177.             {
    178.                 PackedVaryings output;
    179.                 output.positionCS = input.positionCS;
    180.                 output.interp00.xyzw = input.texCoord0;
    181.                 #if UNITY_ANY_INSTANCING_ENABLED
    182.                 output.instanceID = input.instanceID;
    183.                 #endif
    184.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    185.                 output.cullFace = input.cullFace;
    186.                 #endif
    187.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    188.                 output.stereoTargetEyeIndexAsRTArrayIdx = input.stereoTargetEyeIndexAsRTArrayIdx;
    189.                 #endif
    190.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    191.                 output.stereoTargetEyeIndexAsBlendIdx0 = input.stereoTargetEyeIndexAsBlendIdx0;
    192.                 #endif
    193.                 return output;
    194.             }
    195.          
    196.             // Unpacked Type: Varyings
    197.             Varyings UnpackVaryings(PackedVaryings input)
    198.             {
    199.                 Varyings output;
    200.                 output.positionCS = input.positionCS;
    201.                 output.texCoord0 = input.interp00.xyzw;
    202.                 #if UNITY_ANY_INSTANCING_ENABLED
    203.                 output.instanceID = input.instanceID;
    204.                 #endif
    205.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    206.                 output.cullFace = input.cullFace;
    207.                 #endif
    208.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    209.                 output.stereoTargetEyeIndexAsRTArrayIdx = input.stereoTargetEyeIndexAsRTArrayIdx;
    210.                 #endif
    211.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    212.                 output.stereoTargetEyeIndexAsBlendIdx0 = input.stereoTargetEyeIndexAsBlendIdx0;
    213.                 #endif
    214.                 return output;
    215.             }
    216.      
    217.             // --------------------------------------------------
    218.             // Build Graph Inputs
    219.      
    220.             SurfaceDescriptionInputs BuildSurfaceDescriptionInputs(Varyings input)
    221.             {
    222.                 SurfaceDescriptionInputs output;
    223.                 ZERO_INITIALIZE(SurfaceDescriptionInputs, output);
    224.          
    225.                 output.uv0 =                         input.texCoord0;
    226.             #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    227.             #define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN output.FaceSign =                    IS_FRONT_VFACE(input.cullFace, true, false);
    228.             #else
    229.             #define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
    230.             #endif
    231.             #undef BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
    232.          
    233.                 return output;
    234.             }
    235.          
    236.      
    237.             // --------------------------------------------------
    238.             // Main
    239.      
    240.             #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl"
    241.             #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/UnlitPass.hlsl"
    242.      
    243.             ENDHLSL
    244.         }
    245.      
    246.         Pass
    247.         {
    248.             Name "ShadowCaster"
    249.             Tags
    250.             {
    251.                 "LightMode" = "ShadowCaster"
    252.             }
    253.        
    254.             // Render State
    255.             Blend One Zero, One Zero
    256.             Cull Back
    257.             ZTest LEqual
    258.             ZWrite On
    259.             // ColorMask: <None>
    260.          
    261.      
    262.             HLSLPROGRAM
    263.             #pragma vertex vert
    264.             #pragma fragment frag
    265.      
    266.             // Debug
    267.             // <None>
    268.      
    269.             // --------------------------------------------------
    270.             // Pass
    271.      
    272.             // Pragmas
    273.             #pragma prefer_hlslcc gles
    274.             #pragma exclude_renderers d3d11_9x
    275.             #pragma target 2.0
    276.             #pragma multi_compile_instancing
    277.      
    278.             // Keywords
    279.             #pragma shader_feature _ _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
    280.             // GraphKeywords: <None>
    281.          
    282.             // Defines
    283.             #define _AlphaClip 1
    284.             #define ATTRIBUTES_NEED_NORMAL
    285.             #define ATTRIBUTES_NEED_TANGENT
    286.             #define SHADERPASS_SHADOWCASTER
    287.      
    288.             // Includes
    289.             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
    290.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    291.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
    292.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
    293.      
    294.             // --------------------------------------------------
    295.             // Graph
    296.      
    297.             // Graph Properties
    298.             CBUFFER_START(UnityPerMaterial)
    299.             CBUFFER_END
    300.             TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _MainTex_TexelSize;
    301.      
    302.             // Graph Functions
    303.             // GraphFunctions: <None>
    304.      
    305.             // Graph Vertex
    306.             // GraphVertex: <None>
    307.          
    308.             // Graph Pixel
    309.             struct SurfaceDescriptionInputs
    310.             {
    311.             };
    312.          
    313.             struct SurfaceDescription
    314.             {
    315.                 float Alpha;
    316.                 float AlphaClipThreshold;
    317.             };
    318.          
    319.             SurfaceDescription SurfaceDescriptionFunction(SurfaceDescriptionInputs IN)
    320.             {
    321.                 SurfaceDescription surface = (SurfaceDescription)0;
    322.                 surface.Alpha = 1;
    323.                 surface.AlphaClipThreshold = 0.5;
    324.                 return surface;
    325.             }
    326.      
    327.             // --------------------------------------------------
    328.             // Structs and Packing
    329.      
    330.             // Generated Type: Attributes
    331.             struct Attributes
    332.             {
    333.                 float3 positionOS : POSITION;
    334.                 float3 normalOS : NORMAL;
    335.                 float4 tangentOS : TANGENT;
    336.                 #if UNITY_ANY_INSTANCING_ENABLED
    337.                 uint instanceID : INSTANCEID_SEMANTIC;
    338.                 #endif
    339.             };
    340.      
    341.             // Generated Type: Varyings
    342.             struct Varyings
    343.             {
    344.                 float4 positionCS : SV_Position;
    345.                 #if UNITY_ANY_INSTANCING_ENABLED
    346.                 uint instanceID : CUSTOM_INSTANCE_ID;
    347.                 #endif
    348.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    349.                 FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;
    350.                 #endif
    351.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    352.                 uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;
    353.                 #endif
    354.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    355.                 uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;
    356.                 #endif
    357.             };
    358.          
    359.             // Generated Type: PackedVaryings
    360.             struct PackedVaryings
    361.             {
    362.                 float4 positionCS : SV_Position;
    363.                 #if UNITY_ANY_INSTANCING_ENABLED
    364.                 uint instanceID : CUSTOM_INSTANCE_ID;
    365.                 #endif
    366.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    367.                 uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;
    368.                 #endif
    369.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    370.                 uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;
    371.                 #endif
    372.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    373.                 FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;
    374.                 #endif
    375.             };
    376.          
    377.             // Packed Type: Varyings
    378.             PackedVaryings PackVaryings(Varyings input)
    379.             {
    380.                 PackedVaryings output;
    381.                 output.positionCS = input.positionCS;
    382.                 #if UNITY_ANY_INSTANCING_ENABLED
    383.                 output.instanceID = input.instanceID;
    384.                 #endif
    385.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    386.                 output.cullFace = input.cullFace;
    387.                 #endif
    388.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    389.                 output.stereoTargetEyeIndexAsRTArrayIdx = input.stereoTargetEyeIndexAsRTArrayIdx;
    390.                 #endif
    391.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    392.                 output.stereoTargetEyeIndexAsBlendIdx0 = input.stereoTargetEyeIndexAsBlendIdx0;
    393.                 #endif
    394.                 return output;
    395.             }
    396.          
    397.             // Unpacked Type: Varyings
    398.             Varyings UnpackVaryings(PackedVaryings input)
    399.             {
    400.                 Varyings output;
    401.                 output.positionCS = input.positionCS;
    402.                 #if UNITY_ANY_INSTANCING_ENABLED
    403.                 output.instanceID = input.instanceID;
    404.                 #endif
    405.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    406.                 output.cullFace = input.cullFace;
    407.                 #endif
    408.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    409.                 output.stereoTargetEyeIndexAsRTArrayIdx = input.stereoTargetEyeIndexAsRTArrayIdx;
    410.                 #endif
    411.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    412.                 output.stereoTargetEyeIndexAsBlendIdx0 = input.stereoTargetEyeIndexAsBlendIdx0;
    413.                 #endif
    414.                 return output;
    415.             }
    416.      
    417.             // --------------------------------------------------
    418.             // Build Graph Inputs
    419.      
    420.             SurfaceDescriptionInputs BuildSurfaceDescriptionInputs(Varyings input)
    421.             {
    422.                 SurfaceDescriptionInputs output;
    423.                 ZERO_INITIALIZE(SurfaceDescriptionInputs, output);
    424.          
    425.             #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    426.             #define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN output.FaceSign =                    IS_FRONT_VFACE(input.cullFace, true, false);
    427.             #else
    428.             #define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
    429.             #endif
    430.             #undef BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
    431.          
    432.                 return output;
    433.             }
    434.          
    435.      
    436.             // --------------------------------------------------
    437.             // Main
    438.      
    439.             #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl"
    440.             #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/ShadowCasterPass.hlsl"
    441.      
    442.             ENDHLSL
    443.         }
    444.      
    445.         Pass
    446.         {
    447.             Name "DepthOnly"
    448.             Tags
    449.             {
    450.                 "LightMode" = "DepthOnly"
    451.             }
    452.        
    453.             // Render State
    454.             Blend One Zero, One Zero
    455.             Cull Back
    456.             ZTest LEqual
    457.             ZWrite On
    458.             ColorMask 0
    459.          
    460.      
    461.             HLSLPROGRAM
    462.             #pragma vertex vert
    463.             #pragma fragment frag
    464.      
    465.             // Debug
    466.             // <None>
    467.      
    468.             // --------------------------------------------------
    469.             // Pass
    470.      
    471.             // Pragmas
    472.             #pragma prefer_hlslcc gles
    473.             #pragma exclude_renderers d3d11_9x
    474.             #pragma target 2.0
    475.             #pragma multi_compile_instancing
    476.      
    477.             // Keywords
    478.             // PassKeywords: <None>
    479.             // GraphKeywords: <None>
    480.          
    481.             // Defines
    482.             #define _AlphaClip 1
    483.             #define ATTRIBUTES_NEED_NORMAL
    484.             #define ATTRIBUTES_NEED_TANGENT
    485.             #define SHADERPASS_DEPTHONLY
    486.      
    487.             // Includes
    488.             #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Color.hlsl"
    489.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
    490.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
    491.             #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
    492.      
    493.             // --------------------------------------------------
    494.             // Graph
    495.      
    496.             // Graph Properties
    497.             CBUFFER_START(UnityPerMaterial)
    498.             CBUFFER_END
    499.             TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); float4 _MainTex_TexelSize;
    500.      
    501.             // Graph Functions
    502.             // GraphFunctions: <None>
    503.      
    504.             // Graph Vertex
    505.             // GraphVertex: <None>
    506.          
    507.             // Graph Pixel
    508.             struct SurfaceDescriptionInputs
    509.             {
    510.             };
    511.          
    512.             struct SurfaceDescription
    513.             {
    514.                 float Alpha;
    515.                 float AlphaClipThreshold;
    516.             };
    517.          
    518.             SurfaceDescription SurfaceDescriptionFunction(SurfaceDescriptionInputs IN)
    519.             {
    520.                 SurfaceDescription surface = (SurfaceDescription)0;
    521.                 surface.Alpha = 1;
    522.                 surface.AlphaClipThreshold = 0.5;
    523.                 return surface;
    524.             }
    525.      
    526.             // --------------------------------------------------
    527.             // Structs and Packing
    528.      
    529.             // Generated Type: Attributes
    530.             struct Attributes
    531.             {
    532.                 float3 positionOS : POSITION;
    533.                 float3 normalOS : NORMAL;
    534.                 float4 tangentOS : TANGENT;
    535.                 #if UNITY_ANY_INSTANCING_ENABLED
    536.                 uint instanceID : INSTANCEID_SEMANTIC;
    537.                 #endif
    538.             };
    539.      
    540.             // Generated Type: Varyings
    541.             struct Varyings
    542.             {
    543.                 float4 positionCS : SV_Position;
    544.                 #if UNITY_ANY_INSTANCING_ENABLED
    545.                 uint instanceID : CUSTOM_INSTANCE_ID;
    546.                 #endif
    547.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    548.                 FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;
    549.                 #endif
    550.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    551.                 uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;
    552.                 #endif
    553.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    554.                 uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;
    555.                 #endif
    556.             };
    557.          
    558.             // Generated Type: PackedVaryings
    559.             struct PackedVaryings
    560.             {
    561.                 float4 positionCS : SV_Position;
    562.                 #if UNITY_ANY_INSTANCING_ENABLED
    563.                 uint instanceID : CUSTOM_INSTANCE_ID;
    564.                 #endif
    565.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    566.                 uint stereoTargetEyeIndexAsRTArrayIdx : SV_RenderTargetArrayIndex;
    567.                 #endif
    568.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    569.                 uint stereoTargetEyeIndexAsBlendIdx0 : BLENDINDICES0;
    570.                 #endif
    571.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    572.                 FRONT_FACE_TYPE cullFace : FRONT_FACE_SEMANTIC;
    573.                 #endif
    574.             };
    575.          
    576.             // Packed Type: Varyings
    577.             PackedVaryings PackVaryings(Varyings input)
    578.             {
    579.                 PackedVaryings output;
    580.                 output.positionCS = input.positionCS;
    581.                 #if UNITY_ANY_INSTANCING_ENABLED
    582.                 output.instanceID = input.instanceID;
    583.                 #endif
    584.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    585.                 output.cullFace = input.cullFace;
    586.                 #endif
    587.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    588.                 output.stereoTargetEyeIndexAsRTArrayIdx = input.stereoTargetEyeIndexAsRTArrayIdx;
    589.                 #endif
    590.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    591.                 output.stereoTargetEyeIndexAsBlendIdx0 = input.stereoTargetEyeIndexAsBlendIdx0;
    592.                 #endif
    593.                 return output;
    594.             }
    595.          
    596.             // Unpacked Type: Varyings
    597.             Varyings UnpackVaryings(PackedVaryings input)
    598.             {
    599.                 Varyings output;
    600.                 output.positionCS = input.positionCS;
    601.                 #if UNITY_ANY_INSTANCING_ENABLED
    602.                 output.instanceID = input.instanceID;
    603.                 #endif
    604.                 #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    605.                 output.cullFace = input.cullFace;
    606.                 #endif
    607.                 #if (defined(UNITY_STEREO_INSTANCING_ENABLED))
    608.                 output.stereoTargetEyeIndexAsRTArrayIdx = input.stereoTargetEyeIndexAsRTArrayIdx;
    609.                 #endif
    610.                 #if (defined(UNITY_STEREO_MULTIVIEW_ENABLED)) || (defined(UNITY_STEREO_INSTANCING_ENABLED) && (defined(SHADER_API_GLES3) || defined(SHADER_API_GLCORE)))
    611.                 output.stereoTargetEyeIndexAsBlendIdx0 = input.stereoTargetEyeIndexAsBlendIdx0;
    612.                 #endif
    613.                 return output;
    614.             }
    615.      
    616.             // --------------------------------------------------
    617.             // Build Graph Inputs
    618.      
    619.             SurfaceDescriptionInputs BuildSurfaceDescriptionInputs(Varyings input)
    620.             {
    621.                 SurfaceDescriptionInputs output;
    622.                 ZERO_INITIALIZE(SurfaceDescriptionInputs, output);
    623.          
    624.             #if defined(SHADER_STAGE_FRAGMENT) && defined(VARYINGS_NEED_CULLFACE)
    625.             #define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN output.FaceSign =                    IS_FRONT_VFACE(input.cullFace, true, false);
    626.             #else
    627.             #define BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
    628.             #endif
    629.             #undef BUILD_SURFACE_DESCRIPTION_INPUTS_OUTPUT_FACESIGN
    630.          
    631.                 return output;
    632.             }
    633.          
    634.      
    635.             // --------------------------------------------------
    636.             // Main
    637.      
    638.             #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/Varyings.hlsl"
    639.             #include "Packages/com.unity.render-pipelines.universal/Editor/ShaderGraph/Includes/DepthOnlyPass.hlsl"
    640.      
    641.             ENDHLSL
    642.         }
    643.      
    644.     }
    645.     FallBack "Hidden/Shader Graph/FallbackError"
    646. }
    647.  

    I changed the blit materials shader to use the new one with the stencil. Unfortunately this made the entire screen black. I tried changing the Ref value in the shader to different values. The screen gets the color inverted when the shaders ref is 0, but any other value results in a black scene. This makes me think that the stencils value is 0 on every fragment. Is there anything I can do to get it to work?

    Thanks for reading this long-winded post!
     

    Attached Files:

    Last edited: Mar 6, 2020
    PoweredByUnity likes this.
  2. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    So I've confirmed that the RenderObjects feature is correctly writing to the stencil buffer. I made a cube in the scene, put it on a special layer, added a new RenderObjects feature to the renderer that draws the new layer after the other render objects feature writes to the stencil buffer. I put the color invert material on the cube and it was correctly masked.
    2020-03-05_12-17-21.gif
    So this means the stencil is correct, but the blit function is not using it. I found a collection of forum posts (1, 2, 3) where @AaronBrownLM sunk a ton of time into trying to get it to work. It seems he found a hacky way to get it to work, but I can't figure out how to translate his findings into a blit that works within the context of a render feature. Also the posts are from 2016. I'm guessing the API has changed, hopefully for the better (ie cleanly supporting blitting with stencils)
     
    PoweredByUnity likes this.
  3. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    It's been a long day and @cyan has put in a ton of time writing code and troubleshooting to try and solve this. It has been confirmed that depth/stencils cannot be used when blitting a color texture. That being said, Cyan made a WIP workaround by manually rendering a fullscreen mesh with the blit material.

    Here's the gist of it
    Code (CSharp):
    1. cmd.Blit(colorSource, tempColor.Identifier());
    2. cmd.SetGlobalTexture(Shader.PropertyToID("_MainTex"), tempColor.Identifier());
    3.  
    4. cmd.SetRenderTarget(colorSource, depthSource);
    5. cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
    6. cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, material);
    7. Camera camera = renderingData.cameraData.camera;
    8. cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
    9. context.ExecuteCommandBuffer(cmd);
    but if you want the entire blit feature/pass here it is
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.Universal;
    4. public class BlitFeature : ScriptableRendererFeature
    5. {
    6.     class BlitPass : ScriptableRenderPass
    7.     {
    8.       // used to label this pass in Unity's Frame Debug utility
    9.       string profilerTag;
    10.       Material material;
    11.       RenderTargetIdentifier colorSource;
    12.       RenderTargetIdentifier depthSource;
    13.       RenderTargetHandle tempColor;
    14.       public BlitPass(string profilerTag, RenderPassEvent renderPassEvent, Material material)
    15.       {
    16.         this.profilerTag = profilerTag;
    17.         this.renderPassEvent = renderPassEvent;
    18.         this.material = material;
    19.       }
    20.       // This isn't part of the ScriptableRenderPass class and is our own addition.
    21.       // For this custom pass we need the camera's color target, so that gets passed in.
    22.       public void Setup(RenderTargetIdentifier colorSource, RenderTargetIdentifier depthSource)
    23.       {
    24.         this.colorSource = colorSource;
    25.         this.depthSource = depthSource;
    26.       }
    27.       // called each frame before Execute, use it to set up things the pass will need
    28.       public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
    29.       {
    30.           // create a temporary render texture that matches the camera
    31.           cmd.GetTemporaryRT(tempColor.id, cameraTextureDescriptor);
    32.       }
    33.       // Execute is called for every eligible camera every frame. It's not called at the moment that
    34.       // rendering is actually taking place, so don't directly execute rendering commands here.
    35.       // Instead use the methods on ScriptableRenderContext to set up instructions.
    36.       // RenderingData provides a bunch of (not very well documented) information about the scene
    37.       // and what's being rendered.
    38.       public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    39.       {
    40.         // fetch a command buffer to use
    41.         CommandBuffer cmd = CommandBufferPool.Get(profilerTag);
    42.         cmd.Clear();
    43.  
    44.         cmd.Blit(colorSource, tempColor.Identifier());
    45.         cmd.SetGlobalTexture(Shader.PropertyToID("_MainTex"), tempColor.Identifier());
    46.  
    47.         cmd.SetRenderTarget(colorSource, depthSource);
    48.         cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
    49.         cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, material);
    50.         Camera camera = renderingData.cameraData.camera;
    51.         cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
    52.         context.ExecuteCommandBuffer(cmd);
    53.      
    54.         CommandBufferPool.Release(cmd);
    55.       }
    56.       // called after Execute, use it to clean up anything allocated in Configure
    57.       public override void FrameCleanup(CommandBuffer cmd)
    58.       {
    59.         cmd.ReleaseTemporaryRT(tempColor.id);
    60.       }
    61.     }
    62.  
    63.     [System.Serializable]
    64.     public class Settings
    65.     {
    66.         // we're free to put whatever we want here, public fields will be exposed in the inspector
    67.         public bool Enabled = true;
    68.         public RenderPassEvent Event = RenderPassEvent.AfterRendering;
    69.         public Material Material;
    70.     }
    71.     // MUST be named "settings" (lowercase) to be shown in the Render Features inspector
    72.     public Settings settings = new Settings();
    73.     private RenderTargetHandle rtHandle;
    74.     private BlitPass pass;
    75.     public override void Create()
    76.     {
    77.         pass = new BlitPass
    78.         (
    79.             "Blit Pass",
    80.             settings.Event,
    81.             settings.Material
    82.         );
    83.     }
    84.     // called every frame once per camera
    85.     public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    86.     {
    87.         if (!settings.Enabled)
    88.         {
    89.             // we can do nothing this frame if we want
    90.             return;
    91.         }
    92.  
    93.         // Gather up and pass any extra information our pass will need.
    94.         // In this case we're getting the camera's color buffer target
    95.         var cameraColorTarget = renderer.cameraColorTarget;
    96.         pass.Setup(cameraColorTarget, renderer.cameraDepth);
    97.         // Ask the renderer to add our pass.
    98.         // Could queue up multiple passes and/or pick passes to use
    99.         renderer.EnqueuePass(pass);
    100.     }
    101. }

    This is the shader I used for the "blit" to invert the colors where the stencil buffer had a value of 1. Keep in mind that there was a Render Objects render feature writing 1 to the stencil buffer before the blit feature got executed.
    Code (CSharp):
    1. Shader "Unlit/UnlitStencil"
    2. {
    3.     SubShader
    4.     {
    5.         Tags { "RenderType"="Opaque" }
    6.         LOD 100
    7.         Stencil {
    8.           Ref 1
    9.           Comp Equal
    10.         }
    11.         Pass
    12.         {
    13.             CGPROGRAM
    14.             #pragma vertex vert
    15.             #pragma fragment frag
    16.  
    17.             #include "UnityCG.cginc"
    18.  
    19.             struct appdata
    20.             {
    21.                 float4 vertex : POSITION;
    22.                 float2 uv : TEXCOORD0;
    23.             };
    24.  
    25.             struct v2f
    26.             {
    27.                 float2 uv : TEXCOORD0;
    28.                 float4 vertex : SV_POSITION;
    29.             };
    30.  
    31.             sampler2D _MainTex;
    32.             float4 _MainTex_ST;
    33.  
    34.             v2f vert (appdata v)
    35.             {
    36.                 v2f o;
    37.                 o.vertex = UnityObjectToClipPos(v.vertex);
    38.                 o.uv = TRANSFORM_TEX(v.uv, _MainTex);
    39.                 return o;
    40.             }
    41.  
    42.             fixed4 frag (v2f i) : SV_Target
    43.             {
    44.                 // sample the texture
    45.                 fixed4 col = 1.0 - tex2D(_MainTex, i.uv);
    46.                 return col;
    47.             }
    48.             ENDCG
    49.         }
    50.     }
    51. }
    52.  

    Apparently this worked in URP 7.1.6, but I was using 7.1.8 where it didn't work. Cyan was able to get it to work in URP 7.1.8 by disabling MSAA and setting Main Light to Disabled in the render pipeline asset. I tried this but still couldn't get it to work until I turned on post processing on the camera in my scene. This is obviously pretty limiting, but it's progress.

    The problem definitely isn't solved yet, but if I learn anything new I'll make a new post here.
     
    PoweredByUnity likes this.
  4. keenanwoodall

    keenanwoodall

    Joined:
    May 30, 2014
    Posts:
    598
    More progress has been made - again not by me!
    Blitting just wasn't playing nice, so it's essentially just a fullscreen pass now. Works with lights, doesn't need post processing enabled and it works the scene view. You still cannot have MSAA, but that's not the end of the world since you can still use post processing for AA.

    Here's the functioning prototype of the desired effect (I just wanted the occluded part to be styled differently)
    2020-03-06_10-07-59.gif
    Here's the final renderer for those who are curious
    upload_2020-3-6_10-10-33.png
    And here's the code
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.Rendering;
    3. using UnityEngine.Rendering.Universal;
    4.  
    5. public class FullscreenPass : ScriptableRendererFeature {
    6.     [System.Serializable]
    7.     public class CustomSettings {
    8.  
    9.         public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingOpaques;
    10.         public Material material;
    11.     }
    12.  
    13.     class Pass : ScriptableRenderPass {
    14.  
    15.         public RenderTargetIdentifier cameraColor { get; set; }
    16.  
    17.         private RenderTargetHandle m_TemporaryColorTexture;
    18.         private CustomSettings settings;
    19.      
    20.         public Pass(CustomSettings settings) {
    21.             this.settings = settings;
    22.         }
    23.      
    24.         public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor) {
    25.             // Create Temp Texture to hold Camera Color
    26.             m_TemporaryColorTexture.Init("_TemporaryColorTexture");
    27.  
    28.             // (doesn't need depthBits so setting this to 0, so the RT might use less memory I guess?)
    29.             RenderTextureDescriptor tempRTD = cameraTextureDescriptor;
    30.             tempRTD.depthBufferBits = 0;
    31.          
    32.             cmd.GetTemporaryRT(m_TemporaryColorTexture.id, tempRTD, FilterMode.Point);
    33.         }
    34.  
    35.         public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData) {
    36.             CommandBuffer cmd = CommandBufferPool.Get("FullscreenPass");
    37.          
    38.             // Copy Color Texture & Set Global _MainTex
    39.             cmd.CopyTexture(cameraColor, m_TemporaryColorTexture.Identifier());
    40.             cmd.SetGlobalTexture(Shader.PropertyToID("_MainTex"), m_TemporaryColorTexture.Identifier());
    41.          
    42.             // Set Projection & Draw Fullscreen Mesh
    43.             cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
    44.             Matrix4x4 matrix = Matrix4x4.TRS(new Vector3(0, 0, -1), Quaternion.identity, Vector3.one);
    45.             cmd.DrawMesh(RenderingUtils.fullscreenMesh, matrix, settings.material);
    46.  
    47.             // Reset Projection (otherwise objects later in the queue won't be rendered correctly)
    48.             Camera camera = renderingData.cameraData.camera;
    49.             cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
    50.          
    51.             context.ExecuteCommandBuffer(cmd);
    52.             CommandBufferPool.Release(cmd);
    53.         }
    54.      
    55.         public override void FrameCleanup(CommandBuffer cmd) {
    56.             if (cmd == null)
    57.                 throw new System.ArgumentNullException("cmd");
    58.  
    59.             // Release Temporary Color Texture
    60.             cmd.ReleaseTemporaryRT(m_TemporaryColorTexture.id);
    61.         }
    62.     }
    63.  
    64.     public CustomSettings settings = new CustomSettings();
    65.  
    66.     Pass m_ScriptablePass;
    67.  
    68.     public override void Create() {
    69.         m_ScriptablePass = new Pass(settings);
    70.         m_ScriptablePass.renderPassEvent = settings.renderPassEvent;
    71.     }
    72.  
    73.     public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData) {
    74.         m_ScriptablePass.cameraColor = renderer.cameraColorTarget;
    75.  
    76.         if (settings.material == null) {
    77.             return;
    78.         }
    79.  
    80.         renderer.EnqueuePass(m_ScriptablePass);
    81.     }
    82. }
     
    Last edited: Mar 6, 2020