Multiple lights in GL3 Shader Syntax
Hey all, I'm building my own material shader in GL3, but I'm having problems in using multiple lights sourcesI have declared an array of lights in this way inside the shader:struct LightSourceParameters {
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 position;
vec3 spotDirection;
float spotExponent;
float spotCutOff;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
};struct LightModelParameters {
vec4 ambient;
};#define NUM_LIGHTS (5)
layout (std140) uniform LightingParameters {
LightModelParameters lightModel;
LightSourceParameters light[NUM_LIGHTS];
};
and declared the parameter like this:
<param name="LightingParameters" state="LIGHT" />
it seems that it only recognises the first light, but non above that, for example if I try "light[1].diffuse" I get some random numbers.
Am I missing something?
Have you tried with less lights?
should be something like the below code snippet. send the message "get_gl3_shader" to any objects bound to a jit.gl.material to see how material generates the shader.
<param name="LightingParameters" state="LIGHT" />
<bind param="LightingParameters" program="fs" />
struct LightModelParameters {
vec4 ambient;
};
struct LightSourceParameters {
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 position;
vec3 spotDirection;
float spotExponent;
float spotCutoff;
float spotCosCutoff;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
};
layout (std140) uniform LightingParameters {
LightModelParameters lightModel;
LightSourceParameters light[2];
};
struct Light {
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec3 toEyePosition;
} ;
Light jit_Light [2];
void main() {
jit_Light[0].toEyePosition = -normalize(light[0].position.xyz);
jit_Light[1].toEyePosition = -normalize(light[1].position.xyz);
}
Hi Rob,
thank you very much for your answer.
After seeing the jit.gl.material generated shader I still have troubles making this work.
It only works for one light, the others contain wrong values.
Here's my shader code:
<jittershader name="Phong_Shader">
<description></description>
<param name="vertexPosition" type="vec3" state="POSITION" />
<param name="vertexColor" type="vec4" state="COLOR" />
<param name="vertexNormal" type="vec3" state="NORMAL" />
<param name="vertexTexcoord" type="vec2" state="TEXCOORD" />
<param name="modelViewProjectionMatrix" type="mat4" state="MODELVIEW_PROJECTION_MATRIX" />
<param name="modelViewMatrix" type="mat4" state="MODELVIEW_MATRIX" />
<param name="textureMatrix0" type="mat4" state="TEXTURE0_MATRIX" />
<param name="LightingParameters" state="LIGHT" />
<param name="FrontMaterialParameters" state="FRONT_MATERIAL" />
<param name="uLightIntensity" type="float" default="3.0" />
<param name="duckTexture" type="int" default="0" />
<language name="glsl" version="1.5">
<bind param="vertexPosition" program="vp" />
<bind param="vertexColor" program="vp" />
<bind param="vertexNormal" program="vp" />
<bind param="vertexTexcoord" program="vp" />
<bind param="modelViewProjectionMatrix" program="vp" />
<bind param="modelViewMatrix" program="vp" />
<bind param="textureMatrix0" program="vp" />
<bind param="LightingParameters" program="fp" />
<bind param="FrontMaterialParameters" program="fp" />
<bind param="uLightIntensity" program="fp" />
<bind param="duckTexture" program="fp" />
<program name="vp" type="vertex">
<![CDATA[
#version 330 core
uniform mat4 modelViewProjectionMatrix;
uniform mat4 modelViewMatrix;
mat3 normalMatrix = transpose(inverse(mat3x3(modelViewMatrix)));
uniform mat4 textureMatrix0;
// Attributes: variables that change for every vertex
in vec3 vertexPosition; // x y z w
in vec4 vertexColor; // r g b a
in vec3 vertexNormal; // x y z
in vec2 vertexTexcoord; // s t
out jit_PerVertex {
//flat vec4 lightIntensity;
vec3 eyePosition;
vec3 eyeNormal;
vec2 textureCoord0;
} jit_out;
// gets vectors in world space and outputs vectors in eye space
void getEyeSpace(out vec3 norm, out vec3 position, out vec2 texcoord)
{
norm = normalize(normalMatrix * vertexNormal);
position = vec3((modelViewMatrix) * vec4(vertexPosition, 1.0));
texcoord = vec2(textureMatrix0 * vec4(vertexTexcoord, 0.0, 1.0));
}
//-------------------------------
void main() {
vec3 eyePosition;
vec3 eyeNormal;
vec2 eyeTexcoord0;
getEyeSpace(eyeNormal, eyePosition, eyeTexcoord0);
jit_out.eyePosition = eyePosition;
jit_out.eyeNormal = eyeNormal;
jit_out.textureCoord0 = eyeTexcoord0;
gl_Position = modelViewProjectionMatrix * vec4(vertexPosition, 1.0);
}
]]>
</program>
<program name="fp" type="fragment">
<![CDATA[
#version 330 core
uniform samplerJit0 duckTexture;
uniform float uLightIntensity;
in jit_PerVertex {
vec3 eyePosition;
vec3 eyeNormal;
vec2 textureCoord0;
} jit_in;
struct LightSourceParameters {
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec4 position;
vec3 spotDirection;
float spotExponent;
float spotCutOff;
float constantAttenuation;
float linearAttenuation;
float quadraticAttenuation;
};
struct MaterialParameters {
vec4 emission;
vec4 ambient;
vec4 diffuse;
vec4 specular;
float shininess;
};
struct LightModelParameters {
vec4 ambient;
};
#define NUM_LIGHTS (5)
layout (std140) uniform LightingParameters {
LightModelParameters lightModel;
LightSourceParameters light[NUM_LIGHTS];
};
struct Material {
vec4 color;
};
struct Light {
vec4 ambient;
vec4 diffuse;
vec4 specular;
vec3 toEyePosition;
};
layout (std140) uniform FrontMaterialParameters {
MaterialParameters frontMaterial;
};
layout (location = 0) out vec4 outColor;
Material jit_Material;
Light jit_Light [NUM_LIGHTS];
// Functions -------------------------------
// out = the variable we pass in it's going to be overridden
// in = we are just going to read the variable without modifying it
// inout = we are going to read the variable and also modify it
// Phong Lighting Model
void phongModel(in int lightIndex, in vec3 eyePosition, in vec3 eyeNormal)
{
vec3 eyeLightPosition = light[lightIndex].position.xyz;
vec3 shapeToLight = normalize(eyeLightPosition - eyePosition);
vec3 shapeToEye = normalize(-eyePosition);
// following line is how it appears in the jit_gl_material shader
//jit_Light[lightIndex].toEyePosition = normalize(eyePosition - eyeLightPosition);
jit_Light[lightIndex].toEyePosition = -normalize(light[lightIndex].position.xyz);
vec3 lightToShape = -shapeToLight;
vec3 reflectVec = reflect(lightToShape, eyeNormal);
float shapeToLight_dot_normal = max(dot(shapeToLight, eyeNormal), 0.0);
float specularAmt = 0.0;
if (shapeToLight_dot_normal > 0.0)
{
specularAmt = pow(max(dot(reflectVec, shapeToEye), 0.0), frontMaterial.shininess);
}
float lightDist = length(eyeLightPosition - eyePosition);
float dimmer = (1.0 / (lightDist * lightDist)) * uLightIntensity;
dimmer = clamp(dimmer, 0.0, 1.0);
jit_Light[lightIndex].diffuse = light[lightIndex].diffuse * shapeToLight_dot_normal * frontMaterial.diffuse;
jit_Light[lightIndex].specular = light[lightIndex].specular * specularAmt * frontMaterial.specular;
jit_Light[lightIndex].ambient = light[lightIndex].ambient * frontMaterial.ambient;
jit_Material.color += jit_Light[lightIndex].diffuse * dimmer;
jit_Material.color += jit_Light[lightIndex].specular * dimmer;
jit_Material.color += jit_Light[lightIndex].ambient * dimmer;
}
void main() {
jit_Material.color = vec4(0.0);
vec4 textureColor = texture(duckTexture, jit_in.textureCoord0);
for (int i=0; i < NUM_LIGHTS; i++)
{
phongModel(i, jit_in.eyePosition, jit_in.eyeNormal);
}
outColor = jit_Material.color * textureColor;
}
]]>
</program>
</language>
</jittershader>
And here the patch:
If you would have some time to look at this it would be great, thank you very much
Thank you very much Rob!
Is it necessary to have the "Light" struct and the "Material" struct or you are just using them for sake of a neat code?
probably not necessary.
After an unreasonable amount of time, I found out that I missed the line
float spotCosCutoff;
in the struct LightSourceParameters
Thank you so much for your help Rob!