Search Unity

Hacked the Pro Glass Refractive shader for grubby glass; sharing the source :)

Discussion in 'Shaders' started by Annihlator, Jan 31, 2014.

  1. Annihlator

    Annihlator

    Joined:
    Oct 15, 2012
    Posts:
    378
    Hey everyone,
    yesterday i had found a need for a Unity Pro Refractive shader which whould "understand" transparancy/alpha better (imho), i decided to hack the existing shader and after a very small round of cleanup am dumping the source online.

    Note, while this may have served purpose (i set the default values as i use them myself currently) for me in this scenario, i've added a LOAD of values to be changed.

    Changing the values of the three vectors will give you acces to likely whichever values you'll need adjusted to allow more light to flow through, be blocked or even make the transparancy ADDITIVE.

    The settings i'm using in my scene (for reference) are:

    Input settings:
    X: 0, Y: 1, Z: 1, W: 0.05;
    Output settings:
    X:0, Y:1, Z:1.5, W:0;
    Tweaks:
    X: 1; Y: 0.75, Z: 0, W: 0.35;

    Images used;
    Tint color/trans: http://static.dyp.im/9tGf0YEwAG/18502df2242dc92959a9262932d6e36b.png
    Normalmap;
    http://static.dyp.im/9mEbxMfc7q/3b0842537778fd5e360fdcc70ce0237c.png

    Both of these maps have been generated by myself in cinema4d and altered in GIMP.
    Non-commercial use is allowed by any means, please send me a small message to get in touch for any other or distributed use of the images.

    Now finally the shader;
    Code (csharp):
    1. // Per pixel bumped refraction.
    2. // Uses a normal map to distort the image behind, and
    3. // an additional texture to tint the color.
    4.  
    5. Shader "FX/Glass/Stained BumpDistort custom tz" {
    6. Properties {
    7.     _BumpAmt  ("Distortion", range (0,128)) = 10
    8.     _BumpAmt  ("Distortion", int) = 10
    9.     _MainTex ("Tint Color, transparency (RGBA)", 2D) = "white" {}
    10.     _BumpMap ("Normalmap", 2D) = "bump" {}
    11.     _InputFactor ("Input settings(clamp min,max / lerp max,min",Vector) = (0,1,0,1)
    12.     _OutputFactor ("Output settings(clamp min,max / lerp max,min",Vector) = (0,1,0,1)
    13.     _Transparencyfactor ("Tweaks: opacity effect on transparancy, maximum opacity, minimum effect, maximum effect",Vector) = (0,1,0,1)
    14. }
    15.  
    16. Category {
    17.  
    18.     // We must be transparent, so other objects are drawn before this one.
    19.     Tags { "Queue"="Transparent" "RenderType"="Opaque" }
    20.  
    21.  
    22.     SubShader {
    23.  
    24.         // This pass grabs the screen behind the object into a texture.
    25.         // We can access the result in the next pass as _GrabTexture
    26.         GrabPass {                         
    27.             Name "BASE"
    28.             Tags { "LightMode" = "Always" }
    29.         }
    30.        
    31.         // Main pass: Take the texture grabbed above and use the bumpmap to perturb it
    32.         // on to the screen
    33.         Pass {
    34.             Name "BASE"
    35.             Tags { "LightMode" = "Always" }
    36.            
    37. CGPROGRAM
    38. #pragma vertex vert
    39. #pragma fragment frag
    40. #pragma fragmentoption ARB_precision_hint_fastest
    41. #include "UnityCG.cginc"
    42.  
    43. struct appdata_t {
    44.     float4 vertex : POSITION;
    45.     float2 texcoord: TEXCOORD0;
    46. };
    47.  
    48. struct v2f {
    49.     float4 vertex : POSITION;
    50.     float4 uvgrab : TEXCOORD0;
    51.     float2 uvbump : TEXCOORD1;
    52.     float2 uvmain : TEXCOORD2;
    53. };
    54.  
    55. float _BumpAmt;
    56. float4 _BumpMap_ST;
    57. float4 _MainTex_ST;
    58. float4 _InputFactor;
    59. float4 _OutputFactor;
    60. float4 _Transparencyfactor;
    61.  
    62. v2f vert (appdata_t v)
    63. {
    64.     v2f o;
    65.     o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    66.     #if UNITY_UV_STARTS_AT_TOP
    67.     float scale = -1.0;
    68.     #else
    69.     float scale = 1.0;
    70.     #endif
    71.     o.uvgrab.xy = (float2(o.vertex.x, o.vertex.y*scale) + o.vertex.w) * 0.5;
    72.     o.uvgrab.zw = o.vertex.zw;
    73.     o.uvbump = TRANSFORM_TEX( v.texcoord, _BumpMap );
    74.     o.uvmain = TRANSFORM_TEX( v.texcoord, _MainTex );
    75.     return o;
    76. }
    77.  
    78. sampler2D _GrabTexture;
    79. float4 _GrabTexture_TexelSize;
    80. sampler2D _BumpMap;
    81. sampler2D _MainTex;
    82.  
    83. half4 frag( v2f i ) : COLOR
    84. {
    85.     // calculate perturbed coordinates
    86.     half2 bump = UnpackNormal(tex2D( _BumpMap, i.uvbump )).rg; // we could optimize this by just reading the x  y without reconstructing the Z
    87.     float2 offset = bump * _BumpAmt * _GrabTexture_TexelSize.xy;
    88.     i.uvgrab.xy = offset * i.uvgrab.z + i.uvgrab.xy;
    89.    
    90.     half4 col = tex2Dproj( _GrabTexture, UNITY_PROJ_COORD(i.uvgrab));
    91.     half4 tint = tex2D( _MainTex, i.uvmain );
    92.    
    93.     half4 input = lerp(_InputFactor.z,_InputFactor.w,clamp(1-tint.a,_InputFactor.x,_InputFactor.y));
    94.     half4 output = lerp(_OutputFactor.z,_OutputFactor.w,clamp(1-input.a,_OutputFactor.x,_OutputFactor.y));
    95.     half4 effector = lerp(_Transparencyfactor.w,_Transparencyfactor.z,1-tint.a*_Transparencyfactor.x);
    96.     //half4 effector = _Transparencyfactor.y*(clamp(lerp(_Transparencyfactor.w,_Transparencyfactor.z,1-tint.a),0,1));
    97.     //half4 trans = col*tint*effector-lerp(_Transparencyfactor.w,_Transparencyfactor.z,1-tint.a);
    98.     //half4 trans = col*tint* clamp(lerp(_Transparencyfactor.w,_Transparencyfactor.z,tint.a)*_Transparencyfactor.x,1-_Transparencyfactor.y,1);
    99.     //half4 trans = col*tint*tint.a;
    100.     //half4 trans = (col*tint)-(1-effector.a)*_Transparencyfactor.x;
    101.     half4 trans = 1;
    102.     trans.rgb = clamp((tint.rgb*col.rgb)-(effector/_Transparencyfactor.y*_Transparencyfactor.y),0,1);
    103.     //trans = trans-(1-(tint.a*_Transparencyfactor.y))*_Transparencyfactor.x;
    104.     //return trans+output.rgba*_Transparencyfactor.y;
    105.     //return trans+output.rgba*effector;
    106.     return trans+output.rgba*effector*(2*(1/_Transparencyfactor.x)+trans);
    107.     //return output.rgba;
    108.     //return trans;
    109.     //return effector;
    110. }
    111. ENDCG
    112.         }
    113.     }
    114.  
    115.     // ------------------------------------------------------------------
    116.     // Fallback for older cards and Unity non-Pro
    117.    
    118.     SubShader {
    119.         Blend DstColor Zero
    120.         Pass {
    121.             Name "BASE"
    122.             SetTexture [_MainTex] { combine texture }
    123.         }
    124.     }
    125. }
    126.  
    127. }
    128.  
    The code may be unoptimized, but i just wanted to give a starting point for those who found the standard refractive shader useless thanks to the lack of alpha ;) if i'll be bothered to improve my code i'll update the code here as well.
    Enjoy!

    (Btw, try some bloom effects, linear lighting and HDR with this shader ;) )
    Once i'm a bit further with my scene i'll dump the executables of that online in another thread :)