Test implementation of phong shader
This commit is contained in:
@@ -1,8 +1,11 @@
|
||||
#include "aliases.h"
|
||||
#include "img.h"
|
||||
#include "obj.h"
|
||||
#include "render.h"
|
||||
#include "shader.h"
|
||||
#include "utils.h"
|
||||
#include "vec.h"
|
||||
#include <math.h>
|
||||
|
||||
typedef struct shader Shader;
|
||||
struct shader {
|
||||
@@ -18,7 +21,12 @@ ShaderID orthographic_albedo = {0};
|
||||
internal Shader perspective = {0};
|
||||
internal Shader orthographic = {0};
|
||||
|
||||
internal V3f g_directional_light = {0.0f, 0.0f, 1.0f};
|
||||
internal V3f g_ambient_light = {0.3f, 0.75f, 0.15f};
|
||||
internal DirectionalLight g_directional_light = {
|
||||
.diffuse_intensity = {0.9f, 0.8f, 0.6f},
|
||||
.specular_intensity = {0.5f, 0.8f, 2.0f},
|
||||
.direction = {0.0f, 0.0f, 1.0f},
|
||||
};
|
||||
internal V3f g_eye = {0.2f, 0.1f, 0.75f};
|
||||
internal V3f g_target = {0};
|
||||
internal V3f g_up = {0.0f, 1.0f, 0.0f};
|
||||
@@ -80,18 +88,16 @@ internal FragmentResult phong_shader_fragment(void *shader,
|
||||
const FragmentData *data,
|
||||
const Colour *colour,
|
||||
const Model *model) {
|
||||
f32 intensity;
|
||||
V3f norm;
|
||||
if (model->normal) {
|
||||
u64 nm_x = data->tex_coords.u * model->normal->width;
|
||||
u64 nm_y = (1.0f - data->tex_coords.v) * model->normal->height;
|
||||
|
||||
Colour pixel = get_pixel(Colour, model->normal, nm_x, nm_y);
|
||||
V3f norm = {.x = pixel.r, .y = pixel.g, .z = pixel.b};
|
||||
norm = (V3f){.x = pixel.r, .y = pixel.g, .z = pixel.b};
|
||||
normalise_v3(norm);
|
||||
|
||||
intensity = get_intensity(&norm);
|
||||
} else {
|
||||
intensity = get_intensity(&data->normal);
|
||||
norm = data->normal;
|
||||
}
|
||||
|
||||
Colour output;
|
||||
@@ -103,9 +109,45 @@ internal FragmentResult phong_shader_fragment(void *shader,
|
||||
output = *colour;
|
||||
}
|
||||
|
||||
output.r = clamp(intensity * output.r, 0.0f, 255.0f);
|
||||
output.g = clamp(intensity * output.g, 0.0f, 255.0f);
|
||||
output.b = clamp(intensity * output.b, 0.0f, 255.0f);
|
||||
V3f local_colour = {.r = output.r, .g = output.g, .b = output.b};
|
||||
local_colour = num_div_v3(local_colour, 255.0f);
|
||||
|
||||
// Ambient term
|
||||
V3f intensity = num_mul_v3(g_ambient_light, model->material.ambient);
|
||||
|
||||
// Diffuse term
|
||||
f32 l_dot_n = dot_v3(norm, g_directional_light.direction);
|
||||
if (l_dot_n <= 0.0f) {
|
||||
goto RETURN_OUTPUT_COLOUR;
|
||||
}
|
||||
|
||||
V3f diffuse = num_mul_v3(g_directional_light.diffuse_intensity,
|
||||
model->material.diffuse * l_dot_n);
|
||||
intensity = add_v3(intensity, diffuse);
|
||||
|
||||
// Specular term
|
||||
V3f _2_l_dot_n_norm = num_mul_v3(norm, 2.0f * l_dot_n);
|
||||
V3f reflected = sub_v3(_2_l_dot_n_norm, g_directional_light.direction);
|
||||
f32 r_dot_v = dot_v3(reflected, data->position);
|
||||
if (r_dot_v <= 0.0f) {
|
||||
goto RETURN_OUTPUT_COLOUR;
|
||||
}
|
||||
|
||||
V3f specular = num_mul_v3(
|
||||
g_directional_light.specular_intensity,
|
||||
powf(model->material.specular * r_dot_v, model->material.shininess));
|
||||
intensity = add_v3(intensity, specular);
|
||||
|
||||
RETURN_OUTPUT_COLOUR:
|
||||
intensity.r = clamp(intensity.r, 0.0f, 1.0f);
|
||||
intensity.g = clamp(intensity.g, 0.0f, 1.0f);
|
||||
intensity.b = clamp(intensity.b, 0.0f, 1.0f);
|
||||
|
||||
local_colour = mul_v3(local_colour, intensity);
|
||||
|
||||
output.r = 255.0f * local_colour.r;
|
||||
output.g = 255.0f * local_colour.g;
|
||||
output.b = 255.0f * local_colour.b;
|
||||
|
||||
return (FragmentResult){.colour = output};
|
||||
}
|
||||
@@ -131,7 +173,7 @@ internal M4x4f get_projection_matrix(ProjectionType projection_type) {
|
||||
}
|
||||
|
||||
internal f32 get_intensity(const V3f *normal) {
|
||||
V3f light = g_directional_light;
|
||||
V3f light = g_directional_light.direction;
|
||||
normalise_v3(light);
|
||||
|
||||
f32 intensity = dot_v3((*normal), light);
|
||||
|
||||
Reference in New Issue
Block a user