Search Unity

Question Clipping a projector by normal

Discussion in 'General Graphics' started by Pythagoras64, Jan 19, 2021.

  1. Pythagoras64

    Pythagoras64

    Joined:
    Feb 10, 2015
    Posts:
    15
    Hi, I was hoping someone more familiar with shaders could help me get the behavior I want out of my projector.

    Ideally what I'd like is to simply not render anything with a normal that deviates too far from straight up, so the projector won't render on the sides of objects.



    This is the code I'm using for the shader.

    Code (CSharp):
    1. Shader "Projector/AlphaBlend"
    2. {
    3.     Properties
    4.     {
    5.         _ShadowTex("ShadowTex", 2D) = "white" {}
    6.         _ColorTint("ColorTint", Color) = (1.0, 0.6, 1.0, 1.0)
    7.     }
    8.  
    9.         Subshader
    10.         {
    11.             Tags { "Queue" = "Transparent" }
    12.             Pass
    13.             {
    14.                 ZWrite Off
    15.                 ColorMask RGB
    16.                 Blend SrcAlpha One
    17.                 Offset -1, -1
    18.  
    19.                 Stencil
    20.                 {
    21.                     Ref 2
    22.                     Comp NotEqual
    23.                     Pass Replace
    24.                 }
    25.  
    26.                 CGPROGRAM
    27.                 #pragma vertex vert
    28.                 #pragma fragment frag
    29.                 #pragma multi_compile_fog
    30.                 #include "UnityCG.cginc"
    31.  
    32.                 struct v2f
    33.                 {
    34.                     float4 uvShadow : TEXCOORD0;
    35.                     UNITY_FOG_COORDS(2)
    36.                     float4 pos : SV_POSITION;
    37.                 };
    38.  
    39.                 float4x4 unity_Projector;
    40.                 float4x4 unity_ProjectorClip;
    41.                 sampler2D _ShadowTex;
    42.                 float4 _ColorTint;
    43.  
    44.                 //Vertex function
    45.                 v2f vert(float4 vertex : POSITION)
    46.                 {
    47.                     v2f o;
    48.                     o.pos = UnityObjectToClipPos(vertex);
    49.                     o.uvShadow = mul(unity_Projector, vertex);
    50.                     UNITY_TRANSFER_FOG(o, o.pos);
    51.                     return o;
    52.                 }
    53.  
    54.                 //Fragment function
    55.                 fixed4 frag(v2f i) : SV_Target
    56.                 {
    57.                     fixed4 tex = tex2Dproj(_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
    58.                     clip(tex.a - 0.5);
    59.                     tex = _ColorTint;
    60.                     tex.a = _ColorTint.a;
    61.                     UNITY_APPLY_FOG(i.fogCoord, tex);
    62.                     return tex;
    63.                 }
    64.  
    65.                 ENDCG
    66.             }
    67.         }
    68. }
    69.  
    My other option was to split the terrain up into a bunch of layers, but I think having the shader handle it would make much more sense.

    Thanks!