antizona

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

commit b5af32e2798ef3ebff4c9e262611a6c80bbcb0bd
parent 9e168f53175fd11c3b955e0b8cfa92e00b5ee5f7
Author: averagecoder <averagecoder@noreply.codeberg.org>
Date:   Mon, 24 Aug 2026 20:22:42 +0300

fix: wrong culling when inside sphere

Diffstat:
Msrc/render.c | 160+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
1 file changed, 91 insertions(+), 69 deletions(-)

diff --git a/src/render.c b/src/render.c @@ -453,14 +453,14 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ v1 = tri->v1; v2 = tri->v2; - min_y = (int)MIN(v0.y, MIN(v1.y, v2.y)); - max_y = (int)MAX(v0.y, MAX(v1.y, v2.y)); + min_y = (int)floorf(MIN(v0.y, MIN(v1.y, v2.y))); + max_y = (int)ceilf(MAX(v0.y, MAX(v1.y, v2.y))); if (max_y < min_y_band || min_y > max_y_band) { return; } - min_x = (int)MIN(v0.x, MIN(v1.x, v2.x)); - max_x = (int)MAX(v0.x, MAX(v1.x, v2.x)); + min_x = (int)floorf(MIN(v0.x, MIN(v1.x, v2.x))); + max_x = (int)ceilf(MAX(v0.x, MAX(v1.x, v2.x))); if (min_x >= WIDTH || max_x < 0) { return; } @@ -550,8 +550,8 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ x_min = (x_long < x_short) ? x_long : x_short; x_max = (x_long < x_short) ? x_short : x_long; - row_min_x = (int)ceilf(x_min - 0.5f); - row_max_x = (int)floorf(x_max - 0.5f); + row_min_x = (int)floorf(x_min); + row_max_x = (int)ceilf(x_max); if (row_min_x < min_x) row_min_x = min_x; if (row_max_x > max_x) row_max_x = max_x; @@ -572,36 +572,39 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ b = (row_w0 * v0.b + row_w1 * v1.b + row_w2 * v2.b) * 255.0f; for (px = row_min_x; px <= row_max_x; px++) { - idx = py * WIDTH + px; - if (inv_w > g_sys->zbuffer[idx] && inv_w >= min_inv_w * 0.99f) { - wf = 1.0f / inv_w; - tx = (int)(u_w * wf * tw) & tw_mask; - ty = (int)(v_w * wf * th) & th_mask; - color = pixels[ty * tw + tx]; - tex_a = (color >> 24) & 0xFF; - if (tex_a > 127) { - ir = (int)r; if (ir > 255) ir = 255; else if (ir < 0) ir = 0; - ig = (int)g_val; if (ig > 255) ig = 255; else if (ig < 0) ig = 0; - ib = (int)b; if (ib > 255) ib = 255; else if (ib < 0) ib = 0; - - tex_r = ((color >> 16) & 0xFF) * ir >> 8; - tex_g = ((color >> 8) & 0xFF) * ig >> 8; - tex_b = (color & 0xFF) * ib >> 8; + if (row_w0 >= -1e-4f && row_w1 >= -1e-4f && row_w2 >= -1e-4f) { + idx = py * WIDTH + px; + if (inv_w >= g_sys->zbuffer[idx] - 1e-6f && inv_w >= min_inv_w * 0.99f) { + wf = 1.0f / inv_w; + tx = (int)(u_w * wf * tw) & tw_mask; + ty = (int)(v_w * wf * th) & th_mask; + color = pixels[ty * tw + tx]; + tex_a = (color >> 24) & 0xFF; + if (tex_a > 127) { + ir = (int)r; if (ir > 255) ir = 255; else if (ir < 0) ir = 0; + ig = (int)g_val; if (ig > 255) ig = 255; else if (ig < 0) ig = 0; + ib = (int)b; if (ib > 255) ib = 255; else if (ib < 0) ib = 0; + + tex_r = ((color >> 16) & 0xFF) * ir >> 8; + tex_g = ((color >> 8) & 0xFF) * ig >> 8; + tex_b = (color & 0xFF) * ib >> 8; + + f = f_w * wf; + if (f > 0.001f) { + if (f > 1.0f) f = 1.0f; + inv_f = 1.0f - f; + tex_r = (uint32_t)(tex_r * inv_f + sky_r * f); + tex_g = (uint32_t)(tex_g * inv_f + sky_g * f); + tex_b = (uint32_t)(tex_b * inv_f + sky_b * f); + } - f = f_w * wf; - if (f > 0.001f) { - if (f > 1.0f) f = 1.0f; - inv_f = 1.0f - f; - tex_r = (uint32_t)(tex_r * inv_f + sky_r * f); - tex_g = (uint32_t)(tex_g * inv_f + sky_g * f); - tex_b = (uint32_t)(tex_b * inv_f + sky_b * f); + g_sys->pixels[idx] = (tex_a << 24) | + (tex_r << 16) | (tex_g << 8) | tex_b; + g_sys->zbuffer[idx] = inv_w; } - - g_sys->pixels[idx] = (tex_a << 24) | - (tex_r << 16) | (tex_g << 8) | tex_b; - g_sys->zbuffer[idx] = inv_w; } } + row_w0 += dw0_dx; row_w1 += dw1_dx; row_w2 -= (dw0_dx + dw1_dx); inv_w += d_inv_w_dx; u_w += d_u_w_dx; v_w += d_v_w_dx; f_w += d_f_w_dx; r += d_r_dx_255; g_val += d_g_dx_255; b += d_b_dx_255; } @@ -628,8 +631,8 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ x_min = (x_long < x_short) ? x_long : x_short; x_max = (x_long < x_short) ? x_short : x_long; - row_min_x = (int)ceilf(x_min - 0.5f); - row_max_x = (int)floorf(x_max - 0.5f); + row_min_x = (int)floorf(x_min); + row_max_x = (int)ceilf(x_max); if (row_min_x < min_x) row_min_x = min_x; if (row_max_x > max_x) row_max_x = max_x; @@ -643,44 +646,47 @@ draw_triangle_band(const struct render_triangle *tri, int min_y_band, int max_y_ inv_w = row_w0 * v0.w + row_w1 * v1.w + row_w2 * v2.w; u_w = row_w0 * u0_w + row_w1 * u1_w + row_w2 * u2_w; - v_w = row_w0 * v0_w + row_w1 * v1_w + row_w2 * v2.w; + v_w = row_w0 * v0_w + row_w1 * v1_w + row_w2 * v2_w; f_w = row_w0 * f0_w + row_w1 * f1_w + row_w2 * f2_w; r = (row_w0 * v0.r + row_w1 * v1.r + row_w2 * v2.r) * 255.0f; g_val = (row_w0 * v0.g + row_w1 * v1.g + row_w2 * v2.g) * 255.0f; b = (row_w0 * v0.b + row_w1 * v1.b + row_w2 * v2.b) * 255.0f; for (px = row_min_x; px <= row_max_x; px++) { - idx = py * WIDTH + px; - if (inv_w > g_sys->zbuffer[idx] && inv_w >= min_inv_w * 0.99f) { - ir = (int)r; if (ir > 255) ir = 255; else if (ir < 0) ir = 0; - ig = (int)g_val; if (ig > 255) ig = 255; else if (ig < 0) ig = 0; - ib = (int)b; if (ib > 255) ib = 255; else if (ib < 0) ib = 0; - wf = 1.0f / inv_w; - - tx = (int)(u_w * wf * tw) & tw_mask; - ty = (int)(v_w * wf * th) & th_mask; - color = pixels[ty * tw + tx]; - - wa = (wa_tc * ((color >> 24) & 0xFF)) >> 8; - tex_r = ((((color >> 16) & 0xFF) * ir >> 8) * wr) >> 8; - tex_g = ((((color >> 8) & 0xFF) * ig >> 8) * wg) >> 8; - tex_b = ((color & 0xFF) * ib >> 8) * wb >> 8; - - f = f_w * wf; - if (f > 0.001f) { - if (f > 1.0f) f = 1.0f; - inv_f = 1.0f - f; - tex_r = (uint32_t)(tex_r * inv_f + sky_r * f); - tex_g = (uint32_t)(tex_g * inv_f + sky_g * f); - tex_b = (uint32_t)(tex_b * inv_f + sky_b * f); - } + if (row_w0 >= -1e-4f && row_w1 >= -1e-4f && row_w2 >= -1e-4f) { + idx = py * WIDTH + px; + if (inv_w >= g_sys->zbuffer[idx] - 1e-6f && inv_w >= min_inv_w * 0.99f) { + ir = (int)r; if (ir > 255) ir = 255; else if (ir < 0) ir = 0; + ig = (int)g_val; if (ig > 255) ig = 255; else if (ig < 0) ig = 0; + ib = (int)b; if (ib > 255) ib = 255; else if (ib < 0) ib = 0; + wf = 1.0f / inv_w; + + tx = (int)(u_w * wf * tw) & tw_mask; + ty = (int)(v_w * wf * th) & th_mask; + color = pixels[ty * tw + tx]; - bg = g_sys->pixels[idx]; - g_sys->pixels[idx] = (0xFF << 24) | - (((tex_r * wa + ((bg >> 16) & 0xFF) * (255 - wa)) >> 8) << 16) | - (((tex_g * wa + ((bg >> 8) & 0xFF) * (255 - wa)) >> 8) << 8) | - ((tex_b * wa + (bg & 0xFF) * (255 - wa)) >> 8); + wa = (wa_tc * ((color >> 24) & 0xFF)) >> 8; + tex_r = ((((color >> 16) & 0xFF) * ir >> 8) * wr) >> 8; + tex_g = ((((color >> 8) & 0xFF) * ig >> 8) * wg) >> 8; + tex_b = ((color & 0xFF) * ib >> 8) * wb >> 8; + + f = f_w * wf; + if (f > 0.001f) { + if (f > 1.0f) f = 1.0f; + inv_f = 1.0f - f; + tex_r = (uint32_t)(tex_r * inv_f + sky_r * f); + tex_g = (uint32_t)(tex_g * inv_f + sky_g * f); + tex_b = (uint32_t)(tex_b * inv_f + sky_b * f); + } + + bg = g_sys->pixels[idx]; + g_sys->pixels[idx] = (0xFF << 24) | + (((tex_r * wa + ((bg >> 16) & 0xFF) * (255 - wa)) >> 8) << 16) | + (((tex_g * wa + ((bg >> 8) & 0xFF) * (255 - wa)) >> 8) << 8) | + ((tex_b * wa + (bg & 0xFF) * (255 - wa)) >> 8); + } } + row_w0 += dw0_dx; row_w1 += dw1_dx; row_w2 -= (dw0_dx + dw1_dx); inv_w += d_inv_w_dx; u_w += d_u_w_dx; v_w += d_v_w_dx; f_w += d_f_w_dx; r += d_r_dx_255; g_val += d_g_dx_255; b += d_b_dx_255; } @@ -2227,12 +2233,28 @@ draw_scene(struct sys_gfx *g, const struct mat4 *proj, const struct mat4 *view, mc.y = g_transforms.sphere_cy[id]; mc.z = g_transforms.sphere_cz[id]; r = g_transforms.sphere_r[id] * 1.05f; - mat_transform(&cv, &w, view, &mc); - if (cv.z + r < 0.1f || cv.z - r > far_clp || - fabsf(cv.x) - r > cv.z * fov_x || - fabsf(cv.y) - r > cv.z * fov_y) { - continue; + + dx = mc.x - cam_x; + dy = mc.y - cam_y; + dz = mc.z - cam_z; + dist_sq = dx * dx + dy * dy + dz * dz; + + if (dist_sq > r * r) { + mat_transform(&cv, &w, view, &mc); + + if (cv.z + r < 0.1f || cv.z - r > far_clp) { + continue; + } + if (cv.z > 0.0f) { + if (fabsf(cv.x) - r > cv.z * fov_x || + fabsf(cv.y) - r > cv.z * fov_y) { + continue; + } + } + } else { + mat_transform(&cv, &w, view, &mc); } + if (is_occluded(g, cv.x, cv.y, cv.z, r)) { continue; }