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

Lightmap as 2nd texture on UV2 for prefabs

Discussion in 'General Graphics' started by Volkerku, Jun 18, 2020.

  1. Volkerku

    Volkerku

    Joined:
    Nov 23, 2016
    Posts:
    113
    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.

    Thanks.

    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. }