Hello,
I know folks have helped me in the past on this and I truly believe I am almost there.
So, after much work I believe my directional light is working in the scene, sort of, but I still get weird artifacts and effects.
Positional lighting doesn’t seem to work at all.
Also, my entire scene is poorly lit and I am not sure what I am doing wrong to have this binary “on, off” effect with lighting.
Anyway, here is what I am talking about.
With positional lighting coming from a point in one direction, the entire scene is dark, as shown below:
When I enable just directional lighting per my shader code; I get the light coming from the right direction but it essentially comes in as an “on, off” thing. You’ll see that I highlighted the areas in the image below where essentially the object is getting light and then right in the next pixel over there is no light:
To show people that I am loading normals, I did a simple “finalColor = NormalColor” colorizer in my shader code.
Here is the resultant image of the scene at the same angle:
Also, per usual, here is my vertex shader:
#version 330 core
#extension GL_ARB_explicit_attrib_location : require
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 vNormal;
layout(location = 2) in vec2 vUV;
layout (std140) uniform Sunlight
{
vec4 SunlightPosition;
vec4 SunlightDiffuse;
vec4 SunlightSpecular;
vec4 SunlightDirection;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent;
float EnableLighting;
float EnableSun;
float ExtraValue;
};
out vec4 worldSpacePosition; // position of the vertex (and fragment) in world space
out vec3 vertexNormalDirection; // surface normal vector in world space
out vec2 TextureCoordinates;
out vec3 NormalColor;
uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;
void main()
{
gl_Position = MVP * vec4(vPosition, 1.0);
TextureCoordinates = vUV;
worldSpacePosition = ModelMatrix * vec4(vPosition, 1.0);
vertexNormalDirection = normalize(NormalMatrix * vNormal);
NormalColor = vNormal;
}
And here is my fragment shader:
#version 330
#extension GL_ARB_explicit_attrib_location : require
precision highp float;
uniform mat4 MVP;
uniform mat4 ModelMatrix;
uniform mat4 ViewMatrix;
uniform mat4 ViewModelMatrix;
uniform mat4 InverseViewMatrix;
uniform mat3 NormalMatrix;
//
// These values vary per Mesh
//
uniform vec4 AmbientMeshColor;
uniform vec4 EmissiveMeshColor;
uniform vec4 DiffuseMeshColor;
uniform vec4 SpecularMeshColor;
uniform vec4 SceneBrightnessColor;
uniform float MeshShininess;
uniform float ObjectHasTextureFile;
//
// Sunlight Settings.
//
layout (std140) uniform Sunlight
{
vec4 SunlightPosition;
vec4 SunlightDiffuse;
vec4 SunlightSpecular;
vec4 SunlightDirection;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent;
float EnableLighting;
float EnableSun;
float ExtraValue;
};
uniform vec4 SceneAmbient;
//
// Whether Materials are enabled at all.
//
uniform float IfEnableTextures;
//
// If we are just simply drawing the skybox.
//
uniform float DrawingSkyBox;
uniform float DrawNormals;
uniform float EnableWireframe;
uniform vec4 WireframeColor;
uniform float TextureCoordinateDebug;
uniform sampler2D MainTextureSampler;
in vec4 worldSpacePosition;
in vec3 vertexNormalDirection;
in vec2 TextureCoordinates;
in vec3 NormalColor;
vec4 finalDiffuseColor;
out vec4 finalColor;
void DrawSkyBox() {
finalColor = texture(MainTextureSampler, TextureCoordinates);
}
void DrawWireFrame() {
finalColor = WireframeColor;
}
void main()
{
if (DrawingSkyBox != 1.0) {
if (DrawNormals == 1.0) {
finalColor = vec4(NormalColor, 1.0);
} else {
vec3 normalDirection = normalize(vertexNormalDirection);
vec3 viewDirection = normalize(vec3(InverseViewMatrix * vec4(0.0, 0.0, 0.0, 1.0) - worldSpacePosition));
vec3 lightDirection;
float attenuation;
if (SunlightPosition.w == 0.0) // directional light?
{
attenuation = 1.0; // no attenuation
lightDirection = normalize(vec3(SunlightPosition));
}
else // point light or spotlight (or other kind of light)
{
vec3 positionToLightSource = vec3(SunlightPosition - worldSpacePosition);
float distance = length(positionToLightSource);
lightDirection = normalize(positionToLightSource);
attenuation = 1.0 / (constantAttenuation
+ linearAttenuation * distance
+ quadraticAttenuation * distance * distance);
if (spotCutoff <= 90.0) // spotlight?
{
float clampedCosine = max(0.0, dot(-lightDirection, vec3(SunlightDirection)));
if (clampedCosine < cos(radians(spotCutoff))) // outside of spotlight cone?
{
attenuation = 0.0;
}
else
{
attenuation = attenuation * pow(clampedCosine, spotExponent);
}
}
}
vec4 ambientLighting = SceneAmbient * AmbientMeshColor;
vec3 diffuseReflection;
if (ObjectHasTextureFile == 1.0) {
diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(texture(MainTextureSampler, TextureCoordinates)) * max(0.0, dot(normalDirection, normalDirection));
} else {
diffuseReflection = attenuation * vec3(SunlightDiffuse) * vec3(DiffuseMeshColor) * max(0.0, dot(normalDirection, normalDirection));
}
vec3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0) // light source on the wrong side?
{
specularReflection = vec3(0.0, 0.0, 0.0); // no specular reflection
}
else // light source on the right side
{
specularReflection = attenuation * vec3(SunlightSpecular) * vec3(SpecularMeshColor) * pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), MeshShininess);
}
finalColor = vec4(vec3(ambientLighting) + diffuseReflection + specularReflection, DiffuseMeshColor.a);
}
} else {
DrawSkyBox();
}
}
Thank you for your time.