Search Unity

Projector creates multiple projections of the shadder

Discussion in 'General Graphics' started by rubens268, May 25, 2019.

  1. rubens268

    rubens268

    Joined:
    Jan 11, 2015
    Posts:
    5
    Hi!,

    Im trying to build my own Fog of War, I'm doing it with a projector, I alredy have it, with a custom shader that acts as a mask and with a projector:



    It works ok, but I have a problem, the projector repeats the shader over all the GameObjects, as you can see on the next image:



    Another case:


    Here is my shader code:
    Code (CSharp):
    1.  
    2. Shader "Custom/FOWShader"
    3. {
    4.     Properties
    5.     {
    6.         _Color("Color", Color) = (0,0,0,0.7)
    7.         _MainTex("Canvas", 2D) = "white" {}
    8.         _Smoothness("Feather", Range(0,0.1)) = 0.005
    9.         _Rotation("Rotation", Range(0.0, 360.0)) = 0.0
    10.  
    11.     }
    12.  
    13.         SubShader
    14.     {
    15.         Tags{ "Queue" = "Transparent" "RenderType" = "Transparent" "LightMode" = "ForwardBase" }
    16.         Blend One One
    17.         Lighting off
    18.         ZWrite Off
    19.        
    20.        
    21.  
    22.         CGPROGRAM
    23. #pragma surface surf NoLighting noambient alpha:blend
    24. #pragma vertex vert
    25.  
    26.         fixed4 _Color;
    27.     sampler2D _MainTex;
    28.     float _Smoothness;
    29.  
    30.     struct Input
    31.     {
    32.         float2 uv_MainTex;
    33.     };
    34.     float _Rotation;
    35.  
    36.     void vert(inout appdata_full v) {
    37.         v.texcoord1 = v.texcoord; // copy uvs from texcoord to texcoord1 (aka uv2) before rotation
    38.  
    39.         float rot = _Rotation / (57.2957795131);
    40.         float sinX = sin(rot);
    41.         float cosX = cos(rot);
    42.         float sinY = sin(rot);
    43.         float2x2 rotationMatrix = float2x2(cosX, -sinX, sinY, cosX);
    44.         v.texcoord.xy = mul(v.texcoord.xy - 0.5, rotationMatrix) + 0.5;
    45.  
    46.  
    47.     }
    48.  
    49.     fixed4 LightingNoLighting(SurfaceOutput s, fixed3 lightDir, float aten)
    50.     {
    51.         fixed4 color;
    52.         color.rgb = s.Albedo;
    53.         color.a = s.Alpha;
    54.         return color;
    55.     }
    56.  
    57.  
    58.     void surf(Input IN, inout SurfaceOutput o)
    59.     {
    60.  
    61.         half4 gaussianH = tex2D(_MainTex, IN.uv_MainTex + float2(-_Smoothness,0))*0.25;
    62.         gaussianH += tex2D(_MainTex, IN.uv_MainTex)*0.5;
    63.         gaussianH += tex2D(_MainTex, IN.uv_MainTex + float2(_Smoothness,0))*0.25;
    64.  
    65.         half4 gaussianV = tex2D(_MainTex, IN.uv_MainTex + float2(0,-_Smoothness))*0.25;
    66.         gaussianV += tex2D(_MainTex, IN.uv_MainTex) *0.5;
    67.         gaussianV += tex2D(_MainTex, IN.uv_MainTex + float2(0, _Smoothness))*0.25;
    68.  
    69.         half4 blurred = (gaussianH + gaussianV)*0.5;
    70.  
    71.         o.Albedo = _Color.rgb * blurred.g;
    72.         o.Alpha = _Color.a - blurred.g;
    73.     }
    74.  
    75.     ENDCG
    76.     }
    77.         FallBack "Diffuse"
    78. }
    79.  
    I realy dont know what I must do to project only one texture over all the entire scene but not over each mesh.
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    6,738
    Two things:
    Never use a surface shader for something that is “unlit”. The “NoLighting” hack people like to use with the surface shader is still doing some lighting, and will mess up if there are multiple lights in the scene.
    Don’t use a surface shader with a projector. Shaders used with projectors don’t receive any lighting information, and thus will render oddly.

    Now, those two things end up kind of canceling each other out, but there are still unnecessary calculations being done when you use a surface shader that end up making them slower than they should be for this use case. You should be using a shader written specifically to be used with Unity’s projectors.

    Here’s an example shader:
    https://gist.github.com/aras-p/8848786

    The texture using the uvShadow will be aligned to the projector’s projection direction. The texture using the uvFalloff is aligned along the projector’s facing stretching from the near to the far plane. You can remove either texture and it’s associated calculations if not needed.
     
    rubens268 likes this.
  3. rubens268

    rubens268

    Joined:
    Jan 11, 2015
    Posts:
    5
    Wow it's nice, thanks! I rly learned so much things from u :D