I’m trying to do a simple vertex shader with my own weirdo lighting but I can’t get it working. In the example below I simply use the built-in functions to calculate the lighting but it seems the view- and light-directions are just wrong, e.g. not really in object-space.
In my scene I have a single spot-light.
Am I missing something obvious in this shader:
SubShader {
Pass {
Tags { "LightMode" = "VertexOrNone" }
CGPROGRAM
#pragma vertex vert
#pragma multi_compile_builtin_noshadows
#include "UnityCG.cginc"
#include "AutoLight.cginc"
struct v2f {
V2F_POS_FOG;
float4 color : COLOR0;
float4 uv : TEXCOORD0;
};
uniform float _Shininess;
v2f vert (appdata_base v)
{
v2f o;
PositionFog( v.vertex, o.pos, o.fog );
float3 lightDir = ObjSpaceLightDir(v.vertex);
float3 viewDir = ObjSpaceViewDir(v.vertex);
float atten = 1.0;
o.color = SpecularLight(lightDir,viewDir,v.normal,float4(1,1,1,1),_Shininess,atten);
o.uv = v.texcoord;
return o;
}
ENDCG
SetTexture [_MainTex] { combine Texture * Primary }
}
}
Here is a simple vertex lit shader:
Shader "Simple Vertex Lit"
{
SubShader
{
Pass
{
Lighting On
Material
{
Diffuse (1, 1, 1, 1)
Ambient (1, 1, 1, 1)
}
}
}
}
Funny 
The point is that I need a different lighting equation so the fixed-function won’t do. I got it all working using a pixel-shader as well, but I need it done using just a vertex-shader.
Why do you think it is wrong?
Where do you set the light coords for the object and the vertex normal?
I only see that you setup the passes to use the light data but you don’t setup the light which is used.
(Normal-Diffuse.shader from the built-in shader pack you can download in the resource section shows that, especially in conjunction with the spotlight transformation matrix)
I’m not sure if any light but the “sun” will just work without first defining its existance and coordinates.
here for example 178-201 from said shader:
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
Disclaimer: I might all be wrong but from my understanding so far, you have to tell your shaders to use a given amount of lights or not use them in their calculation. This gives great flexibility on the optimization end.
I tried this shader but it doesn’t work. My object turns black.
I have this shader and it works OK:
SubShader {
Pass {
Name "BASE"
Tags {
"LightMode" = "Vertex"
}
Lighting On
SeperateSpecular On
Material {
Diffuse (1,1,1,1)
Ambient (1,1,1,1)
Shininess [_Shininess]
Specular [_SpecColor]
Emission [_Emission]
}
SetTexture [_MainTex] { combine Texture lerp(Texture) constant constantColor [_PaintColor] }
SetTexture [_MainTex] { combine Primary * Previous }
}
}
But I need a different lighting calculation. So I thought I could replace this part:
Lighting On
SeperateSpecular On
Material {
Diffuse (1,1,1,1)
Ambient (1,1,1,1)
Shininess [_Shininess]
Specular [_SpecColor]
Emission [_Emission]
}
with something like this:
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
but that doesn’t work. The object is just black. Is this something that should/could work and I’m just missing some magic tag or keyword somewhere or is this not a normal approach to the problem?