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