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

A reflective shader which takes two cube maps + alpha too control strength

Discussion in 'Shaders' started by uk, Jul 14, 2013.

  1. uk

    uk

    Joined:
    Apr 8, 2013
    Posts:
    14
    Is it possible to modify, for example the "bumped unlit" shader to take 2 cube maps instead of one. And have some kind of alpha map to control the strength?
    I don't really know much about shader programming. so it would be awesome if someone more knowledgeable in writing shaders could tell me:

    1. How would you go about doing this?, is there any special place in the shader docs I should look at?

    2. Is it gonna be too complicated for someone who never wrote a shader before?, I don't really have the time to spend several days/weeks to read up about shader programming just to get started :)

    Thanks!
     
  2. brianasu

    brianasu

    Joined:
    Mar 9, 2010
    Posts:
    369
    Here you go I just hacked the built in shaders. I would start by reading the shaderlab documents and writing surface shaders. Shaders are not an easy concept to grasp at the start. Took me a year to learn a lot.
    If you want to do a custom shader I suggest you start simpler with a 1 color shader. Bumped shaders require knowledge of tangent space matrices.

    I suggest you use the built in shaders or visual shader editors to help develop them.


    Code (csharp):
    1. Shader "Reflective/Bumped Unlit 2 Cubemaps" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _ReflectColor ("Reflection Color", Color) = (1,1,1,0.5)
    5.    
    6.     _MainTex ("Base (RGB), RefStrength (A)", 2D) = "white" {}
    7.     _BumpMap ("Normalmap", 2D) = "bump" {}
    8.    
    9.     _AlphaControlMap ("Blend Texture (A)", 2D) = "white" {} //<-- Controls stength using alpha channel a bit of a waste since rgb not used
    10.    
    11.     _CubeA ("Reflection Cubemap A", Cube) = "" { TexGen CubeReflect } //<--
    12.     _CubeB ("Reflection Cubemap B", Cube) = "" { TexGen CubeReflect } //<--
    13. }
    14.  
    15. Category {
    16.     Tags { "RenderType"="Opaque" }
    17.     LOD 250
    18.    
    19.     // ------------------------------------------------------------------
    20.     // Shaders
    21.  
    22.     SubShader {
    23.         // Always drawn reflective pass
    24.         Pass {
    25.             Name "BASE"
    26.             Tags {"LightMode" = "Always"}
    27. CGPROGRAM
    28. #pragma vertex vert
    29. #pragma fragment frag
    30. #pragma fragmentoption ARB_precision_hint_fastest
    31.  
    32. #include "UnityCG.cginc"
    33.  
    34. struct v2f {
    35.     float4 pos : SV_POSITION;
    36.     float2  uv      : TEXCOORD0;
    37.     float2  uv2     : TEXCOORD1;
    38.     float2  uv3     : TEXCOORD2;
    39.     float3  I       : TEXCOORD3;
    40.     float3  TtoW0   : TEXCOORD4;
    41.     float3  TtoW1   : TEXCOORD5;
    42.     float3  TtoW2   : TEXCOORD6;
    43. };
    44.  
    45. uniform float4 _MainTex_ST, _BumpMap_ST, _AlphaControlMap_ST;
    46.  
    47. v2f vert(appdata_tan v)
    48. {
    49.     v2f o;
    50.     o.pos = mul (UNITY_MATRIX_MVP, v.vertex);
    51.     o.uv =  TRANSFORM_TEX(v.texcoord,_MainTex);
    52.     o.uv2 = TRANSFORM_TEX(v.texcoord,_BumpMap);
    53.     o.uv3 = TRANSFORM_TEX(v.texcoord,_AlphaControlMap);
    54.    
    55.     o.I = -WorldSpaceViewDir( v.vertex );
    56.    
    57.     TANGENT_SPACE_ROTATION;
    58.     o.TtoW0 = mul(rotation, _Object2World[0].xyz * unity_Scale.w);
    59.     o.TtoW1 = mul(rotation, _Object2World[1].xyz * unity_Scale.w);
    60.     o.TtoW2 = mul(rotation, _Object2World[2].xyz * unity_Scale.w);
    61.    
    62.     return o;
    63. }
    64.  
    65. sampler2D _BumpMap;
    66. sampler2D _MainTex;
    67. sampler2D _AlphaControlMap;
    68.  
    69. samplerCUBE _CubeA;
    70. samplerCUBE _CubeB;
    71.  
    72. fixed4 _ReflectColor;
    73. fixed4 _Color;
    74.  
    75. fixed4 frag (v2f i) : COLOR
    76. {
    77.     // Sample and expand the normal map texture
    78.     fixed3 normal = UnpackNormal(tex2D(_BumpMap, i.uv2));
    79.    
    80.     fixed4 texcol = tex2D(_MainTex,i.uv);
    81.    
    82.     // transform normal to world space
    83.     half3 wn;
    84.     wn.x = dot(i.TtoW0, normal);
    85.     wn.y = dot(i.TtoW1, normal);
    86.     wn.z = dot(i.TtoW2, normal);
    87.    
    88.     // calculate reflection vector in world space
    89.     half3 r = reflect(i.I, wn);
    90.    
    91.     fixed4 c = UNITY_LIGHTMODEL_AMBIENT * texcol;
    92.     c.rgb *= 2;
    93.  
    94.     fixed4 reflcolorA = texCUBE(_CubeA, r) * _ReflectColor * texcol.a; //<-- Cube Map A
    95.     fixed4 reflcolorB = texCUBE(_CubeB, r) * _ReflectColor * texcol.a; //<-- Cube Map B
    96.  
    97.     fixed lerpValue = tex2D(_AlphaControlMap, i.uv3).a; //<-- Value in alpha channel controls strength
    98.  
    99.     return c + lerp(reflcolorA, reflcolorB, lerpValue); // <-- blend between _CubeA and _CubeB
    100. }
    101. ENDCG  
    102.         }
    103.     }
    104.    
    105.     // ------------------------------------------------------------------
    106.     //  No vertex or fragment programs
    107.    
    108.     SubShader {
    109.         Pass {
    110.             Tags {"LightMode" = "Always"}
    111.             Name "BASE"
    112.             BindChannels {
    113.                 Bind "Vertex", vertex
    114.                 Bind "Normal", normal
    115.             }
    116.             SetTexture [_Cube] {
    117.                 constantColor [_ReflectColor]
    118.                 combine texture * constant
    119.             }
    120.         }
    121.     }
    122. }
    123.    
    124. FallBack "VertexLit", 1
    125.  
    126. }
     
  3. uk

    uk

    Joined:
    Apr 8, 2013
    Posts:
    14
    Wow, thats really nice of you, thank you so much :)...Gonna try this out!