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: Code (csharp): 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: Code (csharp): 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.