Problem with cg lighting


I’m trying to do some basic lighting on my texture splatted geomipterrain.

The texture splatting works fine, and so does the ambient light, but I can’t get Panda to recognise the directional light.

Here’s the code where I setup the shader:

tAlphaTexture = loader.loadTexture("assets/terrainalpha.png")
        t0Texture = loader.loadTexture("assets/earthrough.jpg")
        t1Texture = loader.loadTexture("assets/grass.jpg")
        t2Texture = loader.loadTexture("assets/rockgrassy.jpg")
        t3Texture = loader.loadTexture("assets/groundplants.jpg")
        terrainShader = Shader.load("")

        # add lights for shader
        # four textures and an alpha map for the texture splatter

And here’s the shader

void vshader( in float4 vtx_position    : POSITION,
              in float3 vtx_normal      : NORMAL,
              in float2 vtx_texcoord0   : TEXCOORD0,
      in uniform float4x4 mat_modelproj,
             out float2 l_texcoord0      : TEXCOORD0,
             out float2 l_texcoord1      : TEXCOORD1,
             out float3 l_texcoord2      : TEXCOORD2, // object position
             out float3 l_texcoord3      : TEXCOORD3, // normal
             out float4 l_position       : POSITION)
    l_texcoord0 = vtx_texcoord0*20;
    l_texcoord1 = vtx_texcoord0;
    l_texcoord2 =;
    l_texcoord3 = vtx_normal;

void fshader( in float2 l_texcoord0 : TEXCOORD0,
              in float2 l_texcoord1 : TEXCOORD1,
              in float3 l_texcoord2 : TEXCOORD2, // object position
              in float3 l_texcoord3 : TEXCOORD3, // normal
              in float4 l_position  : POSITION,
      in uniform float4x4 dlight_dlight,
      in uniform float4 alight_alight,
      in uniform sampler2D tex_0  : TEXUNIT0,
      in uniform sampler2D tex_1  : TEXUNIT1,
      in uniform sampler2D tex_2  : TEXUNIT2,
      in uniform sampler2D tex_3  : TEXUNIT3,
      in uniform sampler2D tex_4  : TEXUNIT4,
             out float4 o_color     : COLOR )
    // calculate texture
    float4 tex0=tex2D(tex_0,l_texcoord0);
    float4 tex1=tex2D(tex_1,l_texcoord0);
    float4 tex2=tex2D(tex_2,l_texcoord0);
    float4 tex3=tex2D(tex_3,l_texcoord0);
    float4 alpha=tex2D(tex_4,l_texcoord1);
    o_color =tex0;
    // calculate lighting
    float3 P =;  
    float3 N = normalize(l_texcoord3); 
    // ambient term
    float3 ambient =;

    // rest is commented out for now

When I run this I get the following error:

:gobj(error): Keyword 'to' or 'rel' expected (uniform in float4x4 dlight_dlight)

Anybody have any ideas?

      in uniform float4x4 dlight_dlight,
      in uniform float4 alight_alight, 

is wrong.

In my shader i do

     in uniform float4 mspos_sun  ,
     in uniform float4 mspos_light1 ,
     in uniform float4 mspos_light2 ,
     in uniform float4 mspos_light3 ,

mspos_ mean model space coordinates.

there is many different prifixes to get what you want see manual but dlight_ is not right.

treeform, alight_ and dlight_ are correct prefixes. alight_ contains the color of the ambient light, and dlight_ contains a matrix with the color as first row, specular as second row, third row is modelspace direction, and the fourth row is the model-space ‘pseudo half-angle’.

hmm i was wrong then.

Well I can manage without it and do it treeform’s way. Thanks for your help.

I am however, still curious to know why it doesn’t work - perhaps there is a mistake in the manual?

I’ve investigated it a bit more and it appears to be a bug in the code. Or, in the manual.
Looking at the code, it appears to expect something like slight_blah_rel_clip_of_blah or alight_blah_to_world or something similar. Which doesn’t make much sense – you don’t want them relative to anything.
Can you try something like dlight_dlight_to_world, just to keep the parser happy?

