Hello,
I am attempting to adapt a phong shader I found online for a project I am working on and I essentially have a problem with the specular lighting.
It is probably best explained by the images below but essentially the sunlight implemented via the shader is “on” or “off” with no gradual degradation in between.
Below are the images and the GLSL code I am using.
Any ideas?
Thank you.
With just the textures and a black material:
Vertex Shader Code:
#version 330 core
#extension GL_ARB_explicit_attrib_location : require
// Input vertex data, different for all executions of this shader.
layout(location = 0) in vec3 vPosition;
layout(location = 1) in vec3 Normals;
layout(location = 2) in vec2 vUV;
// Output data ; will be interpolated for each fragment.
out vec3 SurfaceNormal;
out vec4 vertexPosition;
out vec2 TextureCoordinates;
// Values that stay constant for the whole mesh.
uniform mat4 MVP;
uniform mat3 NormalMatrix;
void main(){
gl_Position = vertexPosition = MVP * vec4(vPosition, 1.0);
SurfaceNormal = normalize(NormalMatrix * Normals);
TextureCoordinates = vUV;
}
Fragment Shader Code:
#version 330
#extension GL_ARB_explicit_attrib_location : require
//
// These values vary per Mesh
//
//
// Base Material Color.
//
uniform vec4 MaterialColor;
//
// Material Ambient Color.
//
uniform vec4 AmbientMeshColor;
//
// Material Emissive Color.
//
uniform vec4 EmissiveMeshColor;
//
// Material Diffuse Color.
//
uniform vec4 DiffuseMeshColor;
//
// Material Specular Color.
//
uniform vec4 SpecularMeshColor;
//
// Material Mesh Shininess
//
uniform float MeshShininess;
//
// Whether Materials are enabled at all.
//
uniform float IfEnableTextures;
//
// Whether the object itself has Materials.
//
uniform float ObjectHasTextureFile;
//
// Whether I am drawing the skybox or not.
//
uniform float DrawingSkyBox;
//
// Wireframe Settings
//
uniform float EnableWireframe;
uniform vec4 WireframeColor;
uniform float EnableLighting;
uniform float EnableSun;
uniform vec3 SunDirection;
uniform vec3 LightHalfVector;
uniform vec4 SunColor;
uniform vec4 SunSpotCutoff;
uniform float SunLightStrength;
uniform float TextureCoordinateDebug;
uniform float TextureClamping;
uniform sampler2D MainTextureSampler;
in vec4 vertexPosition; // position of the vertex (and fragment) in world space
in vec3 SurfaceNormal; // surface normal vector in world space
in vec2 TextureCoordinates; // Texture coordinates...
uniform mat4 InverseView;
vec4 MaterialTextureColor;
out vec4 finalColor;
struct lightSource
{
vec4 position;
vec4 diffuse;
vec4 specular;
float constantAttenuation, linearAttenuation, quadraticAttenuation;
float spotCutoff, spotExponent;
vec3 spotDirection;
};
lightSource light0 = lightSource(
vec4(0.0, 1.0, 3.0, 1.0),
vec4(1.0, 0.984, 0.569, 1.0),
vec4(1.0, 1.0, 1.0, 1.0),
0.0, 1.0, 0.0,
180.0, 0.0,
vec3(0.0, 0.0, 0.0)
);
void DrawSkyBox() {
finalColor = texture(MainTextureSampler, TextureCoordinates);
}
void DrawWireFrame() {
finalColor = WireframeColor;
}
void SunlightWithoutMaterials() {
vec3 normalDirection = normalize(SurfaceNormal);
vec3 viewDirection = normalize(vec3(InverseView * vec4(0.0, 0.0, 0.0, 1.0) - vertexPosition));
vec3 lightDirection;
float attenuation;
attenuation = 1.0; // no attenuation
lightDirection = normalize(vec3(light0.position));
vec3 ambientLighting = vec3(MaterialColor) * vec3(AmbientMeshColor);
vec3 diffuseReflection = attenuation * vec3(light0.diffuse) * vec3(DiffuseMeshColor) * max(0.0, dot(normalDirection, lightDirection));
vec3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0)
{
specularReflection = vec3(0.0, 0.0, 0.0);
}
else
{
specularReflection = attenuation * vec3(light0.specular) * vec3(SpecularMeshColor)
* pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), MeshShininess);
}
finalColor = vec4(ambientLighting + diffuseReflection + specularReflection, MaterialColor.a);
}
void SunlightWithMaterials() {
vec3 normalDirection = normalize(SurfaceNormal);
vec3 viewDirection = normalize(vec3(InverseView * vec4(0.0, 0.0, 0.0, 1.0) - vertexPosition));
vec3 lightDirection;
float attenuation;
attenuation = 1.0;
lightDirection = normalize(vec3(light0.position));
vec3 ambientLighting = vec3(MaterialTextureColor) * vec3(AmbientMeshColor);
vec3 diffuseReflection = attenuation * vec3(light0.diffuse) * vec3(DiffuseMeshColor) * max(0.0, dot(normalDirection, lightDirection));
vec3 specularReflection;
if (dot(normalDirection, lightDirection) < 0.0)
{
specularReflection = vec3(0.0, 0.0, 0.0);
}
else
{
specularReflection = attenuation * vec3(light0.specular) * vec3(SpecularMeshColor)
* pow(max(0.0, dot(reflect(-lightDirection, normalDirection), viewDirection)), MeshShininess);
}
finalColor = vec4(ambientLighting + diffuseReflection + specularReflection, MaterialColor.a);
}
void LightingWithoutMaterials() {
if (EnableLighting == 1.0 && EnableSun == 1.0) {
SunlightWithoutMaterials();
} else if (EnableLighting == 1.0) {
finalColor = min(MaterialColor * AmbientMeshColor, vec4(1.0));
} else {
finalColor = MaterialColor;
}
}
void LightingWithMaterials() {
if (EnableLighting == 1.0 && EnableSun == 1.0) {
SunlightWithMaterials();
} else if (EnableLighting == 1.0) {
finalColor = min(MaterialTextureColor * AmbientMeshColor, vec4(1.0));
} else {
finalColor = MaterialTextureColor;
}
}
void main() {
if (TextureCoordinateDebug == 1) {
finalColor = vec4(TextureCoordinates, 0.0, 1.0);
} else if (EnableWireframe == 1.0) {
DrawWireFrame();
} else if (DrawingSkyBox == 1.0) {
DrawSkyBox();
} else {
if (IfEnableTextures != 1.0 && ObjectHasTextureFile != 1.0) {
LightingWithoutMaterials();
} else {
MaterialTextureColor = texture(MainTextureSampler, TextureCoordinates);
LightingWithMaterials();
}
}
}