Lightmapped/Bumped Specular in cg

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:

Shader "Customized Shaders/Lightmapped Bumped Specular Alpha" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 0)
	_Shininess ("Shininess", Range (0.01, 1)) = 0.078125
	_MainTex ("Base (RGB) TransGloss (A)", 2D) = "white" {}
	_BumpMap ("Bumpmap", 2D) = "bump" {}
	_LightMap ("Lightmap (RGB)", 2D) = "lightmap" {LightmapMode}
}

Category {
	AlphaToMask True
	ColorMask RGB
	Fog { Color [_AddFog] }
	Blend AppSrcAdd AppDstAdd
	
	// ------------------------------------------------------------------
	// ARB fragment program
	
	SubShader {
		UsePass "Transparent/Cutout/Specular/BASE"
		
		// Pixel lights
		Pass {
			Name "PPL"
			Tags { "LightMode" = "Pixel" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_builtin
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest

#include "UnityCG.cginc"
#include "AutoLight.cginc" 

struct appdata {
	float4 vertex : POSITION;
    float4 tangent : TANGENT;
	float3 normal : NORMAL;
	float4 texcoord : TEXCOORD0;
	float4 texcoord1 : TEXCOORD1;
};
					
struct v2f {
	V2F_POS_FOG;
	LIGHTING_COORDS
	float3	uvK; // xy = UV, z = specular K
	float2	uv2;
	float2 uv3;
	float3	viewDirT;
	float3	lightDirT;
}; 

uniform float4 _MainTex_ST, _BumpMap_ST, _LightMap_ST;
uniform float _Shininess;


v2f vert (appdata v)
{	
	v2f o;
	PositionFog( v.vertex, o.pos, o.fog );
	o.uvK.xy = TRANSFORM_TEX(v.texcoord,_MainTex);
	o.uvK.z = _Shininess * 128;
	o.uv2 = TRANSFORM_TEX(v.texcoord,_BumpMap);
	o.uv3 = TRANSFORM_TEX(v.texcoord1,_LightMap);	

	TANGENT_SPACE_ROTATION;
	o.lightDirT = mul( rotation, ObjSpaceLightDir( v.vertex ) );	
	o.viewDirT = mul( rotation, ObjSpaceViewDir( v.vertex ) );	

	
	TRANSFER_VERTEX_TO_FRAGMENT(o);
	return o;
}

uniform sampler2D _BumpMap;
uniform sampler2D _MainTex;
uniform sampler2D _LightMap;
uniform float4 _Color;

float4 frag (v2f i) : COLOR
{		
	float4 lightcol = tex2D( _LightMap, i.uv3 );
	float4 texcol = tex2D( _MainTex, i.uvK.xy );	
	texcol = texcol*lightcol + (texcol*_PPLAmbient*2*_Color);
	
	// get normal from the normal map
	float3 normal = tex2D(_BumpMap, i.uv2).xyz * 2 - 1;
	
	half4 c = SpecularLight( i.lightDirT, i.viewDirT, normal, texcol, i.uvK.z, LIGHT_ATTENUATION(i) );
	return c;
}
ENDCG  
		}
	}	
}

FallBack "Transparent/Cutout/VertexLit", 1

}

Any help is much appreciated!
Thanks

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.

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:

Shader "Customized Shaders/Bumped Specular" {
Properties {
	_Color ("Main Color", Color) = (1,1,1,1)
	_SpecColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1)
	_Shininess ("Shininess", Range (0.03, 1)) = 0.078125
	_MainTex ("Base (RGB) Gloss (A)", 2D) = "white" {}
	_BumpMap ("Bumpmap (RGB)", 2D) = "bump" {}
	_LightMap ("Lightmap (RGB)", 2D) = "black" {}
}

