Search Unity

AdditiveProjection.shader

Discussion in 'Shaders' started by Jonathan Czeck, Dec 21, 2005.

  1. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    Hey. I'm working on an additive projector shader for my game. I'm going to try it as a fallback from pixel lit spotlights for car headlights. I've got something working but I'd like the effect to be more intense. (While staying within the fixed function pipeline) I may be tired or I just can't figure it out. :)

    The neat thing about it currently is that you can color the "light" texture.

    I admit that I do not completely understand how the projector shaders work. What is the definition of "fresnel", here?

    Thanks,
    -Jon

    edit: put in nicholas' fog fix

    Code (csharp):
    1.  
    2. SHADER "Projector/Projector Additive" {
    3.     Properties {
    4.         _ShadowTex ("Cookie", 2D) = "fresnel.png" {
    5.             TexGen ObjectLinear    
    6.         }
    7.         _FalloffTex ("FallOff", 2D) = "fresnel.png" {
    8.             TexGen ObjectLinear
    9.         }
    10.     }
    11.  
    12.     SUBSHADER {
    13.         Pass {
    14.             ZWrite off
    15.             Offset -1, -1
    16.            
    17.             Fog { Color (0,0,0,0) }
    18.             AlphaTest Greater 0
    19.             ColorMask RGB
    20.             // Get fresnel value into alpha. This is used in next stage.
    21.             blend DstColor SrcAlpha
    22.             SetTexture [_ShadowTex] {
    23.                 combine texture, ONE - texture
    24.                 Matrix [_Projector]
    25.             }
    26.             SetTexture [_FalloffTex] {
    27.                 constantColor (1,1,1,0)
    28.                 combine previous lerp (texture) constant
    29.                 Matrix [_ProjectorClip]
    30.             }
    31.         }
    32.     }
    33. }
    34.  
     

    Attached Files:

  2. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    More questions:

    Why the Offset -1, -1? And the Fog?
     
  3. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    The "fresnel.png" is a leftover from Unity 0.3 (or thereabouts). It is a default texture in case none is assigned... AFAIR the builtins are:
    "black", "white", "bump"... Now that you can assign textures to the shaders there's not a big reason for it.

    The Offset -1, -1 is to avoid any Z-fighting. It raises the depth of the rendered pixels (without altering their positions)

    The fog { Color (1,1,1,1) } makes the object fade to white as the distance increases. As this shader is multiplied in, that means the shadow fades to transparency as fog kicks in. Since you're doing an additive blend, you want to set fog color to black: Fog { Color (0,0,0,0) }[/b]
     
  4. Jonathan Czeck

    Jonathan Czeck

    Joined:
    Mar 17, 2005
    Posts:
    1,713
    So in the ShadowProjector shader:

    // Get fresnel value into alpha. This is used in next stage.

    Could be rephrased to:

    // Get texture value into alpha. This is used in next stage.

    ?

    As for the intensity, all I can think now is to add another pass, which would be a tad costly for my situation, I think. Think there is a way to do it in one? :D

    Thanks a lot,
    -Jon
     
  5. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    You have spare space in the first combiner. Try sth like this:

    Code (csharp):
    1.  
    2. SHADER "Projector/Projector Additive" {
    3.    Properties {
    4.       _Color ("Tint Color (RGB), Color) = (1,1,1,0)
    5.      _ShadowTex ("Cookie", 2D) = "fresnel.png" {
    6.         TexGen ObjectLinear    
    7.      }
    8.      _FalloffTex ("FallOff", 2D) = "fresnel.png" {
    9.         TexGen ObjectLinear    
    10.      }
    11.   }
    12.  
    13.   SUBSHADER {
    14.      Pass {
    15.         ZWrite off
    16.         Offset -1, -1
    17.          
    18.         Fog { Color (1,1,1) }
    19.         AlphaTest Greater 0
    20.         ColorMask RGB
    21.         // Get fresnel value into alpha. This is used in next stage.
    22.         blend DstColor SrcAlpha
    23.         SetTexture [_ShadowTex] {
    24.            combine constant * texture, ONE - texture
    25.            constantColor [_Color]
    26.            Matrix [_Projector]
    27.         }
    28.         SetTexture [_FalloffTex] {
    29.            constantColor (1,1,1,0)
    30.            combine previous lerp (texture) constant
    31.            Matrix [_ProjectorClip]
    32.         }
    33.      }
    34.   }
    35. }
    36.  
    Note: This is untested - but you can see the changes I made in the first combiner - multiplied in a constant color, which gets set from the _Color property I added above.

    Also, depending on which GFX card you target, you can have more than 2 combiners. Here are the caps:

    ATI Rage128, Geforce2, Geforce4MX: 2 combiners
    ATI Radeon7000, R7500: 3 combiners
    NVidia 3TI, 4 TI, any Geforce: 4 combiners
    ATI Radeon9000 or above: 6 combiners
     
  6. NicholasFrancis

    NicholasFrancis

    Joined:
    Apr 8, 2005
    Posts:
    1,587
    Looking at your blend set up, it looks a bit weird... You basically multiply your alpha with the existing color and then add in the color you calculated...

    I think you want Blend One One for a pure additive, or a Blend OneMinusSrcColor One for a softer look
     
  7. antenna-tree

    antenna-tree

    Joined:
    Oct 30, 2005
    Posts:
    5,324
    Hey aarku, any more updates to your additive projection shader? Custom Shaders are something I haven't even begun to get my head around yet, but the Blob Shadow in 1.2 got me excited about them.

    I'd really like to have some spotlight action in the game I'm working on. Any chance of putting your results up on the WIKI? :D