I am trying to go from basic lighting to more advance lighting (PBR, etc). I am using PyOpengl and Opengl version 4.4
I ran my python code and was able to see a mesh. In this code I am able to move a light source and see the diffuse lighting effect.
My vertex shader is the following and never changed
#version 440 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
out vec3 FragPos;
out vec3 Normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
gl_Position = projection * view * vec4(FragPos, 1.0);
}
My fragment shade was initially this one,
#version 440 core
in vec3 FragPos;
in vec3 Normal;
uniform vec3 lightPos;
out vec4 FragColor;
void main()
{
vec3 N = normalize(Normal);
vec3 L = normalize(lightPos - FragPos);
float diff = max(dot(N, L), 0.0);
FragColor = vec4(vec3(diff), 1.0);
}
Runing it with these I go the results described above. I see my 3d object and I am able to move a light cube I generated and see the effects. So far so good. I decided to change the fragment shader to this (still trying to keep it simple):
#version 440 core
in vec3 FragPos;
in vec3 Normal;
out vec4 FragColor;
uniform vec3 lightPos;
uniform vec3 lightColor;
uniform vec3 viewPos;
// PBR Inputs (uniforms only)
uniform vec4 baseColorFactor;
uniform float metallicFactor;
uniform float roughnessFactor;
void main()
{
// Normalized vectors
vec3 N = normalize(Normal);
vec3 L = normalize(lightPos - FragPos);
vec3 V = normalize(viewPos - FragPos);
vec3 H = normalize(L + V);
// Lambertian diffuse (energy-conserving)
float NdotL = max(dot(N, L), 0.0);
// Specular approximation (simple Blinn-Phong-like using roughness)
float NdotH = max(dot(N, H), 0.0);
float spec = pow(NdotH, 1.0 / (roughnessFactor + 0.001));
// Blend between diffuse/specular based on metallic
vec3 diffuseColor = baseColorFactor.rgb * (1.0 - metallicFactor);
vec3 specularColor = mix(vec3(0.04), baseColorFactor.rgb, metallicFactor);
vec3 color = (diffuseColor * NdotL + specularColor * spec) * lightColor;
FragColor = vec4(color, baseColorFactor.a);
}
Of course I am passing the following,
baseColorFactor, metallicFactor, roughnessFactor
Now when I do this it bombs! I no longer see my 3d object, my light cube as disappeared and instead I what looks like a thick white line. Now, here is the kicker! I go back to my initial fragment shader and run again the program and I get exactly the same result as when I used the latter fragment shader. No matter what I change I get the same result. I imagine it has to do with something of the GL State???.
I tried resetting this state using the following:
def reset_gl_state():
glUseProgram(0)
glBindVertexArray(0)
glBindBuffer(GL_ARRAY_BUFFER, 0)
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)
glEnable(GL_DEPTH_TEST)
glDepthFunc(GL_LESS)
glDisable(GL_BLEND)
glDisable(GL_CULL_FACE)
glClearColor(0.1, 0.1, 0.1, 1.0)
I include the rendering loop (abbreviated) here in case this helps
while not glfw.window_should_close(window):
glfw.poll_events()
# Compute delta_time for smooth motion
# Handle keyboard input for moving the light
# reset gl state
reset_gl_state()
# Clear the framebuffer
# ------------------------------------------------------------------
# Camera matrices
# ------------------------------------------------------------------
model = glm.mat4(1.0)
projection = glm.perspective(glm.radians(fov), 800 / 600, 0.1, distance * 4)
view = glm.lookAt(eye, target, up)
# ------------------------------------------------------------------
# Draw the main object with lighting
# ------------------------------------------------------------------
shader.use()
shader.set_uniform_mat4("model", model)
shader.set_uniform_mat4("view", view)
shader.set_uniform_mat4("projection", projection)
shader.set_uniform_vec3("viewPos", eye)
shader.set_uniform_vec3("lightPos", light_pos)
shader.set_uniform_vec3("lightColor", glm.vec3(10.0, 10.0, 10.0))
mesh.draw(shader)
# ------------------------------------------------------------------
# Draw the light cube
# ------------------------------------------------------------------
light_shader.use()
light_shader.set_uniform_mat4("view", view)
light_shader.set_uniform_mat4("projection", projection)
light_model = glm.mat4(1.0)
light_model = glm.translate(light_model, light_pos)
light_model = glm.scale(light_model, glm.vec3(0.2))
light_shader.set_uniform_mat4("model", light_model)
light_shader.set_uniform_vec3("lightColor", glm.vec3(1.0, 1.0, 1.0))
glBindVertexArray(lightVAO)
glDrawArrays(GL_TRIANGLES, 0, 36)
glBindVertexArray(0)
# Swap buffers
glfw.swap_buffers(window)
# Cleanup
glfw.terminate()
Any ideas on what is going on and how to fix it???