mirror of
https://git.coom.tech/drummyfish/small3dlib.git
synced 2024-11-21 20:39:57 +01:00
Fix near culling
This commit is contained in:
parent
8c00c5d7fd
commit
246cb2a8cc
2 changed files with 21 additions and 15 deletions
32
small3dlib.h
32
small3dlib.h
|
@ -260,7 +260,13 @@ typedef uint16_t S3L_Index;
|
||||||
|
|
||||||
#ifndef S3L_NEAR
|
#ifndef S3L_NEAR
|
||||||
#define S3L_NEAR (S3L_FRACTIONS_PER_UNIT / 4) /**< Distance of the near
|
#define S3L_NEAR (S3L_FRACTIONS_PER_UNIT / 4) /**< Distance of the near
|
||||||
clipping plane. */
|
clipping plane. Points in front or EXATLY ON
|
||||||
|
this plane are considered outside the
|
||||||
|
frustum. This must be >= 0. */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if S3L_NEAR <= 0
|
||||||
|
#define S3L_NEAR 1 // Can't be <= 0.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef S3L_FAST_LERP_QUALITY
|
#ifndef S3L_FAST_LERP_QUALITY
|
||||||
|
@ -1722,20 +1728,14 @@ void S3L_makeCameraMatrix(S3L_Transform3D cameraTransform, S3L_Mat4 *m)
|
||||||
S3L_mat4Xmat4(m,&r);
|
S3L_mat4Xmat4(m,&r);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Performs perspecive division (z-divide). Does NOT check for division by zero.
|
||||||
|
*/
|
||||||
static inline void S3L_perspectiveDivide(S3L_Vec4 *vector,
|
static inline void S3L_perspectiveDivide(S3L_Vec4 *vector,
|
||||||
S3L_Unit focalLength)
|
S3L_Unit focalLength)
|
||||||
{
|
{
|
||||||
S3L_Unit divisor = vector->z > 0 ? vector->z : (-1 * (vector->z - 1));
|
vector->x = (vector->x * focalLength) / vector->z;
|
||||||
/* ^ This has two purposes:
|
vector->y = (vector->y * focalLength) / vector->z;
|
||||||
|
|
||||||
1. Prevent division by zero.
|
|
||||||
2. Prevent a "rapid flip" of the vertex, e.g.: having a vertex
|
|
||||||
[100,0,0.1] z-divides it to [1000,0], but when it shift a short
|
|
||||||
distance to [100,0,-0.1], it z-divides to [-1000,0], rapidly flipping
|
|
||||||
from right to the left. */
|
|
||||||
|
|
||||||
vector->x = (vector->x * focalLength) / divisor;
|
|
||||||
vector->y = (vector->y * focalLength) / divisor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1756,7 +1756,7 @@ static inline int8_t S3L_triangleIsVisible(
|
||||||
if ( // outside frustum?
|
if ( // outside frustum?
|
||||||
|
|
||||||
#if S3L_STRICT_NEAR_CULLING
|
#if S3L_STRICT_NEAR_CULLING
|
||||||
p0.z < S3L_NEAR || p1.z < S3L_NEAR || p2.z < S3L_NEAR ||
|
p0.z <= S3L_NEAR || p1.z <= S3L_NEAR || p2.z <= S3L_NEAR ||
|
||||||
// ^ partially in front of NEAR?
|
// ^ partially in front of NEAR?
|
||||||
#else
|
#else
|
||||||
clipTest(z,<=,S3L_NEAR) || // completely in front of NEAR?
|
clipTest(z,<=,S3L_NEAR) || // completely in front of NEAR?
|
||||||
|
@ -1812,6 +1812,12 @@ void _S3L_projectVertex(
|
||||||
|
|
||||||
S3L_vec3Xmat4(result,projectionMatrix);
|
S3L_vec3Xmat4(result,projectionMatrix);
|
||||||
|
|
||||||
|
result->z = result->z >= S3L_NEAR ? result->z : S3L_NEAR;
|
||||||
|
/* ^ This firstly prevents zero division in the follwoing z-divide and
|
||||||
|
secondly "pushes" vertices that are in front of near a little bit forward,
|
||||||
|
which makes the behave a bit better. If all three vertices end up exactly
|
||||||
|
on NEAR, the triangle will be culled. */
|
||||||
|
|
||||||
S3L_perspectiveDivide(result,focalLength);
|
S3L_perspectiveDivide(result,focalLength);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
//#define S3L_PRESET_HIGHEST_QUALITY
|
//#define S3L_PRESET_HIGHEST_QUALITY
|
||||||
|
|
||||||
#define S3L_FLAT 0
|
#define S3L_FLAT 0
|
||||||
#define S3L_STRICT_NEAR_CULLING 1
|
#define S3L_STRICT_NEAR_CULLING 0
|
||||||
#define S3L_PERSPECTIVE_CORRECTION 1
|
#define S3L_PERSPECTIVE_CORRECTION 1
|
||||||
#define S3L_SORT 0
|
#define S3L_SORT 0
|
||||||
#define S3L_Z_BUFFER 1
|
#define S3L_Z_BUFFER 1
|
||||||
|
|
Loading…
Reference in a new issue