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,
|
Render *render, Colour colour, RenderType type,
|
||||||
ProjectionType projection);
|
ProjectionType projection);
|
||||||
internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
|
internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
|
||||||
|
V3f normals[TRIANGLE_VERTICES],
|
||||||
V2f coordinates[TRIANGLE_VERTICES], Colour colour,
|
V2f coordinates[TRIANGLE_VERTICES], Colour colour,
|
||||||
f32 intensity, Image *texture);
|
Image *texture, RenderType type);
|
||||||
internal void reorder_points(V2u vertices[TRIANGLE_VERTICES],
|
internal void reorder_points(V2u vertices[TRIANGLE_VERTICES],
|
||||||
V2f coordinates[TRIANGLE_VERTICES]);
|
V2f coordinates[TRIANGLE_VERTICES]);
|
||||||
internal TriangleBBox get_triangle_bbox(const Image *img,
|
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);
|
draw_line(img, x0, y0, x1, y1, colour);
|
||||||
}
|
}
|
||||||
} else if (type == RENDER_TYPE_FILLED || type == RENDER_TYPE_SHADED) {
|
} else if (type == RENDER_TYPE_FILLED || type == RENDER_TYPE_SHADED) {
|
||||||
f32 intensity = 1.0f;
|
fill_triangle(render, vertices, normals, coordinates, colour,
|
||||||
|
model->texture, type);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
|
internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
|
||||||
|
V3f normals[TRIANGLE_VERTICES],
|
||||||
V2f coordinates[TRIANGLE_VERTICES], Colour colour,
|
V2f coordinates[TRIANGLE_VERTICES], Colour colour,
|
||||||
f32 intensity, Image *texture) {
|
Image *texture, RenderType type) {
|
||||||
Image *img = &(render->img);
|
Image *img = &(render->img);
|
||||||
Depth *depth = &(render->depth);
|
Depth *depth = &(render->depth);
|
||||||
TriangleBBox bbox = get_triangle_bbox(img, vertices);
|
TriangleBBox bbox = get_triangle_bbox(img, vertices);
|
||||||
@ -285,14 +271,12 @@ internal void fill_triangle(Render *render, V3f vertices[TRIANGLE_VERTICES],
|
|||||||
V3f coords;
|
V3f coords;
|
||||||
f32 z;
|
f32 z;
|
||||||
f32 zbuf;
|
f32 zbuf;
|
||||||
|
f32 nx, ny, nz;
|
||||||
|
V3f normal;
|
||||||
f32 tx_u, tx_v;
|
f32 tx_u, tx_v;
|
||||||
u64 tx_x, tx_y;
|
u64 tx_x, tx_y;
|
||||||
|
|
||||||
if (!texture) {
|
f32 intensity = 1.0f;
|
||||||
colour.r *= intensity;
|
|
||||||
colour.g *= intensity;
|
|
||||||
colour.b *= intensity;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (u64 y = bbox.y0; y <= bbox.y1; ++y) {
|
for (u64 y = bbox.y0; y <= bbox.y1; ++y) {
|
||||||
for (u64 x = bbox.x0; x <= bbox.x1; ++x) {
|
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);
|
zbuf = get_pixel(f32, &(render->depth), x, y);
|
||||||
|
|
||||||
if (z > zbuf) {
|
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) {
|
if (texture) {
|
||||||
tx_u = coordinates[0].u * coords.x + coordinates[1].u * coords.y +
|
tx_u = coordinates[0].u * coords.x + coordinates[1].u * coords.y +
|
||||||
coordinates[2].u * coords.z;
|
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;
|
tx_y = (1.0f - tx_v) * texture->height;
|
||||||
|
|
||||||
colour = get_pixel(Colour, texture, tx_x, tx_y);
|
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(depth, x, y, &z);
|
||||||
set_pixel(img, x, y, &colour);
|
set_pixel(img, x, y, &colour);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user