Implement shading based on vertex normals
This commit is contained in:
parent
d323c0ae14
commit
643da4e58d
76286
resources/head.obj
76286
resources/head.obj
File diff suppressed because it is too large
Load Diff
56
src/obj.c
56
src/obj.c
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user