- Home /
CG diffuse shader
Hi there,
I've written a CG shader that's meant as an overlay on top of the existing material, ie: you have your base diffuse/specular/whatever material and then drop my shader material on top. It works great for normal meshes. Problem I have is I need to do this for the terrain as well... At the moment I've written a basic CG version of the terrain shader but I can't seem to copy the lighting of Unity's diffuse surface shader exactly in a CG shader. Could someone point me in the right direction to find a simple diffuse shader written in CG? Or is there an easier way to combine my CG shader with Unity's terrain surface shader? Obviously it would be easier if I could have my shader as a second pass on a replacement terrain shader rather than having to re-write the terrain shader in CG.
Help is much appreciated! :)
Answer by whydoidoit · Apr 12, 2013 at 08:44 AM
Here's my CG terrain shader:
Shader "Custom/Terrain" {
Properties {
_Splat0 ("Layer 1 (R)", 2D) = "white" {}
_Splat1 ("Layer 2 (G)", 2D) = "white" {}
_Splat2 ("Layer 3 (B)", 2D) = "white" {}
_Splat3 ("Layer 4 (A)", 2D) = "white" {}
_Control ("Control (RGBA)", 2D) = "white" {}
_MainTex ("Never Used", 2D) = "white" {}
}
SubShader {
Tags {
"SplatCount" = "4"
"Queue" = "Geometry-100"
"RenderType" = "Opaque"
}
Pass {
ZTest LEqual
Lighting on
ZWrite on
CGPROGRAM
// Upgrade NOTE: excluded shader from DX11 and Xbox360; has structs without semantics (struct v2f members lightDirection)
#pragma exclude_renderers d3d11 xbox360
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D_half _Splat0;
sampler2D_half _Splat1;
sampler2D_half _Splat2;
sampler2D_half _Splat3;
sampler2D_half _Control;
half4 _Splat0_ST;
half4 _Splat1_ST;
half4 _Splat2_ST;
half4 _Splat3_ST;
half4 _Control_ST;
struct a2v
{
half4 vertex : POSITION;
half3 normal : NORMAL;
half4 texcoord : TEXCOORD0;
};
struct v2f
{
fixed4 pos : SV_POSITION;
half2 uv : TEXCOORD0;
half2 uv0 : TEXCOORD1;
half2 uv1 : TEXCOORD2;
half2 uv2 : TEXCOORD3;
half2 uv3 : TEXCOORD4;
fixed4 light : TEXCOORD5;
};
v2f vert (a2v v)
{
v2f o;
o.pos = mul( UNITY_MATRIX_MVP, v.vertex);
o.uv = TRANSFORM_TEX (v.texcoord, _Control);
o.uv0 = TRANSFORM_TEX (v.texcoord, _Splat0);
o.uv1 = TRANSFORM_TEX (v.texcoord, _Splat1);
o.uv2 = TRANSFORM_TEX (v.texcoord, _Splat2);
o.uv3 = TRANSFORM_TEX (v.texcoord, _Splat3);
fixed3 toLight = normalize(unity_LightPosition[0].xyz);
fixed3 lightColor = saturate(
UNITY_LIGHTMODEL_AMBIENT.rgb
+ (unity_LightColor[0].rgb *
(dot( normalize( mul( (float3x3) UNITY_MATRIX_IT_MV, v.normal)), toLight.xyz ))));
o.light = fixed4(lightColor * 2,1) ;
return o;
}
fixed4 frag(v2f i) : COLOR
{
fixed4 c = tex2D (_Control, i.uv);
fixed3 c1 = tex2D (_Splat0, i.uv0);
fixed3 c2 = tex2D (_Splat1, i.uv1);
fixed3 c3 = tex2D (_Splat2, i.uv2);
fixed3 c4 = tex2D (_Splat3, i.uv3);
return fixed4(((c1.rgb * c.r) + (c2.rgb * c.g) + (c3.rgb * c.b) + (c4.rgb * c.a)), 1) * i.light;
}
ENDCG
}
}
FallBack "Diffuse"
}
The diffuse calculation is for one directional light only and is shown in the line that won't format properly no matter what I do. And the lines before and after it.