Search Unity

How to make projector additive shader work with Unity 5

Discussion in 'Shaders' started by Jessmess, Oct 6, 2015.

  1. Jessmess

    Jessmess

    Joined:
    Oct 6, 2015
    Posts:
    2
    Hello

    I'm trying to get a projector to work in Unity 5 but the fixed function TexGen additive shader found on the Unity wiki isn't working with Unity 5.

    The light projector shader that comes with Unity 5 doesn't work like a light at all. It works like a faint decal material instead.

    How would I go about changing the projector multiply shader to work like the additive projector.


    Here is the additive shader from Unity 4:

    Code (csharp):
    1.  
    2. Shader "Projector/Additive" {
    3. Properties {
    4. _ShadowTex ("Cookie", 2D) = "" { TexGen ObjectLinear }
    5. _FalloffTex ("FallOff", 2D) = "" { TexGen ObjectLinear }
    6. }
    7. Subshader {
    8. Pass {
    9. ZWrite off
    10. Fog { Color (1, 1, 1) }
    11. ColorMask RGB
    12. Blend One One
    13. SetTexture [_ShadowTex] {
    14. combine texture, ONE - texture
    15. Matrix [_Projector]
    16. }
    17. SetTexture [_FalloffTex] {
    18. constantColor (0,0,0,0)
    19. combine previous lerp (texture) constant
    20. Matrix [_ProjectorClip]
    21. }
    22. }
    23. }
    24. }
    25.  
    26.  
    And here is the multiply projector:

    Code (csharp):
    1.  
    2.  
    3. Shader "Projector/Multiply" {
    4.  
    5. Properties {
    6.  
    7. _ShadowTex ("Cookie", 2D) = "gray" {}
    8.  
    9. _FalloffTex ("FallOff", 2D) = "white" {}
    10.  
    11. }
    12.  
    13. Subshader {
    14.  
    15. Tags {"Queue"="Transparent"}
    16.  
    17. Pass {
    18.  
    19. ZWrite Off
    20.  
    21. ColorMask RGB
    22.  
    23. Blend DstColor Zero
    24.  
    25. Offset -1, -1
    26.  
    27.  
    28. CGPROGRAM
    29.  
    30. #pragma vertex vert
    31.  
    32. #pragma fragment frag
    33.  
    34. #pragma multi_compile_fog
    35.  
    36. #include "UnityCG.cginc"
    37.  
    38.  
    39. struct v2f {
    40.  
    41. float4 uvShadow : TEXCOORD0;
    42.  
    43. float4 uvFalloff : TEXCOORD1;
    44.  
    45. UNITY_FOG_COORDS(2)
    46.  
    47. float4 pos : SV_POSITION;
    48.  
    49. };
    50.  
    51.  
    52. float4x4 _Projector;
    53.  
    54. float4x4 _ProjectorClip;
    55.  
    56.  
    57. v2f vert (float4 vertex : POSITION)
    58.  
    59. {
    60.  
    61. v2f o;
    62.  
    63. o.pos = mul (UNITY_MATRIX_MVP, vertex);
    64.  
    65. o.uvShadow = mul (_Projector, vertex);
    66.  
    67. o.uvFalloff = mul (_ProjectorClip, vertex);
    68.  
    69. UNITY_TRANSFER_FOG(o,o.pos);
    70.  
    71. return o;
    72.  
    73. }
    74.  
    75.  
    76. sampler2D _ShadowTex;
    77.  
    78. sampler2D _FalloffTex;
    79.  
    80.  
    81. fixed4 frag (v2f i) : SV_Target
    82.  
    83. {
    84.  
    85. fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
    86.  
    87. texS.a = 1.0-texS.a;
    88.  
    89.  
    90. fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
    91.  
    92. fixed4 res = lerp(fixed4(1,1,1,0), texS, texF.a);
    93.  
    94.  
    95. UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(1,1,1,1));
    96.  
    97. return res;
    98.  
    99. }
    100.  
    101. ENDCG
    102.  
    103. }
    104.  
    105. }
    106.  
    107. }
    108.  
    109.  
    110.  

    Being a bit of a noob with shaders I can't find the part of the shader that actually multiplies the values.

    Can someone point me to the right direction?
     
  2. pixpusher2

    pixpusher2

    Joined:
    Oct 30, 2013
    Posts:
    121
    Use the multiply projector shader and change line 23 from
    Code (CSharp):
    1. Blend DstColor Zero
    to
    Code (CSharp):
    1. Blend One One
    and it should work as additive. Remember to change the shader name to something else at the beginning too.
     
  3. Jessmess

    Jessmess

    Joined:
    Oct 6, 2015
    Posts:
    2
    Thank you very much. That was quick.

    Is there any way to multiply the additive effect with a variable?
     
  4. pixpusher2

    pixpusher2

    Joined:
    Oct 30, 2013
    Posts:
    121
    I've added an adjustable Power variable to multiply the effect. It's not been tested though.

    Code (CSharp):
    1. Shader "Projector/Additive" {
    2. Properties {
    3. _ShadowTex ("Cookie", 2D) = "gray" {}
    4. _FalloffTex ("FallOff", 2D) = "white" {}
    5. _Power ("Power", Float) = 1
    6. }
    7. Subshader {
    8. Tags {"Queue"="Transparent"}
    9. Pass {
    10. ZWrite Off
    11. ColorMask RGB
    12. Blend One One
    13. Offset -1, -1
    14. CGPROGRAM
    15. #pragma vertex vert
    16. #pragma fragment frag
    17. #pragma multi_compile_fog
    18. #include "UnityCG.cginc"
    19. struct v2f {
    20. float4 uvShadow : TEXCOORD0;
    21. float4 uvFalloff : TEXCOORD1;
    22. UNITY_FOG_COORDS(2)
    23. float4 pos : SV_POSITION;
    24. };
    25. float4x4 _Projector;
    26. float4x4 _ProjectorClip;
    27. v2f vert (float4 vertex : POSITION)
    28. {
    29. v2f o;
    30. o.pos = mul (UNITY_MATRIX_MVP, vertex);
    31. o.uvShadow = mul (_Projector, vertex);
    32. o.uvFalloff = mul (_ProjectorClip, vertex);
    33. UNITY_TRANSFER_FOG(o,o.pos);
    34. return o;
    35. }
    36. sampler2D _ShadowTex;
    37. sampler2D _FalloffTex;
    38.  
    39. float _Power;
    40. fixed4 frag (v2f i) : SV_Target
    41. {
    42. fixed4 texS = tex2Dproj (_ShadowTex, UNITY_PROJ_COORD(i.uvShadow));
    43. texS.a = 1.0-texS.a;
    44. fixed4 texF = tex2Dproj (_FalloffTex, UNITY_PROJ_COORD(i.uvFalloff));
    45. fixed4 res = lerp(fixed4(1,1,1,0), texS, texF.a);
    46. UNITY_APPLY_FOG_COLOR(i.fogCoord, res, fixed4(1,1,1,1));
    47.  
    48. return res * _Power;
    49. }
    50. ENDCG
    51. }
    52. }
    53. }