I'm testing a per-pixel lighting script and in most cases it works, however, if I look in the correct direction (fps camera), or if I change the weapon that is displayed on the screen, it becomes VERY weird:
If someone could try the scripts (posted below) in one of their irrlicht apps and see if they get similar results, please tell me. All help appreciated.
Incorrect: (notice that you can see through walls and etc)
Correct: (notice that you can nolonger see through walls and everything is lit correctly)
Vertex shader (GLSL):
Code: Select all
/*
www.UltimateGameProgramming.com
PerPixel Lighting Shader in GLSlang.
Created by the Programming Ace.
Input...
gl_Vertex = vertex object space position.
gl_ModelViewProjectionMatrix = current model view projection matrix.
gl_MultiTexCoord0.xy = texture coords for unit 0.
Varying...
texCoord0 = output vertex texture coordinates.
normal = vertex normal.
pos = vertex pos.
Output...
gl_Position = output position.
*/
varying vec2 texCoord0;
varying vec3 normal;
varying vec4 pos;
void main()
{
// Tranform to clip space.
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
// Set tex coord.
texCoord0 = gl_MultiTexCoord0.xy;
// Send vertex pos and normal to the pixel shader.
normal = gl_NormalMatrix * gl_Normal;
pos = gl_Vertex;
}
Code: Select all
/*
www.UltimateGameProgramming.com
PerPixel Lighting Shader in GLSlang.
Created by the Programming Ace.
Varying...
texCoord0 = output vertex texture coordinates.
normal = vertex normal.
pos = vertex pos.
Uniform...
decal = binded texture.
light[] = array of lights.
ambientColor = ambient color.
mat = material.
cameraPos = view position.
Output...
gl_FragColor = output vertex color.
*/
struct Light
{
vec4 lightColor;
vec4 lightPos;
float constant;
float linear;
float quadratic;
};
struct Material
{
vec4 matAmbient;
vec4 matDiffuse;
vec4 matSpecular;
vec4 emissive;
float shininess;
};
varying vec2 texCoord0;
varying vec3 normal;
varying vec4 pos;
uniform sampler2D decal;
uniform Light light[2];
uniform Material mat;
uniform vec4 ambientColor;
uniform vec4 cameraPos;
void calDiffuseSpecular(Light light, vec4 pos, vec3 norm, vec4 camPos, float shininess,
out vec4 diffuseOut, out vec4 specularOut)
{
// Get light attenuation for point light effect.
float d = distance(pos, light.lightPos);
float attenuationFactor = 1 / (light.constant + light.linear *
d + light.quadratic * d * d);
// Calculate diffuse with the attenuation.
vec4 lightVec = normalize(light.lightPos - pos);
float diffuseLight = max(dot(norm, lightVec), 0);
diffuseOut = attenuationFactor * light.lightColor * diffuseLight;
// Calculate specular with the attenuation.
vec4 eyeVec = normalize(camPos - pos);
vec4 halfVec = normalize(lightVec + eyeVec);
float specularLight = pow(max(dot(norm, halfVec), 0), shininess);
// No diffuse, no specular.
if(diffuseLight <= 0) specularLight = 0;
specularOut = attenuationFactor * light.lightColor * specularLight;
}
void main()
{
// Re-normalize.
vec3 n = normalize(normal);
// Get ambient value.
vec4 ambient = mat.matAmbient * ambientColor;
vec4 diffuseLight;
vec4 specularLight;
vec4 diffuseSum = 0;
vec4 specularSum = 0;
// Calculate diffuse and specular for all lights.
for(int i = 0; i < 2; i++)
{
calDiffuseSpecular(light[i], pos, n, cameraPos, mat.shininess, diffuseLight, specularLight);
diffuseSum += diffuseLight;
specularSum += specularLight;
}
// Get final diffuse and specular values.
vec4 diffuse = mat.matDiffuse * diffuseSum;
vec4 specular = mat.matSpecular * specularSum;
// Set final light color.
gl_FragColor = (mat.emissive + ambient + diffuse + specular) * texture2D(decal, texCoord0);
gl_FragColor.w = 1;
}
GM L66 ENGINE