Search Unity

Help with building diffuse + normal + specular/+color/+gloss + AO shader

Discussion in 'Shaders' started by Demian-Wright, Jun 5, 2013.

  1. Demian-Wright

    Demian-Wright

    Joined:
    Jun 5, 2013
    Posts:
    2
    I'm just starting out with Unity and I was quite surprised to find out that Unity (free version) doesn't ship with this shader. I'm in need of a shader that uses the following texture maps:
    • Diffuse
    • Normal
    • Ambient occlusion
    • Specular
    • Specular hardness/gloss map
    • Specular color
    I found Strumpy Shader Editor and managed to do most of these with it but I'm having trouble with the specular color map as well as the ambient occlusion. Below is the shader I made with the shader editor.
    Code (csharp):
    1. Shader "RealShader"
    2. {
    3.     Properties
    4.     {
    5. _diffuse("Diffuse map", 2D) = "gray" {}
    6. _normal("Normal map", 2D) = "bump" {}
    7. _specularhardness("Specular hardness map", 2D) = "white" {}
    8. _specular("Specular power map", 2D) = "white" {}
    9.  
    10.     }
    11.    
    12.     SubShader
    13.     {
    14.         Tags
    15.         {
    16. "Queue"="Geometry"
    17. "IgnoreProjector"="False"
    18. "RenderType"="Opaque"
    19.  
    20.         }
    21.  
    22.        
    23. Cull Back
    24. ZWrite On
    25. ZTest LEqual
    26. ColorMask RGBA
    27. Fog{
    28. }
    29.  
    30.  
    31.         CGPROGRAM
    32. #pragma surface surf BlinnPhongEditor  vertex:vert
    33. #pragma target 3.0
    34.  
    35.  
    36. sampler2D _diffuse;
    37. sampler2D _normal;
    38. sampler2D _specularhardness;
    39. sampler2D _specular;
    40.  
    41.             struct EditorSurfaceOutput {
    42.                 half3 Albedo;
    43.                 half3 Normal;
    44.                 half3 Emission;
    45.                 half3 Gloss;
    46.                 half Specular;
    47.                 half Alpha;
    48.                 half4 Custom;
    49.             };
    50.            
    51.             inline half4 LightingBlinnPhongEditor_PrePass (EditorSurfaceOutput s, half4 light)
    52.             {
    53. half3 spec = light.a * s.Gloss;
    54. half4 c;
    55. c.rgb = (s.Albedo * light.rgb + light.rgb * spec);
    56. c.a = s.Alpha;
    57. return c;
    58.  
    59.             }
    60.  
    61.             inline half4 LightingBlinnPhongEditor (EditorSurfaceOutput s, half3 lightDir, half3 viewDir, half atten)
    62.             {
    63.                 half3 h = normalize (lightDir + viewDir);
    64.                
    65.                 half diff = max (0, dot ( lightDir, s.Normal ));
    66.                
    67.                 float nh = max (0, dot (s.Normal, h));
    68.                 float spec = pow (nh, s.Specular*128.0);
    69.                
    70.                 half4 res;
    71.                 res.rgb = _LightColor0.rgb * diff;
    72.                 res.w = spec * Luminance (_LightColor0.rgb);
    73.                 res *= atten * 2.0;
    74.  
    75.                 return LightingBlinnPhongEditor_PrePass( s, res );
    76.             }
    77.            
    78.             struct Input {
    79.                 float2 uv_diffuse;
    80. float2 uv_normal;
    81. float2 uv_specularhardness;
    82. float2 uv_specular;
    83.  
    84.             };
    85.  
    86.             void vert (inout appdata_full v, out Input o) {
    87. float4 VertexOutputMaster0_0_NoInput = float4(0,0,0,0);
    88. float4 VertexOutputMaster0_1_NoInput = float4(0,0,0,0);
    89. float4 VertexOutputMaster0_2_NoInput = float4(0,0,0,0);
    90. float4 VertexOutputMaster0_3_NoInput = float4(0,0,0,0);
    91.  
    92.  
    93.             }
    94.            
    95.  
    96.             void surf (Input IN, inout EditorSurfaceOutput o) {
    97.                 o.Normal = float3(0.0,0.0,1.0);
    98.                 o.Alpha = 1.0;
    99.                 o.Albedo = 0.0;
    100.                 o.Emission = 0.0;
    101.                 o.Gloss = 0.0;
    102.                 o.Specular = 0.0;
    103.                 o.Custom = 0.0;
    104.                
    105. float4 Tex2D0=tex2D(_diffuse,(IN.uv_diffuse.xyxy).xy);
    106. float4 Tex2D1=tex2D(_normal,(IN.uv_normal.xyxy).xy);
    107. float4 UnpackNormal0=float4(UnpackNormal(Tex2D1).xyz, 1.0);
    108. float4 Tex2D2=tex2D(_specularhardness,(IN.uv_specularhardness.xyxy).xy);
    109. float4 Tex2D3=tex2D(_specular,(IN.uv_specular.xyxy).xy);
    110. float4 Master0_2_NoInput = float4(0,0,0,0);
    111. float4 Master0_5_NoInput = float4(1,1,1,1);
    112. float4 Master0_7_NoInput = float4(0,0,0,0);
    113. float4 Master0_6_NoInput = float4(1,1,1,1);
    114. o.Albedo = Tex2D0;
    115. o.Normal = UnpackNormal0;
    116. o.Specular = Tex2D2;
    117. o.Gloss = Tex2D3;
    118.  
    119.                 o.Normal = normalize(o.Normal);
    120.             }
    121.         ENDCG
    122.     }
    123.     Fallback "Diffuse"
    124. }
    125.  
    I have no idea how I would add the ambient occlusion texture to that. It only needs to have the diffuse texture be multiplied (as in the math function) by the AO texture.

    Below is a specular + specular color + normal shader I found on the forums. I would somehow need to combine the specular color part with the shader above but I have no clue how to.

    Code (csharp):
    1. Shader "Bumped Color Specular" {
    2. Properties {
    3.     _Color ("Main Color", Color) = (1,1,1,1)
    4.     _Shininess ("Shininess", Range (0.03, 1)) = 0.078125
    5.     _MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
    6.     _BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
    7.     _SpecMap ("Spec map (RGB)", 2D) = "white" {}
    8. }
    9.  
    10. Category {
    11.     Blend AppSrcAdd AppDstAdd
    12.     Fog { Color [_AddFog] }
    13.     Tags { "RenderType"="Opaque" }
    14.    
    15.     SubShader {
    16.         // Ambient pass
    17.         Pass {
    18.             Name "BASE"
    19.             Tags {"LightMode" = "PixelOrNone"}
    20.             Blend AppSrcAdd AppDstAdd
    21.             Color [_PPLAmbient]
    22.             SetTexture [_MainTex] {constantColor [_Color] Combine texture * primary DOUBLE, texture * constant}
    23.         }
    24.        
    25.         // Vertex lights
    26.         Pass {
    27.             Name "BASE"
    28.             Tags {"LightMode" = "Vertex"}
    29.             Lighting On
    30.             Material {
    31.                 Diffuse [_Color]
    32.                 Emission [_PPLAmbient]
    33.             }
    34.  
    35. CGPROGRAM
    36. #pragma fragment frag
    37. #pragma fragmentoption ARB_fog_exp2
    38. #pragma fragmentoption ARB_precision_hint_fastest
    39.  
    40. #include "UnityCG.cginc"
    41.  
    42. uniform sampler2D _MainTex;
    43.  
    44. half4 frag (v2f_vertex_lit i) : COLOR {
    45.     return VertexLight( i, _MainTex );
    46. }
    47. ENDCG
    48.         }
    49.        
    50.         // Pixel lights
    51.         Pass {
    52.             Name "PPL"    
    53.             Tags { "LightMode" = "Pixel" }
    54. CGPROGRAM
    55. #pragma vertex vert
    56. #pragma fragment frag
    57. #pragma multi_compile_builtin
    58. #pragma fragmentoption ARB_fog_exp2
    59. #pragma fragmentoption ARB_precision_hint_fastest
    60. #include "UnityCG.cginc"
    61. #include "AutoLight.cginc"
    62.  
    63. struct v2f {
    64.     V2F_POS_FOG;
    65.     LIGHTING_COORDS
    66.     float3    uvK; // xy = UV, z = specular K
    67.     float4    uv2; // bumpmap UV, specmap UV
    68.     float3    viewDirT;
    69.     float3    lightDirT;
    70. };
    71.  
    72. uniform float4 _MainTex_ST, _BumpMap_ST, _SpecMap_ST;
    73. uniform float _Shininess;
    74.  
    75.  
    76. v2f vert (appdata_tan v)
    77. {    
    78.     v2f o;
    79.     PositionFog( v.vertex, o.pos, o.fog );
    80.     o.uvK.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
    81.     o.uvK.z = _Shininess * 128;
    82.     o.uv2.xy = TRANSFORM_TEX(v.texcoord, _BumpMap);
    83.     o.uv2.zw = TRANSFORM_TEX(v.texcoord, _SpecMap);
    84.  
    85.     TANGENT_SPACE_ROTATION;
    86.     o.lightDirT = mul( rotation, ObjSpaceLightDir( v.vertex ) );    
    87.     o.viewDirT = mul( rotation, ObjSpaceViewDir( v.vertex ) );    
    88.  
    89.     TRANSFER_VERTEX_TO_FRAGMENT(o);    
    90.     return o;
    91. }
    92.  
    93. uniform sampler2D _BumpMap;
    94. uniform sampler2D _MainTex;
    95. uniform sampler2D _SpecMap;
    96. uniform float4 _LightColor0;
    97.  
    98. // Calculates Blinn-Phong (specular) lighting model
    99. inline half4 SpecularColorLight( half3 lightDir, half3 viewDir, half3 normal, half4 color, half4 specColor, float specK, half atten )
    100. {
    101.     #ifndef USING_DIRECTIONAL_LIGHT
    102.     lightDir = normalize(lightDir);
    103.     #endif
    104.     viewDir = normalize(viewDir);
    105.     half3 h = normalize( lightDir + viewDir );
    106.    
    107.     half diffuse = dot( normal, lightDir );
    108.    
    109.     float nh = saturate( dot( h, normal ) );
    110.     float spec = pow( nh, specK ) * color.a;
    111.    
    112.     half4 c;
    113.     c.rgb = (color.rgb * _ModelLightColor0.rgb * diffuse + _LightColor0.rgb * specColor.rgb * spec) * (atten * 2);
    114.     c.a = _LightColor0.a * specColor.a * spec * atten; // specular passes by default put highlights to overbright
    115.     return c;
    116. }
    117.  
    118.  
    119. half4 frag (v2f i) : COLOR
    120. {        
    121.     half4 texcol = tex2D( _MainTex, i.uvK.xy );
    122.     half4 speccol = tex2D( _SpecMap, i.uv2.zw );
    123.     float3 normal = tex2D(_BumpMap, i.uv2.xy).xyz * 2.0 - 1.0;
    124.    
    125.     half4 c = SpecularColorLight( i.lightDirT, i.viewDirT, normal, texcol, speccol, i.uvK.z, LIGHT_ATTENUATION(i) );
    126.     return c;
    127. }
    128. ENDCG  
    129.         }
    130.     }    
    131. }
    132.  
    133. FallBack "Diffuse"
    134.  
    135. }
    I'm essentially asking if someone who actually knows this shader script could combine the specular color to my shader and add in the ambient occlusion part.
     
    Last edited: Jun 7, 2013
  2. RC-1290

    RC-1290

    Joined:
    Jul 2, 2012
    Posts:
    639
    Have you tried the Ambient Occlusion Image Effect?
    If you only need static ambient occlusion per object, you could calculate ambient occlusion in your modeling program and add it to the diffuse texture before importing it into Unity.


    By the way, creating a shader that combines functionality from two other shaders isn't just "help", it's doing the work for you.
     
  3. Demian-Wright

    Demian-Wright

    Joined:
    Jun 5, 2013
    Posts:
    2
    I've decided to bake the ambient occlusion into the diffuse since that's essentially what I wanted in the first place.

    I suppose so. I just can't make heads or tails of this shader script.
     
  4. Annihlator

    Annihlator

    Joined:
    Oct 15, 2012
    Posts:
    378