Hi,
I went through the different examples of Nvidia Cg Tutorial and I’m trying to implement basic vertex diffuse lighting, for learning purposes.
Here’s the code :
Shader "Debug/SimpleVertex" {
Properties {
_Kd ("Diffuse",Color) = (0,1,0,0)
}
SubShader {
Pass {
//Name "Lighting On"
Tags { "LightMode" = "Pixel" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float4 _Kd;
void vert(float4 pos : POSITION, float4 normal : NORMAL,
out float4 oPos : POSITION, out float4 ocolor : COLOR) {
oPos = mul(glstate.matrix.mvp, pos);
float3 P = pos.xyz;
float3 N = normal;
float3 L = normalize(_ObjectSpaceLightPos0 - P);
//float3 L = normalize(glstate.light[0].position - P);
float diffuseLight = max(dot(N, L), 0);
float4 diffuse = _Kd * glstate.light[0].diffuse * diffuseLight;
ocolor.xyz = diffuse;
ocolor.w = 1;
}
void frag(float4 color : COLOR, out float4 ocolor : COLOR) {
ocolor = color;
}
ENDCG
}
}
}
It kinda works, but there are things I don’t understand.
1/ there’s a sphere and a plane (unity primitives) and a point light in my scene. If I scale the plane in any direction just a bit, it becomes black. The same happens with a cube, cylinder or capsule, but not with the sphere, which I can scale.
2/ the light is in auto render mode. If I move an object outside the range of the point light it dissapears (there’s still the wireframe but it’s fully transparent).
Docs say :
Pixel: Rendered once for each pixel light.
So that’s fine.
but if I switch to PixelOrNone, the objects are transparent when in range of the light and black when outside of the range. Even if the light is in “force pixel” render mode.
Docs say : PixelOrNone: Rendered if only pixel lights or no lights at all hit the object. Often used as an ambient pass.
So I would have guessed the objects get rendered when in range and black outside.
Further tests : PixelOnly: same result than Pixel. VertexAndPixel : objects transparent all the time.
Vertex and VertexOrPixel and VertexOrNone and VertexOnly: the lighting of the object is freezed and not affected by the light position, and when objects are out of range they become transparent.
The docs say : Vertex lights are rendered using “vertex” passes . All lights are rendered at once, using a fixed function OpenGL/Direct3D lighting model (Blinn-Phong). It is not possible to use vertex programs with vertex lights.
So the vertex and fragment program have no effect when in pixel mode, don’t really understand what I get for “VertexOrPixel” mode though.
3/ has the “Lighting On” line any effect when using cg code ?
4/ I tried using glstate.light[0].position but the shading was wrong, so I guess the position is not in world space. So I use _ObjectSpaceLightPos0 which I found in UnityCG.cginc, but there are no variables for the other lights and I’m not sure which matrix I should use to get glstate.light[1].position in the correct space.
Sorry for the lengthy post, thanks if you can clear things up.
I know I’m supposed to use the unity shaderlab stuff, but I’d like to understand the basics to build more complicated shader.
Thanks a lot
Vincent