just have a look at this shader.
although it has some bugs it might be helpful.
bugs:
- it produces artifacts: some kind of bright glow around the texture edge where the geometry receives shadows. i guess it is some kind of alpha blending issue… but using just a single pass should work correctely
- backface does not get written into the shadow map’s depth buffer
see: http://forum.unity3d.com/viewtopic.php?t=40440
Shader "Hidden/TerrainEngine/Details/Vertexlit" {
Properties {
// we get no color?
_Color ("Main Color", Color) = (1,1,1,1)
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
_Cutoff ("Alpha cutoff", Range(0,1)) = 0.5
}
Category {
Tags {"RenderType"="TransparentCutout"}
LOD 200
Alphatest Greater [_Cutoff]
AlphaToMask True
ColorMask RGB
Blend AppSrcAdd AppDstAdd
Cull Off
// ------------------------------------------------------------------
// ARB fragment program
SubShader {
// Ambient pass
Pass {
Name "BASE"
Tags {"LightMode" = "PixelOrNone"}
Color [_PPLAmbient]
SetTexture [_MainTex] {constantColor [_Color] Combine texture * primary DOUBLE, texture * primary}
}
// Vertex lights
// not supported?
/*
Pass {
Name "BASE"
Tags {"LightMode" = "Vertex"}
Lighting On
Material {
Diffuse [_Color]
Emission [_PPLAmbient]
}
SetTexture [_MainTex] {combine texture * primary DOUBLE, texture * primary}
}
*/
// Pixel lights
Pass {
Name "PPL"
Tags { "LightMode" = "Pixel" }
Fog { Color [_AddFog] }
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
#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
float2 uv;
float3 normal;
float3 lightDir;
float3 vertex;
};
uniform float4 _MainTex_ST;
v2f vert (appdata_base v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
//Viewdir in object space
// see: [url]http://forum.unity3d.com/viewtopic.php?t=12015[/url]
float3 ovd = v.vertex.xyz - _ObjectSpaceCameraPos;
float dp = dot(ovd, v.normal);
//If viewdir is same direction-ish as normal, flip it.
o.normal = v.normal * -sign(dp);
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
o.lightDir = ObjSpaceLightDir( v.vertex );
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
uniform sampler2D _MainTex;
uniform float4 _Color;
float4 frag (v2f i) : COLOR
{
half4 texcol = tex2D( _MainTex, i.uv );
// its is not written to the shadowmap correctely...
#ifndef USING_DIRECTIONAL_LIGHT
i.lightDir = normalize(i.lightDir);
#endif
// original lighting
//half c = DiffuseLight( i.lightDir, i.normal, texcol, LIGHT_ATTENUATION(i) );
half diffuse = dot( i.normal, i.lightDir );
/// lighting hack: some baselight + diffuse lighting * x
diffuse = 0.4 + diffuse * 0.35;
half4 c;
c.rgb = texcol.rgb * _ModelLightColor0.rgb * (diffuse * LIGHT_ATTENUATION(i) * 2);
//c.a = 0; // diffuse passes by default don't contribute to overbright
c.a = texcol.a * _Color.a;
//c.a = texcol.a;
return c;
}
ENDCG
SetTexture [_MainTex] {combine texture}
SetTexture [_LightTexture0] {combine texture}
SetTexture [_LightTextureB0] {combine texture}
}
/// end 1st pass
/// 2nd pass
Pass {
Name "PPL2"
Tags { "LightMode" = "Pixel" }
// Only render pixels less or equal to the value
AlphaTest LEqual [_Cutoff]
// Set up alpha blending
Blend SrcAlpha OneMinusSrcAlpha
// Dont write to the depth buffer
ZWrite Off
SetTexture [_MainTex] { constantColor [_Color] Combine texture * constant, texture * constant}
}
/// end 2nd pass
}
// ------------------------------------------------------------------
// Radeon 9000
SubShader {
// Ambient pass
Pass {
Name "BASE"
Tags {"LightMode" = "PixelOrNone"}
Color [_PPLAmbient]
SetTexture [_MainTex] {constantColor [_Color] Combine texture * primary DOUBLE, texture * constant}
}
// Vertex lights
Pass {
Name "BASE"
Tags {"LightMode" = "Vertex"}
Lighting On
Material {
Diffuse [_Color]
Emission [_PPLAmbient]
}
SetTexture [_MainTex] {Combine texture * primary DOUBLE, texture * primary}
}
// Pixel lights with 0 light textures
Pass {
Name "PPL"
Tags {
"LightMode" = "Pixel"
"LightTexCount" = "0"
}
CGPROGRAM
#pragma vertex vert
#include "UnityCG.cginc"
struct v2f {
V2F_POS_FOG;
float2 uv : TEXCOORD0;
float3 normal : TEXCOORD1;
float3 lightDir : TEXCOORD2;
};
uniform float4 _MainTex_ST;
v2f vert(appdata_base v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
o.normal = v.normal;
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
o.lightDir = ObjSpaceLightDir( v.vertex );
return o;
}
ENDCG
Program "" {
SubProgram {
Local 0, [_ModelLightColor0]
Local 1, [_Color]
"!!ATIfs1.0
StartConstants;
CONSTANT c0 = program.local[0];
CONSTANT c1 = program.local[1];
EndConstants;
StartOutputPass;
SampleMap r0, t0.str; # main texture
SampleMap r1, t2.str; # normalized light dir
PassTexCoord r2, t1.str; # normal
DOT3 r5.sat, r2, r1.2x.bias; # R5 = diffuse (N.L)
MUL r0.rgb, r0, r5;
MUL r0.rgb.2x, r0, c0;
MUL r0.a, r0, c1;
EndPass;
"
}
}
SetTexture[_MainTex] {combine texture}
SetTexture[_CubeNormalize] {combine texture}
}
// Pixel lights with 1 light texture
Pass {
Name "PPL"
Tags {
"LightMode" = "Pixel"
"LightTexCount" = "1"
}
CGPROGRAM
#pragma vertex vert
#include "UnityCG.cginc"
uniform float4 _MainTex_ST;
uniform float4x4 _SpotlightProjectionMatrix0;
struct v2f {
V2F_POS_FOG;
float2 uv : TEXCOORD0;
float3 normal : TEXCOORD1;
float3 lightDir : TEXCOORD2;
float4 LightCoord0 : TEXCOORD3;
};
v2f vert(appdata_tan v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
o.normal = v.normal;
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
o.lightDir = ObjSpaceLightDir( v.vertex );
o.LightCoord0 = mul(_SpotlightProjectionMatrix0, v.vertex);
return o;
}
ENDCG
Program "" {
SubProgram {
Local 0, [_ModelLightColor0]
Local 1, [_Color]
"!!ATIfs1.0
StartConstants;
CONSTANT c0 = program.local[0];
CONSTANT c1 = program.local[1];
EndConstants;
StartOutputPass;
SampleMap r0, t0.str; # main texture
SampleMap r1, t2.str; # normalized light dir
PassTexCoord r4, t1.str; # normal
SampleMap r2, t3.str; # a = attenuation
DOT3 r5.sat, r4, r1.2x.bias; # R5 = diffuse (N.L)
MUL r0.rgb, r0, r5;
MUL r0.rgb.2x, r0, c0;
MUL r0.rgb, r0, r2.a; # attenuate
MUL r0.a, r0, c1;
EndPass;
"
}
}
SetTexture[_MainTex] {combine texture}
SetTexture[_CubeNormalize] {combine texture}
SetTexture[_LightTexture0] {combine texture}
}
// Pixel lights with 2 light textures
Pass {
Name "PPL"
Tags {
"LightMode" = "Pixel"
"LightTexCount" = "2"
}
CGPROGRAM
#pragma vertex vert
#include "UnityCG.cginc"
uniform float4 _MainTex_ST;
uniform float4x4 _SpotlightProjectionMatrix0;
uniform float4x4 _SpotlightProjectionMatrixB0;
struct v2f {
V2F_POS_FOG;
float2 uv : TEXCOORD0;
float3 normal : TEXCOORD1;
float3 lightDir : TEXCOORD2;
float4 LightCoord0 : TEXCOORD3;
float4 LightCoordB0 : TEXCOORD4;
};
v2f vert(appdata_tan v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
o.normal = v.normal;
o.uv = TRANSFORM_TEX(v.texcoord,_MainTex);
o.lightDir = ObjSpaceLightDir( v.vertex );
o.LightCoord0 = mul(_SpotlightProjectionMatrix0, v.vertex);
o.LightCoordB0 = mul(_SpotlightProjectionMatrixB0, v.vertex);
return o;
}
ENDCG
Program "" {
SubProgram {
Local 0, [_ModelLightColor0]
Local 1, [_Color]
"!!ATIfs1.0
StartConstants;
CONSTANT c0 = program.local[0];
CONSTANT c1 = program.local[1];
EndConstants;
StartOutputPass;
SampleMap r0, t0.str; # main texture
SampleMap r1, t2.str; # normalized light dir
PassTexCoord r4, t1.str; # normal
SampleMap r2, t3.stq_dq; # a = attenuation 1
SampleMap r3, t4.stq_dq; # a = attenuation 2
DOT3 r5.sat, r4, r1.2x.bias; # R5 = diffuse (N.L)
MUL r0.rgb, r0, r5;
MUL r0.rgb.2x, r0, c0;
MUL r0.rgb, r0, r2.a; # attenuate
MUL r0.rgb, r0, r3.a;
MUL r0.a, r0, c1;
EndPass;
"
}
}
SetTexture[_MainTex] {combine texture}
SetTexture[_CubeNormalize] {combine texture}
SetTexture[_LightTexture0] {combine texture}
SetTexture[_LightTextureB0] {combine texture}
}
}
// ------------------------------------------------------------------
// Radeon 7000
Category {
Material {
Diffuse [_Color]
Emission [_PPLAmbient]
}
Lighting On
Cull Off
SubShader {
Pass {
Name "BASE"
Tags {"LightMode" = "PixelOrNone"}
Color [_PPLAmbient]
Lighting Off
SetTexture [_MainTex] {Combine texture * primary DOUBLE}
SetTexture [_MainTex] {Combine texture * primary DOUBLE}
SetTexture [_MainTex] {Combine texture * primary DOUBLE, primary * texture}
}
Pass {
Name "BASE"
Tags {"LightMode" = "Vertex"}
SetTexture [_MainTex] {Combine texture * primary DOUBLE, primary * texture}
}
Pass {
Name "PPL"
Tags {
"LightMode" = "Pixel"
"LightTexCount" = "2"
}
SetTexture [_LightTexture0] { combine previous * texture alpha, previous }
SetTexture [_LightTextureB0] {
combine previous * texture alpha + constant, previous
constantColor [_PPLAmbient]
}
SetTexture [_MainTex] { combine previous * texture DOUBLE, primary * texture}
}
Pass {
Name "PPL"
Tags {
"LightMode" = "Pixel"
"LightTexCount" = "1"
}
SetTexture [_LightTexture0] {
combine previous * texture alpha + constant, previous
constantColor [_PPLAmbient]
}
SetTexture [_MainTex] { combine previous * texture DOUBLE, primary * texture}
}
Pass {
Name "PPL"
Tags {
"LightMode" = "Pixel"
"LightTexCount" = "0"
}
SetTexture [_MainTex] { combine previous * texture DOUBLE, primary * texture}
}
}
}
}
Fallback "Transparent/Cutout/VertexLit", 2
}