Category {
	Blend AppSrcAdd AppDstAdd
	Fog { Color [_AddFog] }
	
	// ------------------------------------------------------------------
	// ARB fragment program
	
	SubShader { 
		UsePass "Specular/BASE"
	
		// Ambient pass lightmap
		Pass {
			Name "BASE"
			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
			Color [_PPLAmbient]
			BindChannels {
				Bind "Vertex", vertex
				Bind "normal", normal
				Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
				Bind "texcoord", texcoord1 // main uses 1st uv
			}
			SetTexture [_LightMap] {
				constantColor [_Color]
				combine texture * constant
			}
			SetTexture [_MainTex] {
				constantColor [_Color]
				combine texture * previous, texture * constant
			}
		}
		
		// Vertex lights pass lightmap
		Pass {
			Name "BASE"
			Tags {"LightMode" = "Vertex"}
			Material {
				Diffuse [_Color]
				Shininess [_Shininess]
				Specular [_SpecColor]
			}

			Lighting On
			SeparateSpecular On

			BindChannels {
				Bind "Vertex", vertex
				Bind "normal", normal
				Bind "texcoord1", texcoord0 // lightmap uses 2nd uv
				Bind "texcoord1", texcoord1 // lightmap uses 2nd uv
				Bind "texcoord", texcoord2 // main uses 1st uv
			}
			
			SetTexture [_LightMap] {
				constantColor [_Color]
				combine texture * constant
			}
			SetTexture [_LightMap] {
				constantColor (0.5,0.5,0.5,0.5)
				combine previous * constant + primary
			}
			SetTexture [_MainTex] {
				combine texture * previous DOUBLE, texture * primary
			}
		}
		
		// Pixel lights
		Pass { 
			Name "PPL"	
			Tags { "LightMode" = "Pixel" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_builtin
#pragma fragmentoption ARB_fog_exp2
#pragma fragmentoption ARB_precision_hint_fastest 
#include "UnityCG.cginc"
#include "AutoLight.cginc" 

struct v2f {
	V2F_POS_FOG;
	LIGHTING_COORDS
	float3	uvK; // xy = UV, z = specular K
	float2	uv2;
	float2 	uv3;
	float3	viewDirT;
	float3	lightDirT;
}; 

uniform float4 _MainTex_ST, _BumpMap_ST,  _LightMap_ST;
uniform float _Shininess;


v2f vert (appdata_tan v)
{	
	v2f o;
	PositionFog( v.vertex, o.pos, o.fog );
	o.uvK.xy = TRANSFORM_TEX(v.texcoord, _MainTex);
	o.uvK.z = _Shininess * 128;
	o.uv2 = TRANSFORM_TEX(v.texcoord, _BumpMap);
	o.uv3 = TRANSFORM_TEX(v.texcoord, _LightMap);
	
	TANGENT_SPACE_ROTATION;
	o.lightDirT = mul( rotation, ObjSpaceLightDir( v.vertex ) );	
	o.viewDirT = mul( rotation, ObjSpaceViewDir( v.vertex ) );	

	TRANSFER_VERTEX_TO_FRAGMENT(o);	
	return o;
}

uniform sampler2D _BumpMap;
uniform sampler2D _MainTex;
uniform sampler2D _LightMap;
uniform float4 _Color;


float4 frag (v2f i) : COLOR
{		
	float4 texcol = tex2D( _MainTex, i.uvK.xy );
	float4 lightcol = tex2D( _LightMap, i.uv3 );
	lightcol = lightcol*_Color*0.5 + _PPLAmbient;
	
	// get normal from the normal map
	float3 normal = tex2D(_BumpMap, i.uv2).xyz * 2.0 - 1.0;
	
	half4 c = SpecularLight( i.lightDirT, i.viewDirT, normal, texcol, i.uvK.z, LIGHT_ATTENUATION(i) );
	c.rgb = c.rgb*lightcol.rgb*2;
	c.a = c.a*_PPLAmbient.a;
		
	return c;
}
ENDCG  
		}
	}
}

FallBack "Specular", 1

}

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.