I did Frustum Culling in my engine, but it does not work correctly. All shown in the video:
If the approximation is too close, the model disappears. On the right in the console you can see that one model is rendered less. With what it can be connected?
Frustum creation code:
bool FrustumCulling::update(ID3D11Device* device, const Camera & view, float angle, float ratio, float _near, float rear)
{
Vector3 pos = (Vector3)view.getViewPosition();
Vector3 d = pos - (Vector3)view.getViewDirection();
d.normalize();
Vector3 right = (Vector3)view.getViewHeight();
right = right.cross(d);
right.normalize();
Vector3 up = Vector3::cross(d, right);
// get h and w near and rear planes
float val = angle * 0.5;
float tang = (float)tan(val);
float nh = _near * tang; // near height
float nw = nh * ratio; // near width
float rh = rear * tang; // rear height
float rw = rh * ratio; // near width
// generate 8 vertex frustum
Vector3 fc = pos - d * rear;
Vector3 ftl = fc + up * rh - right * rw; // ftl - Far(rear) Top Left
Vector3 ftr = fc + up * rh + right * rw;
Vector3 fbl = fc - up * rh - right * rw;
Vector3 fbr = fc - up * rh + right * rw;
Vector3 nc = pos - d * _near;
Vector3 ntl = nc + up * nh - right * nw;
Vector3 ntr = nc + up * nh + right * nw;
Vector3 nbl = nc - up * nh - right * nw;
Vector3 nbr = nc - up * nh + right * nw;
// generate 6 planes frustum
Plane3 p(ntr, ntl, ftl);
data.planes[TOP] = PlanesFrustum(p.getPlane());
p = Plane3(nbl, nbr, fbr);
data.planes[BOTTOM] = PlanesFrustum(p.getPlane());
p = Plane3(ntl, nbl, fbl);
data.planes[LEFT] = PlanesFrustum(p.getPlane());
p = Plane3(nbr, ntr, fbr);
data.planes[RIGHT] = PlanesFrustum(p.getPlane());
p = Plane3(ftr, ftl, fbl);
data.planes[FARP] = PlanesFrustum(p.getPlane());
p = Plane3(ntl, ntr, nbr);
data.planes[NEARP] = PlanesFrustum(p.getPlane());
}
Model verification code (cube bbox) to hit frustum:
bool modelCheckFrustum(Vector3 * v)
{
for(int k = 0;k<8;k++)
{
Vector3 p0 = v[k];
int isFrustum(0);
for(int l = 0; l<PLANES_SIZE;l++)
{
Vector4 n = planes[l].pl; //
float value = shortDistanseFromPointToPlane(n, p0);
if(value > 0.f) // point in current plane
++isFrustum;
}
if (isFrustum == PLANES_SIZE)// point in frusrtum
return true; // model in frustum
}
return false; // model not in frustum
}
PLANES_SIZE - count planes, == 6
planes - array planes frustum
planes - Vector4, when x,y,z - a,b,c, and w - d
Method shortDistanseFromPointToPlane:
float shortDistanseFromPointToPlane(Vector4 p, Vector3 p0)
{
return p.x*p0.x + p.y*p0.y + p.z*p0.z + p.w;
}
Distance to the front and rear planes:
float SCREEN_DEPTH = 1000.f;
float SCREEN_NEAR = 0.01f;
Creating a matrix of perspectives:
matrixProjection = Matrix::CreatePerspectiveFovLHMatrix(GeneralMath::PI / 4, w / (float)h, SCREEN_NEAR, SCREEN_DEPTH);
w, i - width and height window
How to fix this nasty bug? Thank.
P.S.: I did frustum culing in this lesson.
UPD1:
I created a model frustum, and it shows that not a single BBox vertex got inside the frustum. Now I know the reason, it remains to come up with a solution to this problem :)