Implement shading based on vertex normals

This commit is contained in:
Abdelrahman Said 2024-08-11 19:53:07 +01:00
parent d323c0ae14
commit 643da4e58d
2 changed files with 38165 additions and 38177 deletions
resources
src

File diff suppressed because it is too large Load Diff

@ -60,8 +60,9 @@ internal void render_triangle(const Triangle *triangle, const Model *model,
Render *render, Colour colour, RenderType type,
ProjectionType projection);
internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
V3f normals[TRIANGLE_VERTICES],
V2f coordinates[TRIANGLE_VERTICES], Colour colour,
f32 intensity, Image *texture);
Image *texture, RenderType type);
internal void reorder_points(V2u vertices[TRIANGLE_VERTICES],
V2f coordinates[TRIANGLE_VERTICES]);
internal TriangleBBox get_triangle_bbox(const Image *img,
@ -242,30 +243,15 @@ internal void render_triangle(const Triangle *triangle, const Model *model,
draw_line(img, x0, y0, x1, y1, colour);
}
} else if (type == RENDER_TYPE_FILLED || type == RENDER_TYPE_SHADED) {
f32 intensity = 1.0f;
if (type == RENDER_TYPE_SHADED) {
V3f ab = V3(V3f, f32, vertices[0].x, vertices[0].y, vertices[0].z,
vertices[1].x, vertices[1].y, vertices[1].z);
V3f ac = V3(V3f, f32, vertices[0].x, vertices[0].y, vertices[0].z,
vertices[2].x, vertices[2].y, vertices[2].z);
V3f normal = cross_product(ac, ab);
normalise_v3(normal);
intensity = dot_v3(normal, g_light_dir);
}
if (intensity > 0.0f) {
fill_triangle(render, vertices, coordinates, colour, intensity,
model->texture);
}
fill_triangle(render, vertices, normals, coordinates, colour,
model->texture, type);
}
}
internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
V3f normals[TRIANGLE_VERTICES],
V2f coordinates[TRIANGLE_VERTICES], Colour colour,
f32 intensity, Image *texture) {
Image *texture, RenderType type) {
Image *img = &(render->img);
Depth *depth = &(render->depth);
TriangleBBox bbox = get_triangle_bbox(img, vertices);
@ -285,14 +271,12 @@ internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
V3f coords;
f32 z;
f32 zbuf;
f32 nx, ny, nz;
V3f normal;
f32 tx_u, tx_v;
u64 tx_x, tx_y;
if (!texture) {
colour.r *= intensity;
colour.g *= intensity;
colour.b *= intensity;
}
f32 intensity = 1.0f;
for (u64 y = bbox.y0; y <= bbox.y1; ++y) {
for (u64 x = bbox.x0; x <= bbox.x1; ++x) {
@ -308,6 +292,21 @@ internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
zbuf = get_pixel(f32, &(render->depth), x, y);
if (z > zbuf) {
if (type == RENDER_TYPE_SHADED) {
nx = normals[0].x * coords.x + normals[1].x * coords.y +
normals[2].x * coords.z;
ny = normals[0].y * coords.x + normals[1].y * coords.y +
normals[2].y * coords.z;
nz = normals[0].z * coords.x + normals[1].z * coords.y +
normals[2].z * coords.z;
normal = (V3f){nx, ny, nz};
intensity = dot_v3(normal, g_light_dir);
}
if (intensity < 0.0f) {
continue;
}
if (texture) {
tx_u = coordinates[0].u * coords.x + coordinates[1].u * coords.y +
coordinates[2].u * coords.z;
@ -317,11 +316,12 @@ internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
tx_y = (1.0f - tx_v) * texture->height;
colour = get_pixel(Colour, texture, tx_x, tx_y);
colour.r *= intensity;
colour.g *= intensity;
colour.b *= intensity;
}
colour.r *= intensity;
colour.g *= intensity;
colour.b *= intensity;
set_pixel(depth, x, y, &z);
set_pixel(img, x, y, &colour);
}