_WorldSpaceLightPos0 giving no position information for point lights.

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
            }
        }
}
1 Like

did you solve the bug?

In this thread bgolus writes

Also if "LightMode"="ForwardBase" is true then the _WorldSpaceLightPos0 is always for a directional light, even if none exists in the scene. Only "LightMode"="ForwardAdd" has support for passing the position of point lights.

Is your light baked?