Search Unity

Lightmapped/Bumped Specular in cg

Discussion in 'Shaders' started by devel, Mar 2, 2010.

  1. devel

    devel

    Joined:
    Mar 11, 2009
    Posts:
    140
    Hi everybody,

    I have started with shader programming. Currently I am trying to re-do existing Unity shaders but done in cg so i can compare the results.

    At the moment I am trying to implement Unitys Lightmapped/Bumped Specular shader in cg and the result (much darker) just wont look like Unitys result.

    I have tried many different combinations but it ll never look like Unitys result.

    I have found the equation of lightmapping here:
    http://forum.unity3d.com/viewtopic.php?t=33372&highlight=lightmap

    What am I doing wrong?

    Heres what I do:

    Code (csharp):
    1.  
    2. Shader "Customized Shaders/Lightmapped Bumped Specular Alpha" {
    3. Properties {
    4.     _Color ("Main Color", Color) = (1,1,1,1)
    5.     _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 0)
    6.     _Shininess ("Shininess", Range (0.01, 1)) = 0.078125
    7.     _MainTex ("Base (RGB) TransGloss (A)", 2D) = "white" {}
    8.     _BumpMap ("Bumpmap", 2D) = "bump" {}
    9.     _LightMap ("Lightmap (RGB)", 2D) = "lightmap" {LightmapMode}
    10. }
    11.  
    12. Category {
    13.     AlphaToMask True
    14.     ColorMask RGB
    15.     Fog { Color [_AddFog] }
    16.     Blend AppSrcAdd AppDstAdd
    17.    
    18.     // ------------------------------------------------------------------
    19.     // ARB fragment program
    20.    
    21.     SubShader {
    22.         UsePass "Transparent/Cutout/Specular/BASE"
    23.        
    24.         // Pixel lights
    25.         Pass {
    26.             Name "PPL"
    27.             Tags { "LightMode" = "Pixel" }
    28. CGPROGRAM
    29. #pragma vertex vert
    30. #pragma fragment frag
    31. #pragma multi_compile_builtin
    32. #pragma fragmentoption ARB_fog_exp2
    33. #pragma fragmentoption ARB_precision_hint_fastest
    34.  
    35. #include "UnityCG.cginc"
    36. #include "AutoLight.cginc"
    37.  
    38. struct appdata {
    39.     float4 vertex : POSITION;
    40.     float4 tangent : TANGENT;
    41.     float3 normal : NORMAL;
    42.     float4 texcoord : TEXCOORD0;
    43.     float4 texcoord1 : TEXCOORD1;
    44. };
    45.                    
    46. struct v2f {
    47.     V2F_POS_FOG;
    48.     LIGHTING_COORDS
    49.     float3  uvK; // xy = UV, z = specular K
    50.     float2  uv2;
    51.     float2 uv3;
    52.     float3  viewDirT;
    53.     float3  lightDirT;
    54. };
    55.  
    56. uniform float4 _MainTex_ST, _BumpMap_ST, _LightMap_ST;
    57. uniform float _Shininess;
    58.  
    59.  
    60. v2f vert (appdata v)
    61. {  
    62.     v2f o;
    63.     PositionFog( v.vertex, o.pos, o.fog );
    64.     o.uvK.xy = TRANSFORM_TEX(v.texcoord,_MainTex);
    65.     o.uvK.z = _Shininess * 128;
    66.     o.uv2 = TRANSFORM_TEX(v.texcoord,_BumpMap);
    67.     o.uv3 = TRANSFORM_TEX(v.texcoord1,_LightMap);  
    68.  
    69.     TANGENT_SPACE_ROTATION;
    70.     o.lightDirT = mul( rotation, ObjSpaceLightDir( v.vertex ) );   
    71.     o.viewDirT = mul( rotation, ObjSpaceViewDir( v.vertex ) ); 
    72.  
    73.    
    74.     TRANSFER_VERTEX_TO_FRAGMENT(o);
    75.     return o;
    76. }
    77.  
    78. uniform sampler2D _BumpMap;
    79. uniform sampler2D _MainTex;
    80. uniform sampler2D _LightMap;
    81. uniform float4 _Color;
    82.  
    83. float4 frag (v2f i) : COLOR
    84. {      
    85.     float4 lightcol = tex2D( _LightMap, i.uv3 );
    86.     float4 texcol = tex2D( _MainTex, i.uvK.xy );   
    87.     texcol = texcol*lightcol + (texcol*_PPLAmbient*2*_Color);
    88.    
    89.     // get normal from the normal map
    90.     float3 normal = tex2D(_BumpMap, i.uv2).xyz * 2 - 1;
    91.    
    92.     half4 c = SpecularLight( i.lightDirT, i.viewDirT, normal, texcol, i.uvK.z, LIGHT_ATTENUATION(i) );
    93.     return c;
    94. }
    95. ENDCG  
    96.         }
    97.     }  
    98. }
    99.  
    100. FallBack "Transparent/Cutout/VertexLit", 1
    101.  
    102. }

    Any help is much appreciated!
    Thanks
     
  2. Kragh

    Kragh

    Joined:
    Jan 22, 2008
    Posts:
    657
    First of all I think it's wrong to put your lightmapped calculations in as you have, as it will be done for each pixel light in your scene, instead of just one time in the ambient pass. So keep it within an ambient pass still. Second of all, if you look in the build in version, the lightmap is also multiplied on the ambient color, whereas here you are adding the ambient after the multiplication. So I see quite a few things that differs in your version, which would render the final result different.
     
  3. devel

    devel

    Joined:
    Mar 11, 2009
    Posts:
    140
    Thanks for answering Kragh. Please, would you give me some more specific help? I am fairly new (have read the docs) and I believe I have tried every possible way combination to make this work.

    Can you give me some programming details?

    I have tried to change my code in the way I believe you suggested me to.

    So heres what I do now:

    Code (csharp):
    1.  
    2. Shader "Customized Shaders/Bumped Specular" {
    3. Properties {
    4.     _Color ("Main Color", Color) = (1,1,1,1)
    5.     _SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
    6.     _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
    7.     _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
    8.     _BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
    9.     _LightMap ("Lightmap (RGB)", 2D) = "black" {}
    10. }
    11.  
    12. Category {
    13.     Blend AppSrcAdd AppDstAdd
    14.     Fog { Color [_AddFog] }
    15.    
    16.     // ------------------------------------------------------------------
    17.     // ARB fragment program
    18.    
    19.     SubShader {
    20.         UsePass "Specular/BASE"
    21.    
    22.         // Ambient pass lightmap
    23.         Pass {
    24.             Name "BASE"
    25.             Tags {"LightMode" = "None"} // I have changed this from PixelOrNone to None since I guess the pixel rendering will be done twice for the 2 Pixel passes
    26.             Color [_PPLAmbient]
    27.             BindChannels {
    28.                 Bind "Vertex", vertex
    29.                 Bind "normal", normal
    30.                 Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
    31.                 Bind "texcoord", texcoord1 // main uses 1st uv
    32.             }
    33.             SetTexture [_LightMap] {
    34.                 constantColor [_Color]
    35.                 combine texture * constant
    36.             }
    37.             SetTexture [_MainTex] {
    38.                 constantColor [_Color]
    39.                 combine texture * previous, texture * constant
    40.             }
    41.         }
    42.        
    43.         // Vertex lights pass lightmap
    44.         Pass {
    45.             Name "BASE"
    46.             Tags {"LightMode" = "Vertex"}
    47.             Material {
    48.                 Diffuse [_Color]
    49.                 Shininess [_Shininess]
    50.                 Specular [_SpecColor]
    51.             }
    52.  
    53.             Lighting On
    54.             SeparateSpecular On
    55.  
    56.             BindChannels {
    57.                 Bind "Vertex", vertex
    58.                 Bind "normal", normal
    59.                 Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
    60.                 Bind "texcoord1", texcoord1 // lightmap uses 2nd uv
    61.                 Bind "texcoord", texcoord2 // main uses 1st uv
    62.             }
    63.            
    64.             SetTexture [_LightMap] {
    65.                 constantColor [_Color]
    66.                 combine texture * constant
    67.             }
    68.             SetTexture [_LightMap] {
    69.                 constantColor (0.5,0.5,0.5,0.5)
    70.                 combine previous * constant + primary
    71.             }
    72.             SetTexture [_MainTex] {
    73.                 combine texture * previous DOUBLE, texture * primary
    74.             }
    75.         }
    76.        
    77.         // Pixel lights
    78.         Pass {
    79.             Name "PPL" 
    80.             Tags { "LightMode" = "Pixel" }
    81. CGPROGRAM
    82. #pragma vertex vert
    83. #pragma fragment frag
    84. #pragma multi_compile_builtin
    85. #pragma fragmentoption ARB_fog_exp2
    86. #pragma fragmentoption ARB_precision_hint_fastest
    87. #include "UnityCG.cginc"
    88. #include "AutoLight.cginc"
    89.  
    90. struct v2f {
    91.     V2F_POS_FOG;
    92.     LIGHTING_COORDS
    93.     float3  uvK; // xy = UV, z = specular K
    94.     float2  uv2;
    95.     float2  uv3;
    96.     float3  viewDirT;
    97.     float3  lightDirT;
    98. };
    99.  
    100. uniform float4 _MainTex_ST, _BumpMap_ST,  _LightMap_ST;
    101. uniform float _Shininess;
    102.  
    103.  
    104. v2f vert (appdata_tan v)
    105. {  
    106.     v2f o;
    107.     PositionFog( v.vertex, o.pos, o.fog );
    108.     o.uvK.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
    109.     o.uvK.z = _Shininess * 128;
    110.     o.uv2 = TRANSFORM_TEX(v.texcoord, _BumpMap);
    111.     o.uv3 = TRANSFORM_TEX(v.texcoord, _LightMap);
    112.    
    113.     TANGENT_SPACE_ROTATION;
    114.     o.lightDirT = mul( rotation, ObjSpaceLightDir( v.vertex ) );   
    115.     o.viewDirT = mul( rotation, ObjSpaceViewDir( v.vertex ) ); 
    116.  
    117.     TRANSFER_VERTEX_TO_FRAGMENT(o);
    118.     return o;
    119. }
    120.  
    121. uniform sampler2D _BumpMap;
    122. uniform sampler2D _MainTex;
    123. uniform sampler2D _LightMap;
    124. uniform float4 _Color;
    125.  
    126.  
    127. float4 frag (v2f i) : COLOR
    128. {      
    129.     float4 texcol = tex2D( _MainTex, i.uvK.xy );
    130.     float4 lightcol = tex2D( _LightMap, i.uv3 );
    131.     lightcol = lightcol*_Color*0.5 + _PPLAmbient;
    132.    
    133.     // get normal from the normal map
    134.     float3 normal = tex2D(_BumpMap, i.uv2).xyz * 2.0 - 1.0;
    135.    
    136.     half4 c = SpecularLight( i.lightDirT, i.viewDirT, normal, texcol, i.uvK.z, LIGHT_ATTENUATION(i) );
    137.     c.rgb = c.rgb*lightcol.rgb*2;
    138.     c.a = c.a*_PPLAmbient.a;
    139.        
    140.     return c;
    141. }
    142. ENDCG  
    143.         }
    144.     }
    145. }
    146.  
    147. FallBack "Specular", 1
    148.  
    149. }
    150.  
    I have tried to re-program the calculations as used in the Lightmap/Vertex Lit shader (Vertex Pass combinations added to Pixel Pass as calculations).
    And added the Ambient and Vertex Pass from the Lightmap.