Been tinkering with the engine for quite a while and wanted to add some light sources, but have no idea of how to.
By default there's no light sources at all, right?
I've looked at the Flamerunner's source code and found the shaders used fol lighting there.
The problem is, I'm a total noob with shaders and (what's worse) too dumb to comprehend the math beyond those shaders on my own.
All I can really do at the moment is to try to use the shaders from Flamerunner "as is".
Actually, I just copied part of the shaders (self.meshShader from scene.lua, line #158), added something by myself as well, added a pointlight, updated it once, sending stuff to a shader.
Here's my "light source":
Code: Select all
PointLight = {
shader = g3d.camera.shader,
index = 1,
color = {1,1,1},
pos = {30*6,1,16*6},
specularity = 1,
diffuse = 1,
constant = 1,
linear = 0.001,
quadratic = 0.001,
}
function plu(self)
local i = self.index
self.shader:send("pointLights[" .. i .. "].position", self.pos)
self.shader:send("pointLights[" .. i .. "].color", self.color)
self.shader:send("pointLights[" .. i .. "].specularity", self.specularity)
self.shader:send("pointLights[" .. i .. "].diffuse", self.diffuse)
self.shader:send("pointLights[" .. i .. "].constant", self.constant)
self.shader:send("pointLights[" .. i .. "].linear", self.linear)
self.shader:send("pointLights[" .. i .. "].quadratic", self.quadratic)
end
here's my shader:
Code: Select all
uniform mat4 projectionMatrix;
uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
varying vec4 vertexColor;
// ambient
float ambientStrength = 0.2;
vec4 ambient = ambientStrength * vertexColor;
struct PointLight{
vec3 position;
vec3 color;
float diffuse;
float specularity;
float constant;
float linear;
float quadratic;
};
#define LIGHTS 16 uniform PointLight pointLights[LIGHTS];
#ifdef VERTEX
vec4 position(mat4 transform_projection, vec4 vertex_position)
{
vertexColor = VertexColor;
return projectionMatrix * viewMatrix * modelMatrix * vertex_position;
}
#endif
#ifdef PIXEL
vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir, vec4 texcolor)
{
vec3 lightDir = normalize(light.position - fragPos);
// diffuse shading
float diff = max(dot(normal, lightDir), 0.0);
// specular shading
vec3 reflectDir = reflect(-lightDir, normal);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 0.1);
// attenuation
float distance = length(light.position - fragPos);
float attenuation = 1 / (light.constant + light.linear * distance + light.quadratic * (distance * distance));
// combine results
vec3 ambient = ambientStrength * vec3(texcolor);
vec3 diffuse = light.diffuse * diff * vec3(texcolor);
vec3 specular = light.specularity * spec * vec3(texcolor);
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
return (ambient + diffuse + specular)*light.color;
}
vec4 effect(vec4 color, Image tex, vec2 texcoord, vec2 pixcoord)
{
vec4 texcolor = Texel(tex, texcoord);
if (texcolor.a == 0.0) { discard; }
// saving alpha for later usage
float texalpha = texcolor.a;
// added ambient
vec4 result = (texcolor)*color*ambientStrength*vertexColor;
// restored alpha
result.a = texalpha;
return result;
}
#endif
If I leave only ambient, it works fine.
But as soon as I'm trying to send things to a shader, I'm getting this:
Code: Select all
Shader uniform 'pointLights[0].position' does not exist.
A common error is to define but not use the variable.
I don't get what's wrong
The array is there in the shader, it clearly has a position attribute...
Moreover, any other field is missing too (e.g. I can't set color or diffuse as well).
And yes, I know, I don't actually do anything with sent values in the effect, but I can't even send those values.
(I mean, there's no for (int i=0; i<LIGHTS; i++) etc)
Could anyone help me with this?
Or, better yet, could anyone give an example of just one working pointlight?