Search Unity

Resolved Shader shows different when using SIngle Pass Instanced

Discussion in 'Shaders' started by FiveFingerStudios, Apr 27, 2021.

  1. FiveFingerStudios

    FiveFingerStudios

    Joined:
    Apr 22, 2016
    Posts:
    510
    I have a shader that I works in both multi pass and single pass correctly. I want to get it working in single pass instanced.

    My problem is that the shader renders it different when I switch to single pass instanced, even before I modify the shader code to support instanced.

    If you look at the attached image, the left shows that it should be transparent (red circles) and the right shows it as solid grey (red circle)...which is wrong.

    Any idea what could cause this?

    Code (CSharp):
    1. Shader "Custom/CutOutParticles" {
    2.     Properties{
    3.             _TintColor("Tint Color", Color) = (1,1,1,1)
    4.             _ColorStrength("Color Intensity", Float) = 1
    5.             _MainTex("Base (RGB) Gloss (A)", 2D) = "black" {}
    6.             _CutOut("CutOut (A)", 2D) = "black" {}
    7.             _BumpMap("Normalmap", 2D) = "bump" {}
    8.             _BumpAmt("Bump Amount", Float) = 10
    9.            
    10.  
    11.     }
    12.         Category{
    13.  
    14.             Tags { "Queue" = "Transparent+2"  "IgnoreProjector" = "True"  "RenderType" = "Transparent" }
    15.             Blend SrcAlpha OneMinusSrcAlpha
    16.             Lighting Off
    17.             Cull Off
    18.             ZWrite Off
    19.             Fog {Mode Off}
    20.  
    21.             SubShader {
    22.                 GrabPass {
    23.                     Name "_GrabTexture"
    24.                 }
    25.                 Pass {
    26.  
    27.         CGPROGRAM
    28.         #pragma vertex vert
    29.         #pragma fragment frag
    30.         #pragma fragmentoption ARB_precision_hint_fastest
    31.         #pragma multi_compile_particles
    32.         #include "UnityCG.cginc"
    33.  
    34.         struct appdata {
    35.             float4 vertex : POSITION;
    36.             float2 texcoord: TEXCOORD0;
    37.             fixed4 color : COLOR;
    38.         };
    39.  
    40.         struct v2f {
    41.             float4 vertex : POSITION;
    42.             float4 uvgrab : TEXCOORD0;
    43.             float2 uvbump : TEXCOORD1;
    44.             float2 uvmain : TEXCOORD2;
    45.             float2 uvcutout : TEXCOORD3;
    46.             fixed4 color : COLOR;
    47.             #ifdef SOFTPARTICLES_ON
    48.                 float4 projPos : TEXCOORD4;
    49.             #endif
    50.         };
    51.  
    52.         sampler2D _MainTex;
    53.         sampler2D _CutOut;
    54.         sampler2D _BumpMap;
    55.  
    56.         float _BumpAmt;
    57.         float _ColorStrength;
    58.         sampler2D _GrabTexture;
    59.         float4 _GrabTexture_TexelSize;
    60.         fixed4 _TintColor;
    61.         float4 _LightColor0;
    62.         float4 _MainTex_ST;
    63.         float4 _CutOut_ST;
    64.         float4 _BumpMap_ST;
    65.  
    66.  
    67.         v2f vert(appdata v)
    68.         {
    69.             v2f o;
    70.  
    71.             o.vertex = UnityObjectToClipPos(v.vertex);
    72.             #ifdef SOFTPARTICLES_ON
    73.                 o.projPos = ComputeScreenPos(o.vertex);
    74.                 COMPUTE_EYEDEPTH(o.projPos.z);
    75.             #endif
    76.             o.color = v.color;
    77.             #if UNITY_UV_STARTS_AT_TOP
    78.             float scale = -1.0;
    79.             #else
    80.             float scale = 1.0;
    81.             #endif
    82.             o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    83.             o.uvgrab.zw = o.vertex.w;
    84.             o.uvbump = TRANSFORM_TEX(v.texcoord, _BumpMap);
    85.             o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
    86.             o.uvcutout = TRANSFORM_TEX(v.texcoord, _CutOut);
    87.  
    88.             return o;
    89.         }
    90.  
    91.  
    92.         half4 frag(v2f i) : COLOR
    93.         {
    94.             half2 bumpMap = UnpackNormal(tex2D(_BumpMap, i.uvbump)).rg;
    95.             float2 offset = bumpMap * _GrabTexture_TexelSize.xy * _BumpAmt ;
    96.             i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
    97.             half4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    98.             fixed4 tex = tex2D(_MainTex, i.uvmain) * i.color;
    99.             fixed4 cut = tex2D(_CutOut, i.uvcutout) * i.color;
    100.             fixed4 emission = col * i.color + tex * _LightColor0 * _TintColor * _ColorStrength  ;
    101.             emission.a =  i.color.a * _TintColor.a * (cut.a);
    102.             return emission;
    103.         }
    104.         ENDCG
    105.                 }
    106.             }
    107.  
    108.             SubShader {
    109.                 Blend DstColor Zero
    110.                 Pass {
    111.                     Name "BASE"
    112.                     SetTexture[_MainTex] {    combine texture }
    113.                 }
    114.             }
    115.             }
    116.  
    117. }
    118.  
     

    Attached Files:

  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,342
    You should be using
    ComputeGrabScreenPos()
    to calculate the grab pass UV. It does more then what your code does, especially for stereo rendering.

    And that might not fix it because grab passes are broken in single pass stereo.
     
    gotiobg likes this.
  3. FiveFingerStudios

    FiveFingerStudios

    Joined:
    Apr 22, 2016
    Posts:
    510
    Thanks for the reply. Since its broken, Is there another way to get that effect without using grab passes?

    Edit: Ok, I've given up on this shader. I'll use a different technique to get similar result. Thanks for the help.
     
    Last edited: Apr 28, 2021
  4. FiveFingerStudios

    FiveFingerStudios

    Joined:
    Apr 22, 2016
    Posts:
    510
    After looking at this for a bit, I finally have a solution. Hopefully someone else will benefit from this.

    It looks like the issue is when going to single pass instanced you cannot use sampler2D for the GrabPass, but use UNITY_DECLARE_SCREENSPACE_TEXTURE instead as it needs to be put into a texture array.

    Code (CSharp):
    1. Shader "Custom/CutOutParticles" {
    2.     Properties{
    3.             _TintColor("Tint Color", Color) = (1,1,1,1)
    4.             _ColorStrength("Color Intensity", Float) = 1
    5.             _MainTex("Base (RGB) Gloss (A)", 2D) = "black" {}
    6.             _CutOut("CutOut (A)", 2D) = "black" {}
    7.             _BumpMap("Normalmap", 2D) = "bump" {}
    8.             _BumpAmt("Bump Amount", Float) = 10
    9.          
    10.     }
    11.         Category{
    12.             Tags { "Queue" = "Transparent+2"  "IgnoreProjector" = "True"  "RenderType" = "Transparent" }
    13.             Blend SrcAlpha OneMinusSrcAlpha
    14.             Lighting Off
    15.             Cull Off
    16.             ZWrite Off
    17.             Fog {Mode Off}
    18.             SubShader {
    19.                 GrabPass {
    20.                     Name "_GrabTexture"
    21.                 }
    22.                 Pass {
    23.         CGPROGRAM
    24.         #pragma vertex vert
    25.         #pragma fragment frag
    26.         #pragma fragmentoption ARB_precision_hint_fastest
    27.         #pragma multi_compile_particles
    28.         #pragma multi_compile_instancing
    29.         #include "UnityCG.cginc"
    30.         struct appdata {
    31.             float4 vertex : POSITION;
    32.             float2 texcoord: TEXCOORD0;
    33.             fixed4 color : COLOR;
    34.         };
    35.         struct v2f {
    36.             float4 vertex : POSITION;
    37.             float4 uvgrab : TEXCOORD0;
    38.             float2 uvbump : TEXCOORD1;
    39.             float2 uvmain : TEXCOORD2;
    40.             float2 uvcutout : TEXCOORD3;
    41.             fixed4 color : COLOR;
    42.             #ifdef SOFTPARTICLES_ON
    43.                 float4 projPos : TEXCOORD4;
    44.             #endif
    45.         };
    46.         sampler2D _MainTex;
    47.         sampler2D _CutOut;
    48.         sampler2D _BumpMap;
    49.         float _BumpAmt;
    50.         float _ColorStrength;
    51.         //sampler2D _GrabTexture;
    52.     UNITY_DECLARE_SCREENSPACE_TEXTURE(_GrabTexture);
    53.         float4 _GrabTexture_TexelSize;
    54.         fixed4 _TintColor;
    55.         float4 _LightColor0;
    56.         float4 _MainTex_ST;
    57.         float4 _CutOut_ST;
    58.         float4 _BumpMap_ST;
    59.         v2f vert(appdata v)
    60.         {
    61.             v2f o;
    62.             o.vertex = UnityObjectToClipPos(v.vertex);
    63.             #ifdef SOFTPARTICLES_ON
    64.                 o.projPos = ComputeScreenPos(o.vertex);
    65.                 COMPUTE_EYEDEPTH(o.projPos.z);
    66.             #endif
    67.             o.color = v.color;
    68.             #if UNITY_UV_STARTS_AT_TOP
    69.             float scale = -1.0;
    70.             #else
    71.             float scale = 1.0;
    72.             #endif
    73.             o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    74.             o.uvgrab.zw = o.vertex.w;
    75.             o.uvbump = TRANSFORM_TEX(v.texcoord, _BumpMap);
    76.             o.uvmain = TRANSFORM_TEX(v.texcoord, _MainTex);
    77.             o.uvcutout = TRANSFORM_TEX(v.texcoord, _CutOut);
    78.             return o;
    79.         }
    80.         half4 frag(v2f i) : COLOR
    81.         {
    82.             half2 bumpMap = UnpackNormal(tex2D(_BumpMap, i.uvbump)).rg;
    83.             float2 offset = bumpMap * _GrabTexture_TexelSize.xy * _BumpAmt ;
    84.             i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
    85.             //half4 col = tex2Dproj(_GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    86.         half4 col = UNITY_SAMPLE_SCREENSPACE_TEXTURE(_GrabTexture, i.uvgrab.xy / i.uvgrab.w);
    87.             fixed4 tex = tex2D(_MainTex, i.uvmain) * i.color;
    88.             fixed4 cut = tex2D(_CutOut, i.uvcutout) * i.color;
    89.             fixed4 emission = col * i.color + tex * _LightColor0 * _TintColor * _ColorStrength  ;
    90.             emission.a =  i.color.a * _TintColor.a * (cut.a);
    91.             return emission;
    92.         }
    93.         ENDCG
    94.                 }
    95.             }
    96.             SubShader {
    97.                 Blend DstColor Zero
    98.                 Pass {
    99.                     Name "BASE"
    100.                     SetTexture[_MainTex] {    combine texture }
    101.                 }
    102.             }
    103.             }
    104. }
     
    Frostbite23, MaxEden and bgolus like this.