Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Small mod for Stained Glass shader?

Discussion in 'Shaders' started by bigkahuna, Apr 18, 2008.

  1. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    The standard "Stained Glass" shader is pretty cool, but it creates the alpha transparency of the "tint" by using the level of "white" in the tint texture. The problem is that I cannot therefore use a "white" tint with this shader. Here's the original shader:
    Code (csharp):
    1.  
    2. // Per pixel bumped refraction.
    3. // Uses a normal map to distort the image behind, and
    4. // an additional texture to tint the color.
    5.  
    6. Shader "FX/Glass/Stained BumpDistort Light" {
    7. Properties {
    8.     _BumpAmt  ("Distortion", range (0,128)) = 10
    9.     _MainTex ("Tint Color (RGB)", 2D) = "white" {}
    10.     _BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
    11. }
    12.  
    13. Category {
    14.  
    15.     // We must be transparent, so other objects are drawn before this one.
    16.     Tags { "Queue" = "Transparent" }
    17.    
    18.     // ------------------------------------------------------------------
    19.     //  ARB fragment program
    20.    
    21.     SubShader {
    22.  
    23.         // This pass grabs the screen behind the object into a texture.
    24.         // We can access the result in the next pass as _GrabTexture
    25.         GrabPass {                         
    26.             Name "BASE"
    27.             Tags { "LightMode" = "Always" }
    28.         }
    29.        
    30.         // Main pass: Take the texture grabbed above and use the bumpmap to perturb it
    31.         // on to the screen
    32.         Pass {
    33.             Name "BASE"
    34.             Tags { "LightMode" = "Always" }
    35.            
    36. CGPROGRAM
    37. #pragma fragment frag
    38. #pragma fragmentoption ARB_precision_hint_fastest
    39. #pragma fragmentoption ARB_fog_exp2
    40.  
    41. samplerRECT _GrabTexture : register(s0);
    42. float4 _GrabTexture_TexelSize;
    43. sampler2D _BumpMap : register(s1);
    44. sampler2D _MainTex : register(s2);
    45.  
    46. struct v2f {
    47.     float4 uvgrab : TEXCOORD0;
    48.     float2 uvbump : TEXCOORD1;
    49.     float2 uvmain : TEXCOORD2;
    50. };
    51.  
    52. uniform float _BumpAmt;
    53.  
    54. half4 frag( v2f i ) : COLOR
    55. {
    56.     // calculate perturbed coordinates
    57.     half2 bump = tex2D( _BumpMap, i.uvbump ).rg * 2 - 1;
    58.     float2 offset = bump * _BumpAmt;
    59.     #ifdef SHADER_API_D3D9
    60.     offset *= _GrabTexture_TexelSize.xy;
    61.     #endif
    62.     i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
    63.    
    64.     half4 col = texRECTproj( _GrabTexture, i.uvgrab.xyw );
    65.     half4 tint = tex2D( _MainTex, i.uvmain );
    66.    
    67.     return col * tint;
    68. }
    69.  
    70. ENDCG
    71.             // Set up the textures for this pass
    72.             SetTexture [_GrabTexture] {}    // Texture we grabbed in the pass above
    73.             SetTexture [_BumpMap] {}        // Perturbation bumpmap
    74.             SetTexture [_MainTex] {}        // Color tint
    75.         }
    76.     }
    77.    
    78.     // ------------------------------------------------------------------
    79.     //  Radeon 9000
    80.    
    81.     SubShader {
    82.  
    83.         GrabPass {                         
    84.             Name "BASE"
    85.             Tags { "LightMode" = "Always" }
    86.         }
    87.        
    88.         Pass {
    89.             Name "BASE"
    90.             Tags { "LightMode" = "Always" }
    91.            
    92.             Program "" {
    93.                 SubProgram {
    94.                 Local 0, ([_BumpAmt],0,0,0.001)
    95. "!!ATIfs1.0
    96. StartConstants;
    97.     CONSTANT c0 = program.local[0];
    98. EndConstants;
    99.  
    100. StartPrelimPass;
    101.     PassTexCoord r0, t0.stq_dq; # refraction position
    102.     SampleMap r1, t1.str;       # bumpmap
    103.     MAD r0, r1.2x.bias, c0.r, r0;
    104. EndPass;
    105.  
    106. StartOutputPass;
    107.     SampleMap r0, r0.str;   # sample modified refraction texture
    108.     SampleMap r2, t2.str;       # Get main color texture
    109.    
    110.     MUL r0, r0, r2;
    111. EndPass;
    112. "
    113.                 }
    114.             }
    115.             SetTexture [_GrabTexture] {}
    116.             SetTexture [_BumpMap] {}
    117.             SetTexture [_MainTex] {}
    118.         }
    119.     }
    120.    
    121.     // ------------------------------------------------------------------
    122.     // Fallback for older cards and Unity non-Pro
    123.    
    124.     SubShader {
    125.         Blend DstColor Zero
    126.         Pass {
    127.             Name "BASE"
    128.             SetTexture [_MainTex] { combine texture }
    129.         }
    130.     }
    131. }
    132.  
    133. }
    This is my first attempt at modifying a shader and what I'd like to do is change this shader so that it uses the "black" level to determine the alpha transparency of the tint. Problem is, I can't find where this is taking place. Is this hard-coded in Unity or CG somehow?
     
  2. Aras

    Aras

    Unity Technologies

    Joined:
    Nov 7, 2005
    Posts:
    4,770
    It does not use the level of "white" in the texture; it uses the alpha channel of the texture. So just change the alpha channel of our texture (in your case, I guess you want to invert it).
     
  3. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    I don't think so. At first I thought that was the case, but the alpha channel doesn't seem to be picked up. Instead, it seems that the texture's white level is converted to an alpha channel.
     

    Attached Files:

  4. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Here is the result if I use a simple (no alpha channel) black on white texture. The white becomes transparent and the black is displayed. I'm trying to get the opposite effect (white displayed, black (or alpha channel) is transparent.
     

    Attached Files:

  5. ProtonOne

    ProtonOne

    Joined:
    Mar 8, 2008
    Posts:
    406
    It doesn't appear to really use the alpha directly. Just multiplies the background color by the tint (causing white to be transparent).

    Try changing this:
    Code (csharp):
    1.  
    2. return col * tint;
    To
    Code (csharp):
    1.  
    2. return lerp( col, tint, tint.a );
     
  6. bigkahuna

    bigkahuna

    Joined:
    Apr 30, 2006
    Posts:
    5,434
    Thanks, that seems to work perfectly!