Search Unity

Lightmap as 2nd texture on UV2 for prefabs

Discussion in 'Shaders' started by Volkerku, Jun 18, 2020.

  1. Volkerku

    Volkerku

    Joined:
    Nov 23, 2016
    Posts:
    114
    Working through this great Unity blog post Using light-baked prefabs on mobile devices I got everything working in principle. However the shader which applys the lightmap texture to UV2 does way more then I need it to do. It also calculates specular.
    I'm a shader newby, can anyone pls help with simplifying this shader so it only takes a base texture, a color value and the lightmap texture. I want it to be very cheap to render.

    Thnaks.

    Code (CSharp):
    1. Shader "Custom/LightmappedPrefabWithSpec"
    2. {
    3.   Properties
    4.   {
    5.     _MainTex("Base (RGB)", 2D) = "white" {}
    6.     _Lightmap("Lightmap", 2D) = "white" {}
    7.     _Specmap("Specmap", 2D) = "white" {}
    8.     _SpecularAtt("Glossiness", Range(0.1, 2)) = 0.5
    9.     _SpecularAmt("Specular", Range(0, 1)) = 0.5
    10.   }
    11.  
    12.   SubShader
    13.   {
    14.     Tags{ "Queue" = "Geometry+1" }
    15.     Pass
    16.     {
    17.       CGPROGRAM
    18.  
    19.       // Defining the name of the vertex shader
    20.       #pragma vertex vert
    21.  
    22.       // Defining the name of the fragment shader
    23.       #pragma fragment frag
    24.  
    25.  
    26.       // Include some common helper functions,
    27.       // specifically UnityObjectToClipPos and DecodeLightmap.
    28.       #include "UnityCG.cginc"
    29.  
    30.       // Color Diffuse Map
    31.       sampler2D _MainTex;
    32.       // Tiling/Offset for _MainTex, used by TRANSFORM_TEX in vertex shader
    33.       float4 _MainTex_ST;
    34.  
    35.  
    36.       // Lightmap (created via Unity Lightbaking)
    37.       sampler2D _Lightmap;
    38.       // Tiling/Offset for _Lightmap, used by TRANSFORM_TEX in vertex shader
    39.       float4 _Lightmap_ST;
    40.  
    41.       // Grayscale Map indicating which parts of the models have specular
    42.       // Note: _Specmap_ST is not needed, as this map is using the same
    43.       // UVs as for the _MainTex.
    44.       sampler2D _Specmap;
    45.  
    46.       // This is the vertex shader input: position, UV0, UV1, normal
    47.       // UV1 (= second UV channel) needed for the lightmap texture coordinates
    48.       struct appdata
    49.       {
    50.         float4 vertex   : POSITION;
    51.         float2 texcoord : TEXCOORD0;
    52.         float2 texcoord1: TEXCOORD1;
    53.         float3 normal: NORMAL;
    54.       };
    55.  
    56.       // This is the data passed from the vertex to fragment shader
    57.       struct v2f
    58.       {
    59.         float4 pos  : SV_POSITION; // position of the pixel
    60.         float2 txuv : TEXCOORD0; // for accessing the diffuse color map
    61.         float2 lmuv : TEXCOORD1; // for accessing the light map
    62.         float3 normalDir : TEXCOORD2; // for fake specular
    63.       };
    64.  
    65.       // This is the vertext shader, doing nothing special at all.
    66.       // Most notably it is calculating the surface normal, because that
    67.       // is needed for the fake specular lighting in the fragment shader.
    68.       v2f vert(appdata v)
    69.       {
    70.         v2f o;
    71.         o.pos = UnityObjectToClipPos(v.vertex);
    72.         o.txuv = TRANSFORM_TEX(v.texcoord.xy, _MainTex); // using _MainTex_ST
    73.         o.lmuv = TRANSFORM_TEX(v.texcoord1.xy, _Lightmap); // using _Lightmap_ST
    74.  
    75.         // Calculating the normal of the vertex for the fragment shader
    76.         float4x4 modelMatrixInverse = unity_WorldToObject;
    77.         o.normalDir = normalize(mul(float4(v.normal, 0.0), modelMatrixInverse).xyz);
    78.  
    79.         return o;
    80.       }
    81.  
    82.       uniform float _SpecularAtt;
    83.       uniform float _SpecularAmt;
    84.  
    85.       // Fragment Shader
    86.       half4 frag(v2f i) : COLOR
    87.       {
    88.         // Reading color directly from the diffuse texture, using first UV channel
    89.         half4 col = tex2D(_MainTex, i.txuv.xy);
    90.         // Reading specular (on/off) value from spec map texture
    91.         half4 specVal = tex2D(_Specmap, i.txuv.xy);
    92.         // Reading lightmap value from the lightmap texture
    93.         half4 lm = tex2D(_Lightmap, i.lmuv.xy);
    94.  
    95.         // Fake specular light angle calculation with a hard-coded light direction
    96.         half3 th = normalize(half3(0, 1, -0.25));
    97.         float spec = max(0, dot(i.normalDir, th));
    98.  
    99.         // Adjusting by overall specular amount and glossyness (material parameters)
    100.         spec = _SpecularAmt * pow(spec, 40.0 * _SpecularAtt);
    101.         // We're just using red value of the specular texture, like a grayscale map,
    102.         // although technically spec could be colored.
    103.         // Example: float3 specCol = specVal * spec;
    104.         spec = spec * specVal.r;
    105.  
    106.         // Calculating the final color of the pixel by bringing it all together
    107.         col.rgb = min(half4(1,1,1,1), col.rgb * DecodeLightmap(lm) + col.rgb * spec);
    108.         return col;
    109.       }
    110.       ENDCG
    111.     }
    112.   }
    113.   Fallback "Diffuse"
    114. }