I have two ways of doing frustum culling taken from different web sources. First one takes 200ms to check 10k AABBs, second around 50ms for the same box count. I read some forum answers, people say 0.5ms for 10k is ok but I'm totally far away from those numbers. So what am I doing wrong ?
Measuring time here:
auto frustum = camera.getFrustum(); //frustum
auto n = frustum.pNear;
auto f = frustum.pFar;
auto e = frustum.pExtra;
ArrayList<Pair<vec3, vec3>> planes;
ArrayList<vec3> v1;
n.genVertices(v1);
ArrayList<vec3> v2;
f.genVertices(v2);
planes << Pair<vec3,vec3>(v1[0], -n.genNormal());
planes << Pair<vec3,vec3>(v2[0], n.genNormal());
for(size_t i = 0; i < 4; i++)
{
planes << e[i];
} //frustum planes array initialization done
ArrayList<AABB> objs; //10k test aabbs
for(size_t i = 0; i < 10000; i++)
{
objs << AABB(vec3(rand_float()/100,rand_float()/100,rand_float()/100),rand_float()/100);
}
auto t1 = timer.getTimeNanoSeconds(); //starting to measure
for(size_t i = 0; i < 10000; i++)
{
rs::CollisionEngine::checkAABBAndFrustumFast(objs[i], planes);
}
auto t2 = timer.getTimeNanoSeconds() - t1; //getting time
println("Collision check of 10k objs: "+ toString(t2/1000000) + " ms"); //printing time
Here is slow and fast collision checks:
/**
*
* @param box
* @return 0 - inside, 1 - intersects, 2 - outside
*/
us checkAABBAndFrustumSlow(AABB box, ArrayList<Pair<vec3, vec3>>& planes)
{
ArrayList<vec3> vertices;
box.genVertices(vertices);
us totalIn = 0;
for(int i = 0;i<6;i++){ //six planes for every frustum
Pair<vec3, vec3> plane = planes[i];
auto n = plane.v2;
uint inCount = 8;
uint pIn = 1;
for(int j= 0;j<8;j++){
vec3 v = vertices[j];
vec3 toVertex = (v - plane.v1).normalize();
float res = n * toVertex;
if(res < 0){
inCount -=1;
pIn = 0;
}
}
if(inCount == 0) return 2;
totalIn += pIn;
}
if(totalIn == 6) return 0;
return 1;
}
using namespace rs;
vec3 getPosForFrustum(AABB b, vec3 n)
{
vec3 max = b.center + b.extent;
vec3 p = b.center - b.extent;
if (n.x() >= 0)
p(1) = max.x();
if (n.y() >=0)
p(2) = max.y();
if (n.z() >= 0)
p(3) = max.z();
return p;
}
vec3 getNegForFrustum(AABB b, vec3 n)
{
vec3 min = b.center - b.extent;
vec3 p = b.center + b.extent;
if (n.x() >= 0)
p(1) = min.x();
if (n.y() >=0)
p(2) = min.y();
if (n.z() >= 0)
p(3) = min.z();
return p;
}
uint checkAABBAndFrustumFast(AABB box, ArrayList<Pair<vec3, vec3>>& planes){
uint result = 0;
for(int i = 0;i<6;i++) {
auto n = planes[i].v2;
auto p = planes[i].v1;
if (n * (getPosForFrustum(box, n) - p) < 0)
return 2;
else if (n * (getNegForFrustum(box, n) - p) < 0)
result = 1;
}
return result;
}
EDIT: ArrayList is a custom vector like structure
Pair contains a copy of two objects it takes.
checkAABBAndFrustumSlow
function in more functions then use a profiler to identify what's taking the longest time to execute (or even more counters). \$\endgroup\$