How to use lightmaps from a custom shader?

I’m trying to write a custom shader that uses lightmaps. I’m able to sample the correct lightmap, but texture coordinates seem to be wrong.

Here’s an image of a test scene with built-in diffuse shaders:

Here’s what happens if I use my custom shader:

Below is my shader where I have tried to mimic the built-in diffuse shader and strip away unnecessary code. Any ideas on what I’m doing wrong?


    Shader "Custom/CustomDiffuse"
    {
    	Properties 
    	{
    		_MainTex ("Main Texture", 2D) = "white" {}
    	}
    
    	SubShader 
    	{
    		LOD 200
    
    		Tags 
    		{ 
    			"RenderType" = "Opaque" 
    			"Queue" = "Geometry" 
    		}
    		
    		Pass
    		{
    			Cull Off
    			Fog { Mode Off }
    			AlphaTest Off
    			Blend Off
    
    			CGPROGRAM
    			#pragma vertex vert
    			#pragma fragment frag
    			#pragma glsl_no_auto_normalization
    			#include "UnityCG.cginc"
    				
    			sampler2D _MainTex;
    			float4 _MainTex_ST;
    
    			sampler2D unity_Lightmap;
    			float4 unity_LightmapST;
    
    			struct Vertex
    			{
    				float4 vertex : POSITION;
    				float4 uv : TEXCOORD0;
    				float4 uv2 : TEXCOORD1;
    			};
    
    			struct Fragment
    			{
    				float4 vertex : POSITION;
    				float4 uv : TEXCOORD0;
    				float4 uv2 : TEXCOORD1;
    			};
    
    			Fragment vert(Vertex v)
    			{
    				Fragment o;
    
    				o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
    				o.uv.xy = v.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;
    				o.uv2.xy = v.uv2.xy * unity_LightmapST.xy + unity_LightmapST.zw;
    
    				return o;
    			}
    												
    			fixed4 frag(Fragment IN) : COLOR
    			{
    				fixed4 output = fixed4(0, 0, 0, 1);
    				
    				output.rgb = tex2D(_MainTex, IN.uv.xy).rgb;
    				output.rgb *= 2 * tex2D(unity_Lightmap, IN.uv2.xy).rgb;
    				
    				return saturate(output);
    			}
    			
    			ENDCG
    		}
    	}
    
    	Fallback Off
    }

I use this:

   c.rgb *= (DecodeLightmap(tex2D(unity_Lightmap, i.uv[1]))) * _Power;

Which I put in a multi pass:

         #pragma multi_compile LIGHTMAP_ON LIGHTMAP_OFF

#ifdef LIGHTMAP_ON

        	half4 unity_LightmapST;

        	sampler2D_half unity_Lightmap;

        #endif

@whydoidoit

I tried to use DecodeLightmap(), but it didn’t work, is multi-compile mandatory? if yes, where should I put the multi-compile?

here is the code snippet I have in my fragment function:

float2 LMUV = (INCOMING.uv + unity_LightmapST.zw) * unity_LightmapST.xy;

fixed4 LightmapPass0 = float4(DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap,LMUV)),1);,@whydoidoit

I saw this, and I tried DecodeLightmap() but it didn’t work, is multi-compile mandatory?

inside the fragment part of the shader, I have this:

float2 LMUV = (INCOMING.uv + unity_LightmapST.zw) * unity_LightmapST.xy;

fixed4 LightmapPass0 = float4(DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap,LMUV)),1);