Skip to content

Instantly share code, notes, and snippets.

@slembcke
Last active December 9, 2020 14:43
Show Gist options
  • Save slembcke/b2b2af4dede1d5702a635dc2d0e45d54 to your computer and use it in GitHub Desktop.
Save slembcke/b2b2af4dede1d5702a635dc2d0e45d54 to your computer and use it in GitHub Desktop.
/*
* Used for culling tiles in a map renderer I wrote.
* All tiles used geometry in the [-1, 1] range, and their mvp matrix would get precalculated.
* So it was simply a matter of seeing if their projected OBB overlapped with the screen's clip space.
* Returns true if the cube is visible. (false positives for near misses due to conservative w-value)
*/
static inline bool MapTileFrustumCull(const mat4 mvp){
// Clip space center of the cube is the last column of the matrix.
vec4 c = {mvp.m[12], mvp.m[13], mvp.m[14], mvp.m[15]};
// Clip space extents are the component wise absolute values of the first three columns.
float ex = fabsf(mvp.m[ 0]) + fabsf(mvp.m[ 4]) + fabsf(mvp.m[ 8]);
float ey = fabsf(mvp.m[ 1]) + fabsf(mvp.m[ 5]) + fabsf(mvp.m[ 9]);
float ez = fabsf(mvp.m[ 2]) + fabsf(mvp.m[ 6]) + fabsf(mvp.m[10]);
// Calculate a conservative w-value for the center.
float w = fmaxf(0, c.w + fabsf(mvp.m[ 3]) + fabsf(mvp.m[ 7]) + fabsf(mvp.m[11]));
// Compare the center coord against the screen's clip space bounds using the w-value.
return ((fabsf(c.x) - ex < w) && (fabsf(c.y) - ey < w) && (fabsf(c.z) - ez < w));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment