However, the documentation seems to be outdated because when i tried using the values:
_ModelLightColor[0], _ObjectSpaceLightPos[0]
I got undefined variable error.
After digging into UnityCG.cginc I found unity_LightPosition[0] &unity_LightColor[0] variables which did the trick.
Here is an example of a basic per-vertex diffuse lighting Shader that accepts a texture and an ambient color inputs and adds one light calculations:
Shader "Custom/Per-Vertex diffuse" {
Properties {
_MainTex ("Texture 1", 2D) = "white" {}
_Ambient("Ambient Color",Color) = (0.3,0.3,0.3,1)
}
SubShader {
Tags { "RenderType"="Opaque"}
Pass {
Tags { "LightMode" = "Vertex" }//otherwise no light related values will be filled
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
fixed4 _Ambient;
half4 _MainTex_ST;
struct v2f{
fixed4 position: POSITION;
half2 uv_MainTex:TEXCOORD0;
fixed4 color: COLOR;
};
v2f vert (appdata_base ab) {
v2f o;
o.position = mul(UNITY_MATRIX_MVP,ab.vertex);
o.uv_MainTex = TRANSFORM_TEX(ab.texcoord.xy , _MainTex);
// per vertex light calc
fixed3 lightDirection;
fixed attenuation;
// add diffuse
if(unity_LightPosition[0].w == 0.0)//directional light
{
attenuation = 2;
lightDirection = normalize(mul(unity_LightPosition[0],UNITY_MATRIX_IT_MV).xyz);
}
else// point or spot light
{
lightDirection = normalize(mul(unity_LightPosition[0],UNITY_MATRIX_IT_MV).xyz - ab.vertex.xyz);
attenuation = 1.0/(length(mul(unity_LightPosition[0],UNITY_MATRIX_IT_MV).xyz - ab.vertex.xyz)) * 0.5;
}
fixed3 normalDirction = normalize(ab.normal);
fixed3 diffuseLight = unity_LightColor[0].xyz * max(dot(normalDirction,lightDirection),0);
// combine the lights (diffuse + ambient)
o.color.xyz = diffuseLight * attenuation + _Ambient.xyz;
return o;
}
fixed4 frag(v2f i):COLOR{
fixed4 c = tex2D(_MainTex, i.uv_MainTex);
return c * i.color;
}
ENDCG
}
}
Fallback "Mobile/Diffuse"
}
To learn about the math of differnt types of lighting I recommend Nvidia's Tutorial for CG shaders
No comments:
Post a Comment