diff options
Diffstat (limited to 'kon/kon3d.c')
| -rw-r--r-- | kon/kon3d.c | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/kon/kon3d.c b/kon/kon3d.c index 6d6cee7..8e5c106 100644 --- a/kon/kon3d.c +++ b/kon/kon3d.c @@ -271,6 +271,17 @@ static float *kon_corner_(const kon_terrain_t *terrain, int column, int row) return &terrain->heights[(size_t)row * (size_t)(terrain->columns + 1) + (size_t)column]; } +/* the slope at a corner from the corners around it, so the light does not jump between triangles */ +static kon_vec3_t kon_cornerNormal_(const kon_terrain_t *terrain, int column, int row) +{ + int x0 = column > 0 ? column - 1 : column, x1 = column < terrain->columns ? column + 1 : column; + int z0 = row > 0 ? row - 1 : row, z1 = row < terrain->rows ? row + 1 : row; + float dx = *kon_corner_(terrain, x0, row) - *kon_corner_(terrain, x1, row); + float dz = *kon_corner_(terrain, column, z0) - *kon_corner_(terrain, column, z1); + + return kon_vec3Normalize(KON_VEC3(dx / (float)(x1 - x0), 1.0f, dz / (float)(z1 - z0))); +} + static void kon_chunkBounds_(kon_terrain_t *terrain, int cx, int cz) { int x0 = cx * terrain->chunk, z0 = cz * terrain->chunk; @@ -578,8 +589,23 @@ void kon_drawTerrain(kon_framebuffer_t *fb, const kon_camera_t *camera, const ko kon_vec3_t a = KON_VEC3((float)x, ha, (float)z), b = KON_VEC3((float)x + 1, hb, (float)z); kon_vec3_t c = KON_VEC3((float)x + 1, hc, (float)z + 1), d = KON_VEC3((float)x, hd, (float)z + 1); kon_vec3_t upper = kon_vec3Normalize(KON_VEC3(hd - hc, 1.0f, ha - hd)), lower = kon_vec3Normalize(KON_VEC3(ha - hb, 1.0f, hb - hc)); - kon_vertex_t va = { a, upper, KON_VEC2((float)x, (float)z) }, vd = { d, upper, KON_VEC2((float)x, (float)z + 1) }, vc = { c, upper, KON_VEC2((float)x + 1, (float)z + 1) }; - kon_vertex_t wa = { a, lower, va.uv }, wc = { c, lower, vc.uv }, wb = { b, lower, KON_VEC2((float)x + 1, (float)z) }; + kon_vec3_t na = upper, nb = lower, nc = upper, nd = upper; + kon_vertex_t va, vd, vc, wa, wc, wb; + + if (!terrain->faceted) { + na = kon_cornerNormal_(terrain, x, z); + nb = kon_cornerNormal_(terrain, x + 1, z); + nc = kon_cornerNormal_(terrain, x + 1, z + 1); + nd = kon_cornerNormal_(terrain, x, z + 1); + } + va.position = a; va.normal = na; va.uv = KON_VEC2((float)x, (float)z); + vd.position = d; vd.normal = nd; vd.uv = KON_VEC2((float)x, (float)z + 1); + vc.position = c; vc.normal = nc; vc.uv = KON_VEC2((float)x + 1, (float)z + 1); + wa = va; wc = vc; wb.position = b; wb.normal = nb; wb.uv = KON_VEC2((float)x + 1, (float)z); + if (terrain->faceted) { + wa.normal = lower; + wc.normal = lower; + } kon_drawTriangle3D(fb, vp, va, vd, vc, terrain->material, light, KON_RENDER_DEFAULT); kon_drawTriangle3D(fb, vp, wa, wc, wb, terrain->material, light, KON_RENDER_DEFAULT); |
