Search Unity

Projector onto surface that has alpha cutout

Discussion in 'Shaders' started by mtompson_theMoment, Sep 14, 2018.

  1. mtompson_theMoment

    mtompson_theMoment

    Joined:
    Mar 28, 2017
    Posts:
    6
    Hi
    Please sea attached, I need to mod either the projector shader or the surface it's projecting onto shader!



    The projector is projecting onto mesh that should be invisible, I need to add the alpha from the surface into the projection somehow, please help.

    I have tried render queue orders but no luck.

    Projector shader:
    Code (CSharp):
    1. // Upgrade NOTE: replaced '_Projector' with 'unity_Projector'
    2. // Upgrade NOTE: replaced '_ProjectorClip' with 'unity_ProjectorClip'
    3. Shader "Projector/LightWithIntensity" {
    4.      Properties {
    5.          _Color ("Main Color", Color) = (1,1,1,1)
    6.          _ShadowTex ("Cookie", 2D) = "" {}
    7.          _FalloffTex ("FallOff", 2D) = "" {}
    8.          _Intensity ("Intensity",Float) = 1
    9.      }
    10.    
    11.      Subshader {
    12.          Tags {"Queue"="Transparent" "RenderType"="Transparent"}
    13.          Pass {
    14.              ZWrite Off
    15.              ColorMask RGB
    16.              Blend DstColor One
    17.              Offset -1, -1
    18.  
    19.  
    20.              CGPROGRAM
    21.              #pragma vertex vert
    22.              #pragma fragment frag
    23.              #pragma multi_compile_fog
    24.              #include "UnityCG.cginc"
    25.            
    26.              struct v2f {
    27.                  float4 uvShadow : TEXCOORD0;
    28.                  float4 uvFalloff : TEXCOORD1;
    29.                  UNITY_FOG_COORDS(2)
    30.                  float4 pos : SV_POSITION;
    31.              };
    32.            
    33.              float4x4 unity_Projector;
    34.              float4x4 unity_ProjectorClip;
    35.            
    36.              v2f vert (float4 vertex : POSITION)
    37.              {
    38.                  v2f o;
    39.                  o.pos = UnityObjectToClipPos(vertex);
    40.                  o.uvShadow = mul (unity_Projector, vertex);
    41.                  o.uvFalloff = mul (unity_ProjectorClip, vertex);
    42.                  UNITY_TRANSFER_FOG(o,o.pos);
    43.                  return o;
    44.              }
    45.            
    46.              fixed4 _Color;
    47.              sampler2D _ShadowTex;
    48.              sampler2D _FalloffTex;
    49.              float _Intensity;
    50.            
    51.              fixed4 frag (v2f i) : SV_Target
    52.              {
    53.                  fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
    54.                  texS.rgb *= _Color.rgb;
    55.                  texS.a = 1.0-texS.a;
    56.    
    57.                  fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
    58.                  fixed4 res = texS * _Intensity * texF.a;
    59.                  UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(0,0,0,0));
    60.                  return res;
    61.              }
    62.              ENDCG
    63.          }
    64.      }
    65. }
    Surface shader:
    Shader "Standard (Double Cutout)" {

    Properties {
    _Color ("Color", Color) = (1,1,1,1)
    _MainTex ("Albedo (RGBA)", 2D) = "white" {}
    _MaskTex ("Mask (RGBA)", 2D) = "white" {}
    _Glossiness ("Smoothness", Range(0,1)) = 0.5
    _Metallic ("Metallic", Range(0,1)) = 0.0
    //_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
    //_BumpMap ("Normal Map", 2D) = "bump" {}
    }

    SubShader {
    Tags {"Queue"="Transparent" "IgnoreProjector"="False" "RenderType"="Transparent"}
    //Tags {"Queue"="AlphaTest" "Ignore Projector" = "True" "RenderType"="Transparent"}
    ZWrite Off
    //Blend SrcAlpha One
    //Blend OneMinusSrcAlpha SrcAlpha
    //Offset -1, -1

    LOD 200

    CGPROGRAM

    #pragma surface surf Standard fullforwardshadows alpha:fade

    //#pragma surface surf Standard alpha : fade

    #pragma target 3.0

    sampler2D _MainTex;
    sampler2D _MaskTex;
    sampler2D _BumpMap;

    struct Input {
    float2 uv_MainTex;
    float2 uv2_MaskTex;
    float2 uv_BumpMap;
    };

    half _Glossiness;
    half _Metallic;
    fixed4 _Color;

    void surf (Input IN, inout SurfaceOutputStandard o) {

    fixed4 main = tex2D (_MainTex, IN.uv_MainTex) * _Color;
    fixed4 mask = tex2D (_MaskTex, IN.uv2_MaskTex);

    //Multiplied by the mask.rgb in this case, because if you use a white texture as your mask,
    //you can color it black to add burn marks around the damage.
    o.Albedo = main.rgb * mask.rgb;

    //For most cases, you'd probably just want:
    //surface.Albedo = main.rgb;
    o.Metallic = _Metallic;
    o.Smoothness = _Glossiness;

    o.Alpha = main.a * mask.a;
    //o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap));
    }

    ENDCG
    }
    FallBack "Diffuse"
    }
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    There is no solution to this issue with projectors.

    The way projectors work is they re-render each mesh the projector's frustum overlaps with, just using the Projector's material instead of the one assigned on the mesh's renderer component. This means if you have a shader that's using alpha testing or transparency, the projector has no way to know that. It is just going to blindly render the entire mesh.

    Unity's solution to this problem was to just punt on it. If you look at Unity's internal Alpha Cutout and Transparent shaders, they all have this line in the shader:

    "IgnoreProjector"="True"

    You can probably guess what that does. The Standard Shader released with Unity 5 doesn't even bother with that and will have the same issues as your shader does.

    The only solution is to not use projectors. Instead have your Surface Shader add the caustics on it's own.
     
    NathanWarden likes this.
  3. mtompson_theMoment

    mtompson_theMoment

    Joined:
    Mar 28, 2017
    Posts:
    6
    Understood, many thanks for the reply.