Multiple lights input in GLSL shader

Hi everyone, I’m new to the forum and already in need of some help :slight_smile:

I’ve been messing around trying to learn GLSL and do some simple shaders and got to a point where there’s
a number of point lights I need to pass to the shader in order to iterate through them via for loop.

If I understand correctly what’s noted in glsl manual section it should be possible to have an array of LightSourceParameters structs and then access individual light parameter through an index?

As in:

p3d_LightSource[i].position 
p3d_LightSource[i].ambient
...

I’ve tried to set it up like this but it doesn’t seem to work :confused:

//multiple_lights.vert

#version 430
layout (location = 0) in vec3 p3d_Vertex;
layout (location = 1) in vec3 p3d_Normal;

out vec3 Color;

uniform struct p3d_LightSourceParameters {
  vec4 position;
  vec4 color;
} p3d_LightSource[3];

uniform struct {
  vec4 ambient;
  vec4 diffuse;
  vec3 specular;
  float shininess;
} p3d_Material;

uniform mat4 p3d_ModelViewMatrix;
uniform mat3 p3d_NormalMatrix;
uniform mat4 p3d_ProjectionMatrix;
const int NumEnabledLights = 3;

vec3 ads( int lightIndex, vec4 position, vec3 norm )
{
	vec3 s = normalize( vec3(p3d_LightSource[lightIndex].position - position) );
	vec3 v = normalize(vec3(-position));
	vec3 r = reflect( -s, norm );
	vec3 I = vec3(p3d_LightSource[lightIndex].color);
	return
			I * ( p3d_Material.ambient.xyz +
			p3d_Material.diffuse.xyz * max( dot(s, norm), 0.0 ) +
			p3d_Material.specular * pow( max( dot(r,v), 0.0 ), p3d_Material.shininess ) );
}

void main()
{
	vec3 eyeNorm = normalize( p3d_NormalMatrix * p3d_Normal);
	vec4 eyePosition = p3d_ModelViewMatrix * vec4(p3d_Vertex, 1.0);

	Color = vec3(0.0);
	for( int i = 0; i < NumEnabledLights; i++ )
	Color += ads( i, eyePosition, eyeNorm );

	gl_Position = p3d_ProjectionMatrix * p3d_ModelViewMatrix * vec4(p3d_Vertex, 1.0);
}

here’s the log:

:display:gsg:glgsg(error): Unrecognized uniform name 'p3d_LightSource[0].color'!
:display:gsg:glgsg(error): Unrecognized uniform name 'p3d_LightSource[0].position'!
:display:gsg:glgsg(error): Unrecognized uniform name 'p3d_LightSource[1].color'!
:display:gsg:glgsg(error): Unrecognized uniform name 'p3d_LightSource[1].position'!
:display:gsg:glgsg(error): Unrecognized uniform name 'p3d_LightSource[2].color'!
:display:gsg:glgsg(error): Unrecognized uniform name 'p3d_LightSource[2].position'!

I’m not sure what I’m doing wrong, it’d be awesome if someone has an idea how to fix this.

Hi, welcome to the forums! :slight_smile:

Which version of Panda3D are you using? I believe the p3d_LightSource[i] inputs aren’t available in 1.9, and require a development build of Panda.

For what it’s worth, there’s a rough sample program showing a GLSL lighting shader here:
rdb.name/glsl-lighting.zip

You’re absolutely right, I was using 1.9.4, got 1.10 installed with python 3.5 and it works like a charm :smiley:
Thanks a lot for solving this so fast and for the spotlights sample, those were gonna be my next point of venture anyway so it’s very useful!