Many of you have seen my terrain examples and you know it was plagued with culling problems.

I think I've come up with a reason for the algorithm failing.

The frustum is computed by combining the matWorldView and matWorldProj matrices. This means the frustum is being computed in world space. So if I just send the vertex positions of the terrain to the cull function, it won't be correct.

Here is why. The terrain is not transformed into world space. It is assumed to always lie at 0,0,0 or the center of the entire world. I assumed this meant the terrain vertices were in world space when in fact they are in object space, not world space. It would be no different than having a huge flat grid and not transforming it to world space.

So how do I transform the terrain vertices to world space w/o always having the terrain centered around the camera at the same place? Also since the terrain is the world, is there a need to transform the terrain to world space and then can I assume my vertices are in world space?

The clipping still causes issues at the edges of the screen with viewing changes of 20 degrees or more on any axis. This is not desireable but all the sources I've checked state the algo I'm using should actually still render those objects which may actually lie outside of the frustum.

My culling algo is too perfect and needs some work. Any help or ideas is greatly appreciated. I've downloaded over 30 documents concerning this, bought 3 new books, and still having problems.

Sites to check out:

http://www.realtimerendering.com/

http://www.geometrictools.com/Intersection.html

http://www.toymaker.info/Games/html/..._faq.html#D3D6

http://www.flipcode.com/articles/art...mculling.shtml

http://www.lighthouse3d.com/opengl/viewfrustum/

http://research.microsoft.com/~hoppe/

http://www.vterrain.org/

http://personal.inet.fi/atk/cxengine/docs/issue2.html

This was taken from an article explaining how to extract the planes for the frustum in D3D w/o using D3DXPLANE. I have another source that explains how to do it using D3DXPLANE.

The only code I can come up with to perform this operation is:Until now we have assumed that both, the world and the view matrix are identity matrices. However, the goal

obviously is to make the algorithm work for an arbitrary view. This is, in fact, so easy that it’s almost unbelievable.

If you think about it for a moment then you’ll immediately understand it, and that’s why we are not going to explain

this in any great detail. All we are giving to you is this:

1. If the matrixMis equal to the projection matrix P (i.e., = M P), then the algorithm gives the clipping planes

in view space (i.e., camera space).

2. If the matrixMis equal to the combined view and projection matrices, then the algorithm gives the clipping

planes in world space (i.e., = ⋅ M V P, where V is the view matrix, and P is the projection matrix).

3. If the matrix Mis equal to the combined world, view, and projection matrices, then the algorithm gives the

clipping planes in object space (i.e., = ⋅ ⋅ M W V P, where Wis the world matrix, V is the view matrix, and

P is the projection matrix).

4. and so on...

This does not check to see if the camera is inside of the frustum and does not check to see if the frustum can actually contain the bounding volume.Code:void Terrain::Render(float fTimeDelta,D3DXVECTOR3 vecCameraPos,D3DXMATRIX &matView,D3DXMATRIX &matProj) { D3DXMATRIX matTrans; D3DXMatrixTranslation(&matTrans,-vecCameraPos.x,-vecCameraPos.y,-vecCameraPos.z); m_pDevice->SetTransform(D3DTS_WORLD,&matTrans); m_pFrustum->Compute(&matView,&matProj); RenderNodes(m_pRoot); } void Terrain::RenderNodes(TerrainNode *pNode) { static bool bCullCheck=true; int iResult=CULL_IN; if (bCullCheck) iResult=m_pFrustum->CullAABB(pNode->vecMin,pNode->vecMax); //Bail on this branch if out if (iResult==CULL_OUT) return; if (iResult==CULL_IN || iResult==CULL_INTERSECT) { if (pNode->m_iType==QUAD_LEAF) { //Render geometry bCullCheck=true; } else { //If parent is in, children are definitely in if (iResult==CULL_IN) { bCullCheck=false; } else bCullCheck=true; RenderNodes(pNode->UL); RenderNodes(pNode->UR); RenderNodes(pNode->LL); RenderNodes(pNode>LR); } } }