Hey, I have a question about shader writing in the Cg language.
I’m a little confused as to how this variable(_WorldSpaceLightPos0) works. In the docs, it says that it should return the direction when the light is set to directional, but otherwise, it should return a position.
And the direction works flawlessly. But when I switch my only light in the scene to a point light. I get all 0’s as values.
To debug this I simply return the _WorldSpaceLightPos0 in my fragment function. If it’s a directional light, I get colors, representing the direction. If it’s a point light, I get just black, no matter where I move the light.
I’m lost and have no idea how to fix this. Maybe I’m missing a line of code or something.
Here’s the full code for proof.
Shader "ShaderTest/LitBlinnPhong"
{
Properties
{
_MainTex("Texture", 2D) = "white" {}
_SurfaceColor("Surface Color", Color) = (1,1,1,1)
_Ambient("Ambient Light", Color) = (0,0,0,0)
_Gloss("Glossiness", Range(1, 10)) = 1
_RimPower("Rim Light", Range(0,1)) = 1
_Point("Point", Vector) = (0,0,0,0)
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
Tags { "LightMode" = "ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "UnityLightingCommon.cginc"
float _Gloss;
float _RimPower;
float4 _SurfaceColor;
float4 _Ambient;
float4 _Point;
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float3 worldNormal : COLOR0;
float3 viewDir : COLOR1;
float2 uv : TEXCOORD0;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = UnityObjectToWorldNormal(v.normal);
o.viewDir = WorldSpaceViewDir(v.vertex);
return o;
}
fixed4 frag(v2f i) : SV_Target
{
float4 lightCol = _LightColor0;
float3 n = normalize(i.worldNormal);
float3 v = normalize(i.viewDir);
float3 l = _WorldSpaceLightPos0.xyz;
float3 r = reflect(-l, n);
float3 h = normalize(l + v);
float3 lambert = float3(0, 0, 0);
float3 blinn = float3(0, 0, 0);
float3 fresnel = float3(0, 0, 0);
float lightDist = 1 - distance(_Point, i.worldNormal);
float atten = 1.0;
float gloss = _Gloss * _Gloss;
float roughness = _Gloss / 10;
if (_WorldSpaceLightPos0.w == 0)
{
lambert = clamp(dot(n, l), 0, 1);
blinn = pow(max(0, dot(h, n)), gloss) * lambert;
fresnel = clamp(1 - pow(dot(n, v), 0.5), 0, 1) * lambert;
}
else
{
//lightDist = distance(n, l);
//atten = 1 / lightDist;
//lambert = atten;
}
float4 lambertLight = float4(lambert, 1) * _SurfaceColor;
float4 blinnLight = float4(blinn, 1);
float4 fresnelLight = float4(fresnel, 1) * _RimPower * roughness;
//float4 light = (blinnLight + lambertLight + fresnelLight) * lightCol;
float4 light = float4(lambert, 1);
float4 color = float4(1, 1, 1, 1);
float4 col = color * lightDist;
return _WorldSpaceLightPos0;
}
ENDCG
}
}
}