Search Unity

_Projector, Projector shader and CG

Discussion in 'Shaders' started by taoa, Dec 7, 2010.

  1. taoa

    taoa

    Joined:
    Dec 10, 2009
    Posts:
    88
    Hi all.

    Trying to improve the visual quality of our projectors, I wanted to modify the shader we use for the projectors material.

    This is what we and probably most people are using:

    Code (csharp):
    1. Shader "Projector/Projector Multiply"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Colour", Color) = (1,1,1,0)
    6.         _ShadowTex ("Cookie", 2D) = "gray" { TexGen ObjectLinear }
    7.     }
    8.  
    9.     Subshader
    10.     {
    11.         Tags { "RenderType"="Transparent"  "Queue"="Transparent+100"}
    12.         Pass
    13.         {
    14.             ZWrite Off
    15.             Offset -1, -1
    16.  
    17.             Fog { Mode Off }
    18.            
    19.             //AlphaTest Greater .1
    20.             AlphaTest Less 1
    21.             ColorMask RGB
    22.             Blend One SrcAlpha
    23.  
    24.             SetTexture [_ShadowTex]
    25.             {
    26.                 constantColor [_Color]
    27.                 combine texture * constant, One - texture
    28.                 Matrix [_Projector]
    29.             }
    30.         }
    31.     }
    32. }
    33.  
    We slightly modified it so that it can take a color and removed the falloff texture, but that's pretty much what you'll find in the Projectors package BlobShadow prefab shader.





    Since I want way better control about the way this is all rendered, I wanted to move it to CG code. My puny and failed attempt at simply reproducing what the fixed function shader was doing looks like this:

    Code (csharp):
    1. Shader "Projector/Projector Multiply"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Colour", Color) = (1,1,1,0)
    6.         _ShadowTex ("Cookie", 2D) = "gray" { TexGen ObjectLinear }
    7.     }
    8.  
    9.     Subshader
    10.     {
    11.         Tags { "RenderType"="Transparent"  "Queue"="Transparent+100"}
    12.         Pass
    13.         {
    14.             ZWrite Off
    15.             Offset -1, -1
    16.  
    17.             Fog { Mode Off }
    18.            
    19.             //AlphaTest Greater .1
    20.             AlphaTest Less 1
    21.             ColorMask RGB
    22.             Blend One SrcAlpha
    23. CGPROGRAM
    24. #pragma vertex vert
    25. #pragma fragment frag
    26. #pragma fragmentoption ARB_fog_exp2
    27. #pragma fragmentoption ARB_precision_hint_fastest
    28. #include "UnityCG.cginc"
    29.  
    30. struct v2f
    31. {
    32.     float4 pos : SV_POSITION;
    33.     float2  uv_Main     : TEXCOORD0;
    34. };
    35.  
    36. sampler2D _ShadowTex;
    37. float4 _Color;
    38. float4x4 _Projector;
    39.  
    40. v2f vert(appdata_tan v)
    41. {
    42.     v2f o;
    43.     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    44.     o.uv_Main = mul (_Projector, v.texcoord).xy;
    45.     return o;
    46. }
    47.  
    48. half4 frag (v2f i) : COLOR
    49. {
    50.     half4 tex = tex2D(_ShadowTex, i.uv_Main) * _Color;
    51.     tex.a = 1-tex.a;
    52.     return tex;
    53. }
    54. ENDCG
    55.  
    56.         }
    57.     }
    58. }
    59.  
    This doesn't work, it looks like the projection is being done wrong, as it seems to take only a very little part of the texture I'm passing in:



    (I didn't use the same texture since the other one was simply giving invisible results, whereas this one shows a little gradient on the right coming from the texture, God knows from what part of it though)
    (The receiving geometry in the back is a Terrain in both cases)

    Anyone knows projectors in great details, someone from Unity who worked on it? Someone like, oh I don't knooow, let's saaaaay, Aras? :rolleyes:
     
  2. taoa

    taoa

    Joined:
    Dec 10, 2009
    Posts:
    88
  3. taoa

    taoa

    Joined:
    Dec 10, 2009
    Posts:
    88
    Still in need of an answer for that.

    Also, I'd like to be able to control the projection's transparency by the main color's alpha channel, with the old shader everyone uses.
    If I do something like
    Code (csharp):
    1. combine texture * constant, One - texture * constant
    and set the main color's alpha to 0.5 (128), all I get is



    instead of



    if I set the main color's alpha back to 1, which isn't the result I was expecting.

    Thanks for any help. At all. Please.
     
  4. taoa

    taoa

    Joined:
    Dec 10, 2009
    Posts:
    88
    Concerning the ability to fade a projector in transparency, this shader works:

    Code (csharp):
    1.  
    2.     Subshader
    3.     {
    4.         Tags { "RenderType"="Transparent" "Queue"="Transparent-100" }
    5.         Pass
    6.         {
    7.             ZWrite Off
    8.             Fog { Mode Off }
    9.             ColorMask RGB
    10.             Blend SrcAlpha OneMinusSrcAlpha
    11.             SetTexture [_ShadowTex]
    12.             {
    13.                 constantColor [_Color]
    14.                 combine texture * constant, texture * constant
    15.                 Matrix [_Projector]
    16.             }
    17.         }
    18.     }

    But I'd really rather do those things in CG.

    Thanks!
     
  5. taoa

    taoa

    Joined:
    Dec 10, 2009
    Posts:
    88
    Got it:

    Code (csharp):
    1. Shader "Projector/Projector MultiplyCG"
    2. {
    3.     Properties
    4.     {
    5.         _Color ("Main Colour", Color) = (1,1,1,0)
    6.         _ShadowTex ("Cookie", 2D) = "gray" { TexGen ObjectLinear }
    7.     }
    8.  
    9.     Subshader
    10.     {
    11.         Tags { "RenderType"="Transparent"  "Queue"="Transparent+100"}
    12.         Pass
    13.         {
    14.             ZWrite Off
    15.             Offset -1, -1
    16.  
    17.             Fog { Mode Off }
    18.            
    19.             AlphaTest Less 1
    20.             ColorMask RGB
    21.             Blend One SrcAlpha
    22. CGPROGRAM
    23. #pragma vertex vert
    24. #pragma fragment frag
    25. #pragma fragmentoption ARB_fog_exp2
    26. #pragma fragmentoption ARB_precision_hint_fastest
    27. #include "UnityCG.cginc"
    28.  
    29. struct v2f
    30. {
    31.     float4 pos : SV_POSITION;
    32.     float[COLOR="red"]4[/COLOR] uv_Main     : TEXCOORD0;
    33. };
    34.  
    35. sampler2D _ShadowTex;
    36. float4 _Color;
    37. float4x4 _Projector;
    38.  
    39. v2f vert(appdata_tan v)
    40. {
    41.     v2f o;
    42.     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    43.     o.uv_Main = [COLOR="red"]mul (_Projector, v.vertex);[/COLOR]
    44.     return o;
    45. }
    46.  
    47. half4 frag (v2f i) : COLOR
    48. {
    49.     half4 tex = [COLOR="red"]tex2Dproj[/COLOR](_ShadowTex, [COLOR="red"]UNITY_PROJ_COORD(i.uv_Main)[/COLOR]) * _Color;
    50.     tex.a = 1-tex.a;
    51.     return tex;
    52. }
    53. ENDCG
    54.         }
    55.     }
    56. }
    57.  
    Serves me right for completely overlooking TexGen ObjectLinear in the texture declaration

    We now have a CG version of the projector shader to which we can do more easily some nasty though cool and expensive things!

    All my thanks to Aras :)
     
  6. tomvds

    tomvds

    Joined:
    Oct 10, 2008
    Posts:
    1,028
    Thanks :)
     
  7. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    I am looking to make my own projector shader. The code posted above throws many errors in Unity 4. Are there any examples or working unity cg shaders for projectors out there?
     
  8. Martin-Kraus

    Martin-Kraus

    Joined:
    Feb 18, 2011
    Posts:
    617
    This might work with Unity4 (not sure): http://en.wikibooks.org/wiki/Cg_Programming/Unity/Projectors
    Let me know if it doesn't.
     
  9. Airship

    Airship

    Joined:
    Sep 10, 2011
    Posts:
    260
    Many thanks, Martin! It compiles, though it has some issues with flickering and applying the blob shadow to objects that are not in the projectors FOV. I will tinker around and see if I can get it working correctly before posting again.
     
  10. cassiofoliveira

    cassiofoliveira

    Joined:
    Jan 23, 2013
    Posts:
    1
    I am thankfull from the deep of my heart, this code saved my life!

    The code works, just remove any tag between "[ ]" like "[Color = "red"]" this is probably due to the code editor in here...