I’m not sure whether it’s actually a bug in the manual (and the to_blah is needed) or someone just copied&pasted too much in the code, so I won’t fix it yet. Perhaps drwr knows more about this?

Hmmm, I’ll try it out tomorrow. I assume this will have to be done when I add the shader input, rather than in the shader itself.

To be honest I wasn’t entirely sure what I was going to do with the contents of the matrix anyway. Obviously the “psuedo half angle” is not the actual half angle for each vertex, but I’m not entirely sure how to use the normal to compute the true half angle. I was planning to do a bit of experimentation to work this out. “pseudo half angle” is not a term I have come across before, so any help in that regard would be appreciated also.

Actually, I know very little about this system. This was designed and implemented by Josh.


OK, I reread the manual pages. At least I now understand how to get my dlight. Now I just need to work out how to use the stored data - or give up and do it the usual way. :slight_smile:

For intructional purposes I printed out the shader generated for a node with one ambient light and one directional light to see how the dlight matrix is supposed to be used. Here is the result:

void vshader(
	 in float4 vtx_color : COLOR,
	 out float4 l_color : COLOR,
	 uniform float4x4 trans_model_to_view,
	 uniform float4x4 tpose_view_to_model,
	 in float4 vtx_normal : TEXCOORD0,
	 out float4 l_normal : TEXCOORD1,
	 out float4 l_pos : TEXCOORD0,
	 float4 vtx_position : POSITION,
	 out float4 l_position : POSITION,
	 uniform float4x4 mat_modelproj
) {
	 l_position = mul(mat_modelproj, vtx_position);
	 l_color = vtx_color;
	 l_pos = mul(trans_model_to_view, vtx_position); = mul((float3x3)tpose_view_to_model,;
	 l_normal.w = 0;

void fshader(
	 in float3 l_normal : TEXCOORD1,
	 in float4 l_pos : TEXCOORD0,
	 uniform float4 alight_alight0,
	 uniform float4x4 dlight_dlight0_rel_view,
	 uniform float4x4 attr_material,
	 uniform float4 row1_view_to_model,
	 out float4 o_color : COLOR0,
	 in float4 l_color : COLOR
) {
	 float4 result;
	 // Fetch all textures.
	 // Correct the surface normal for interpolation effects
	 l_normal = normalize(l_normal);
	 // Begin view-space light calculations
	 float ldist,lattenv,langle;
	 float4 lcolor,lspec,lvec,lpoint,latten,ldir,leye,lhalf;
	 float4 tot_ambient = float4(0,0,0,0);
	 float4 tot_diffuse = float4(0,0,0,0);
	 float4 tot_specular = float4(0,0,0,0);
	 float shininess = attr_material[3].w;
	 // Ambient Light 0
	 lcolor = alight_alight0;
	 tot_ambient += lcolor;
	 // Directional Light 0
	 lcolor = dlight_dlight0_rel_view[0];
	 lspec  = dlight_dlight0_rel_view[1];
	 lvec   = dlight_dlight0_rel_view[2];
	 lcolor *= saturate(dot(l_normal,;
	 tot_diffuse += lcolor;
	 lhalf = dlight_dlight0_rel_view[3];
	 lspec *= pow(saturate(dot(l_normal,, shininess);
	 tot_specular += lspec;
	 // Begin view-space light summation
	 result = float4(0,0,0,0);
	 result += tot_ambient * attr_material[0];
	 result += tot_diffuse * l_color;
	 result = saturate(result);
	 // End view-space light calculations
	 tot_specular *= attr_material[3];
	 result.rgb = result.rgb + tot_specular.rgb;
	 o_color = result * 1.000001;

So yeah, my comment about the “pseudo half angle” not being the actual half angle was bollocks - I just needed to brush up on my lighting basics. :slight_smile:

Anyway, I hope this helps people writing their own lighting shaders - I know it will help me.