Add material for specular lighting

This commit is contained in:
Nathan Chapman 2025-07-05 17:04:07 -06:00
parent 860ea04cfb
commit af612fbfe9
12 changed files with 81 additions and 13 deletions

Binary file not shown.

Binary file not shown.

View File

@ -3,6 +3,7 @@
in vec4 vertex_color;
in vec2 texture_coord;
in vec3 normal;
in vec3 frag_pos;
out vec4 color;
@ -13,8 +14,16 @@ struct Directional_Light {
float diffuse_intensity;
};
struct Material {
float shininess;
float specular_intensity;
};
uniform sampler2D tex;
uniform Directional_Light sun;
uniform Material material;
uniform vec3 eye_position;
void main() {
vec4 ambient_color = vec4(sun.color, 1.0f) * sun.ambient_intensity;
@ -22,5 +31,18 @@ void main() {
float diffuse_factor = max(dot(normalize(normal), normalize(sun.direction)), 0.0f);
vec4 diffuse_color = vec4(sun.color, 1.0f) * sun.diffuse_intensity * diffuse_factor;
color = texture(tex, texture_coord) * (ambient_color + diffuse_color);
vec4 specular_color = vec4(0, 0, 0, 0);
if (diffuse_factor > 0.0f) {
vec3 frag_to_eye = normalize(eye_position - frag_pos);
vec3 reflected_vertex = normalize(reflect(sun.direction, normalize(normal)));
float specular_factor = dot(frag_to_eye, reflected_vertex);
if (specular_factor > 0) {
specular_factor = pow(specular_factor, material.shininess);
specular_color = vec4(sun.color * material.specular_intensity * specular_factor, 1.0f);
}
}
color = texture(tex, texture_coord) * (ambient_color + diffuse_color + specular_color);
}

View File

@ -7,6 +7,7 @@ layout (location = 2) in vec3 norm;
out vec4 vertex_color;
out vec2 texture_coord;
out vec3 normal;
out vec3 frag_pos;
uniform mat4 projection;
uniform mat4 model;
@ -17,4 +18,5 @@ void main() {
vertex_color = vec4(clamp(pos, 0.0f, 1.0f), 1.0f);
texture_coord = tex;
normal = mat3(transpose(inverse(model))) * norm;
frag_pos = (model * vec4(pos, 1.0)).xyz;
}

View File

@ -16,4 +16,5 @@ struct Light {
~Light() = default;
};
// Some of these should be u32
void use_light(Light *light, f32 color_location, f32 ambient_intensity_location, f32 direction_location, f32 diffuse_intensity_location);

View File

@ -6,6 +6,7 @@
#include "camera.h"
#include "texture.h"
#include "light.h"
#include "material.h"
static const char *vertex_shader_code = "shaders/shader.vert";
@ -63,6 +64,9 @@ int main() {
Texture plaster_texture = Texture((char *)"assets/textures/plaster_texture_1k.png");
load_texture(&plaster_texture);
Material shiny_material(1.0f, 32.0f);
Material dull_material(0.3f, 4.0f);
Light sun_light(Vector3(1.0f, 1.0f, 1.0f), 0.2f, Vector3(2.0f, -1.0, -2.0f), 1.0f);
Matrix4 projection = glm::perspective(45.0f, (f32)window.buffer_width / (f32)window.buffer_height, 0.1f, 100.0f);
@ -96,32 +100,32 @@ int main() {
shaders[0].uniform_diffuse_direction, shaders[0].uniform_diffuse_intensity
);
glUniformMatrix4fv(shaders[0].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
Matrix4 view = calculate_view_matrix(&camera);
glUniformMatrix4fv(shaders[0].uniform_view, 1, GL_FALSE, glm::value_ptr(view));
glUniform3f(shaders[0].uniform_eye_position, camera.position.x, camera.position.y, camera.position.z);
{
Matrix4 model(1.0f);
model = glm::translate(model, Vector3(0.0f, 0.0f, -2.5f));
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
model = glm::translate(model, Vector3(0.0f, 3.0f, 2.5f));
// model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
glUniformMatrix4fv(shaders[0].uniform_model, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(shaders[0].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
use_texture(&clay_texture);
use_material(&shiny_material, shaders[0].uniform_shininess, shaders[0].uniform_specular_intensity);
render_mesh(meshes[0]);
}
{
Matrix4 model(1.0f);
model = glm::translate(model, Vector3(0.0f, 0.0f, -3.5f));
model = glm::scale(model, Vector3(0.4f, 0.4f, 1.0f));
model = glm::translate(model, Vector3(0.0f, 0.0f, 3.5f));
glUniformMatrix4fv(shaders[0].uniform_model, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(shaders[0].uniform_projection, 1, GL_FALSE, glm::value_ptr(projection));
use_texture(&plaster_texture);
use_material(&dull_material, shaders[0].uniform_shininess, shaders[0].uniform_specular_intensity);
render_mesh(meshes[1]);
}
Matrix4 view = calculate_view_matrix(&camera);
glUniformMatrix4fv(shaders[0].uniform_view, 1, GL_FALSE, glm::value_ptr(view));
glUseProgram(0);
// We usually have two buffers, the first is hidden and that's

10
src/material.cpp Normal file
View File

@ -0,0 +1,10 @@
#include "material.h"
Material::Material(f32 specular_intensity, f32 shininess) : specular_intensity(specular_intensity), shininess(shininess) {}
void use_material(Material *material, u32 shininess_location, u32 specular_intensity_location) {
glUniform1f(shininess_location, material->shininess);
glUniform1f(specular_intensity_location, material->specular_intensity);
}

17
src/material.h Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include <GL/glew.h>
#include "math.h"
/*
The kind of a thing
*/
struct Material {
f32 shininess;
f32 specular_intensity;
Material(f32 specular_intensity, f32 shininess);
~Material() = default;
};
void use_material(Material *material, u32 shininess_location, u32 specular_intensity_location);

View File

@ -3,6 +3,9 @@
#include "math.h"
#include <GL/glew.h>
/*
The shape of a thing
*/
struct Mesh {
u32 VAO, VBO, IBO;
u32 index_count;

View File

@ -64,13 +64,16 @@ bool create_shader(Shader *shader, const char *vertex_shader_path, const char *f
shader->uniform_projection = glGetUniformLocation(shader->id, "projection");
shader->uniform_model = glGetUniformLocation(shader->id, "model");
shader->uniform_view = glGetUniformLocation(shader->id, "view");
shader->uniform_eye_position = glGetUniformLocation(shader->id, "eye_position");
shader->uniform_ambient_color = glGetUniformLocation(shader->id, "sun.color");
shader->uniform_ambient_intensity = glGetUniformLocation(shader->id, "sun.ambient_intensity");
shader->uniform_diffuse_direction = glGetUniformLocation(shader->id, "sun.direction");
shader->uniform_diffuse_intensity = glGetUniformLocation(shader->id, "sun.diffuse_intensity");
shader->uniform_shininess = glGetUniformLocation(shader->id, "material.shininess");
shader->uniform_specular_intensity = glGetUniformLocation(shader->id, "material.specular_intensity");
return true;
}

View File

@ -15,11 +15,17 @@ struct Shader {
u32 uniform_projection;
u32 uniform_model;
u32 uniform_view;
u32 uniform_eye_position;
u32 uniform_ambient_color;
u32 uniform_ambient_intensity;
u32 uniform_diffuse_direction;
u32 uniform_diffuse_intensity;
u32 uniform_shininess;
u32 uniform_specular_intensity;
Shader();
~Shader();
};

View File

@ -9,7 +9,7 @@
#include "math.h"
struct Window {
u32 width = 800, height = 600;
u32 width = 1024, height = 768;
s32 buffer_width, buffer_height;
GLFWwindow *gl_window = nullptr;
bool ascii_keys[1024];