mirror of
https://github.com/JoeyDeVries/LearnOpenGL.git
synced 2026-01-30 20:13:22 +08:00
Add Basic Lighting exercises to repo.
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
int main()
|
||||
{
|
||||
[...]
|
||||
// render loop
|
||||
while(!glfwWindowShouldClose(window))
|
||||
{
|
||||
// per-frame time logic
|
||||
float currentFrame = glfwGetTime();
|
||||
deltaTime = currentFrame - lastFrame;
|
||||
lastFrame = currentFrame;
|
||||
|
||||
// input
|
||||
processInput(window);
|
||||
|
||||
// clear the colorbuffer
|
||||
glClearColor(0.1f, 0.1f, 0.1f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// change the light's position values over time (can be done anywhere in the render loop actually, but try to do it at least before using the light source positions)
|
||||
lightPos.x = 1.0f + sin(glfwGetTime()) * 2.0f;
|
||||
lightPos.y = sin(glfwGetTime() / 2.0f) * 1.0f;
|
||||
|
||||
// set uniforms, draw objects
|
||||
[...]
|
||||
|
||||
// glfw: swap buffers and poll IO events
|
||||
glfwSwapBuffers(window);
|
||||
glfwPollEvents();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
// Vertex shader:
|
||||
// ================
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
|
||||
out vec3 FragPos;
|
||||
out vec3 Normal;
|
||||
out vec3 LightPos;
|
||||
|
||||
uniform vec3 lightPos; // we now define the uniform in the vertex shader and pass the 'view space' lightpos to the fragment shader. lightPos is currently in world space.
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
FragPos = vec3(view * model * vec4(aPos, 1.0));
|
||||
Normal = mat3(transpose(inverse(view * model))) * aNormal;
|
||||
LightPos = vec3(view * vec4(lightPos, 1.0)); // Transform world-space light position to view-space light position
|
||||
}
|
||||
|
||||
|
||||
// Fragment shader:
|
||||
// ================
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 FragPos;
|
||||
in vec3 Normal;
|
||||
in vec3 LightPos; // extra in variable, since we need the light position in view space we calculate this in the vertex shader
|
||||
|
||||
uniform vec3 lightColor;
|
||||
uniform vec3 objectColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
// ambient
|
||||
float ambientStrength = 0.1;
|
||||
vec3 ambient = ambientStrength * lightColor;
|
||||
|
||||
// diffuse
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 lightDir = normalize(LightPos - FragPos);
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = diff * lightColor;
|
||||
|
||||
// specular
|
||||
float specularStrength = 0.5;
|
||||
vec3 viewDir = normalize(-FragPos); // the viewer is always at (0,0,0) in view-space, so viewDir is (0,0,0) - Position => -Position
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
|
||||
vec3 specular = specularStrength * spec * lightColor;
|
||||
|
||||
vec3 result = (ambient + diffuse + specular) * objectColor;
|
||||
FragColor = vec4(result, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
// Vertex shader:
|
||||
// ================
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec3 aNormal;
|
||||
|
||||
out vec3 LightingColor; // resulting color from lighting calculations
|
||||
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 viewPos;
|
||||
uniform vec3 lightColor;
|
||||
|
||||
uniform mat4 model;
|
||||
uniform mat4 view;
|
||||
uniform mat4 projection;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_Position = projection * view * model * vec4(aPos, 1.0);
|
||||
|
||||
// gouraud shading
|
||||
// ------------------------
|
||||
vec3 Position = vec3(model * vec4(aPos, 1.0));
|
||||
vec3 Normal = mat3(transpose(inverse(model))) * aNormal;
|
||||
|
||||
// ambient
|
||||
float ambientStrength = 0.1;
|
||||
vec3 ambient = ambientStrength * lightColor;
|
||||
|
||||
// diffuse
|
||||
vec3 norm = normalize(Normal);
|
||||
vec3 lightDir = normalize(lightPos - Position);
|
||||
float diff = max(dot(norm, lightDir), 0.0);
|
||||
vec3 diffuse = diff * lightColor;
|
||||
|
||||
// specular
|
||||
float specularStrength = 1.0; // this is set higher to better show the effect of Gouraud shading
|
||||
vec3 viewDir = normalize(viewPos - Position);
|
||||
vec3 reflectDir = reflect(-lightDir, norm);
|
||||
float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
|
||||
vec3 specular = specularStrength * spec * lightColor;
|
||||
|
||||
LightingColor = ambient + diffuse + specular;
|
||||
}
|
||||
|
||||
|
||||
// Fragment shader:
|
||||
// ================
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
|
||||
in vec3 LightingColor;
|
||||
|
||||
uniform vec3 objectColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
FragColor = vec4(LightingColor * objectColor, 1.0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
So what do we see?
|
||||
You can see (for yourself or in the provided image) the clear distinction of the two triangles at the front of the
|
||||
cube. This 'stripe' is visible because of fragment interpolation. From the example image we can see that the top-right
|
||||
vertex of the cube's front face is lit with specular highlights. Since the top-right vertex of the bottom-right triangle is
|
||||
lit and the other 2 vertices of the triangle are not, the bright values interpolates to the other 2 vertices. The same
|
||||
happens for the upper-left triangle. Since the intermediate fragment colors are not directly from the light source
|
||||
but are the result of interpolation, the lighting is incorrect at the intermediate fragments and the top-left and
|
||||
bottom-right triangle collide in their brightness resulting in a visible stripe between both triangles.
|
||||
|
||||
This effect will become more apparent when using more complicated shapes.
|
||||
*/
|
||||
Reference in New Issue
Block a user