Test implementation of phong shader
This commit is contained in:
parent
afc10fb79a
commit
2bea7218db
@ -41,9 +41,9 @@ int main(void) {
|
|||||||
|
|
||||||
PhongMaterial material = {
|
PhongMaterial material = {
|
||||||
.ambient = 0.1f,
|
.ambient = 0.1f,
|
||||||
.diffuse = 0.8f,
|
.diffuse = 1.2f,
|
||||||
.specular = 0.1f,
|
.specular = 0.1f,
|
||||||
.shininess = 0.5f,
|
.shininess = 0.8f,
|
||||||
};
|
};
|
||||||
obj.material = material;
|
obj.material = material;
|
||||||
|
|
||||||
|
@ -33,6 +33,13 @@ struct phong_material {
|
|||||||
f32 shininess;
|
f32 shininess;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef struct directional_light DirectionalLight;
|
||||||
|
struct directional_light {
|
||||||
|
V3f diffuse_intensity;
|
||||||
|
V3f specular_intensity;
|
||||||
|
V3f direction;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct model Model;
|
typedef struct model Model;
|
||||||
struct model {
|
struct model {
|
||||||
LIST_TYPE(V3f) * vertices;
|
LIST_TYPE(V3f) * vertices;
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
|
#include "aliases.h"
|
||||||
#include "img.h"
|
#include "img.h"
|
||||||
|
#include "obj.h"
|
||||||
#include "render.h"
|
#include "render.h"
|
||||||
#include "shader.h"
|
#include "shader.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "vec.h"
|
#include "vec.h"
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
typedef struct shader Shader;
|
typedef struct shader Shader;
|
||||||
struct shader {
|
struct shader {
|
||||||
@ -18,7 +21,12 @@ ShaderID orthographic_albedo = {0};
|
|||||||
internal Shader perspective = {0};
|
internal Shader perspective = {0};
|
||||||
internal Shader orthographic = {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_eye = {0.2f, 0.1f, 0.75f};
|
||||||
internal V3f g_target = {0};
|
internal V3f g_target = {0};
|
||||||
internal V3f g_up = {0.0f, 1.0f, 0.0f};
|
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 FragmentData *data,
|
||||||
const Colour *colour,
|
const Colour *colour,
|
||||||
const Model *model) {
|
const Model *model) {
|
||||||
f32 intensity;
|
V3f norm;
|
||||||
if (model->normal) {
|
if (model->normal) {
|
||||||
u64 nm_x = data->tex_coords.u * model->normal->width;
|
u64 nm_x = data->tex_coords.u * model->normal->width;
|
||||||
u64 nm_y = (1.0f - data->tex_coords.v) * model->normal->height;
|
u64 nm_y = (1.0f - data->tex_coords.v) * model->normal->height;
|
||||||
|
|
||||||
Colour pixel = get_pixel(Colour, model->normal, nm_x, nm_y);
|
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);
|
normalise_v3(norm);
|
||||||
|
|
||||||
intensity = get_intensity(&norm);
|
|
||||||
} else {
|
} else {
|
||||||
intensity = get_intensity(&data->normal);
|
norm = data->normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
Colour output;
|
Colour output;
|
||||||
@ -103,9 +109,45 @@ internal FragmentResult phong_shader_fragment(void *shader,
|
|||||||
output = *colour;
|
output = *colour;
|
||||||
}
|
}
|
||||||
|
|
||||||
output.r = clamp(intensity * output.r, 0.0f, 255.0f);
|
V3f local_colour = {.r = output.r, .g = output.g, .b = output.b};
|
||||||
output.g = clamp(intensity * output.g, 0.0f, 255.0f);
|
local_colour = num_div_v3(local_colour, 255.0f);
|
||||||
output.b = clamp(intensity * output.b, 0.0f, 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};
|
return (FragmentResult){.colour = output};
|
||||||
}
|
}
|
||||||
@ -131,7 +173,7 @@ internal M4x4f get_projection_matrix(ProjectionType projection_type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal f32 get_intensity(const V3f *normal) {
|
internal f32 get_intensity(const V3f *normal) {
|
||||||
V3f light = g_directional_light;
|
V3f light = g_directional_light.direction;
|
||||||
normalise_v3(light);
|
normalise_v3(light);
|
||||||
|
|
||||||
f32 intensity = dot_v3((*normal), light);
|
f32 intensity = dot_v3((*normal), light);
|
||||||
|
@ -90,7 +90,30 @@ MAKE_LIST_TYPE(V2f);
|
|||||||
#define dot_v3(V1, V2) \
|
#define dot_v3(V1, V2) \
|
||||||
((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y + (f32)V1.z * (f32)V2.z)
|
((f32)V1.x * (f32)V2.x + (f32)V1.y * (f32)V2.y + (f32)V1.z * (f32)V2.z)
|
||||||
|
|
||||||
#define num_mul_v3(N, V) ((V3f){.x = N * V.x, .y = N * V.y, .z = N * V.z})
|
#define add_v3(V1, V2) \
|
||||||
|
((V3f){ \
|
||||||
|
.x = V1.x + V2.x, \
|
||||||
|
.y = V1.y + V2.y, \
|
||||||
|
.z = V1.z + V2.z, \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define sub_v3(V1, V2) \
|
||||||
|
((V3f){ \
|
||||||
|
.x = V1.x - V2.x, \
|
||||||
|
.y = V1.y - V2.y, \
|
||||||
|
.z = V1.z - V2.z, \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define mul_v3(V1, V2) \
|
||||||
|
((V3f){ \
|
||||||
|
.x = V1.x * V2.x, \
|
||||||
|
.y = V1.y * V2.y, \
|
||||||
|
.z = V1.z * V2.z, \
|
||||||
|
})
|
||||||
|
|
||||||
|
#define num_mul_v3(V, N) ((V3f){.x = (N) * V.x, .y = (N) * V.y, .z = (N) * V.z})
|
||||||
|
|
||||||
|
#define num_div_v3(V, N) ((V3f){.x = V.x / (N), .y = V.y / (N), .z = V.z / (N)})
|
||||||
|
|
||||||
#define magnitude_v3(V) (sqrtf(dot_v3(V, V)))
|
#define magnitude_v3(V) (sqrtf(dot_v3(V, V)))
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user