Sign in to follow this  
renanrosa

Frustum Culling - render only near

Recommended Posts

hi guys, how do I know the distance from the NEAR frustum culling? why things that are further away do not want to render. example, if an object is more than 20 in the shaft will not be rendered, only the things near to the field of vision. see: thank :)

Share this post


Link to post
Share on other sites
Without seeing any code it is hard to tell. Looks like you've got the "In frustum" code wrong or you've set your frustum up smaller than you want.

When you check if an object is in the view frustum you must check the distance from each frustum plane (make sure they all face the same direction). If all planes face inwards, then if all the distances are positive the object is in the frustum. Make the first check you preform be the near plane, store its value and you can then pass it back and then you know the distance an object is from the near plane for any sorting you might need to do.

Post your code for checking if an object is in the frustum. Another thing to check is the near and far planes of any projections you may have setup for rendering.

Share this post


Link to post
Share on other sites
Quote:
Original post by Nanoha
Without seeing any code it is hard to tell. Looks like you've got the "In frustum" code wrong or you've set your frustum up smaller than you want.
..


wow, sorry,
see my cod:
class FrustumCulling:

FrustumCulling::FrustumCulling() // <- Construtor
{

}

bool FrustumCulling::refresh()
{

g_pd3dDevice->GetTransform(D3DTS_PROJECTION, &matProj);
g_pd3dDevice->GetTransform(D3DTS_VIEW, &matView);

D3DXMatrixMultiply(&matFinal, &matView, &matProj);

//left
m_Planes[0].a = matFinal._14 + matFinal._13;
m_Planes[0].b = matFinal._24 + matFinal._23;
m_Planes[0].c = matFinal._34 + matFinal._33;
m_Planes[0].d = matFinal._44 + matFinal._43;
D3DXPlaneNormalize(&m_Planes[0], &m_Planes[0]);

//right
m_Planes[1].a = matFinal._14 - matFinal._13;
m_Planes[1].b = matFinal._24 - matFinal._23;
m_Planes[1].c = matFinal._34 - matFinal._33;
m_Planes[1].d = matFinal._44 - matFinal._43;
D3DXPlaneNormalize(&m_Planes[1], &m_Planes[1]);

//top
m_Planes[2].a = matFinal._14 + matFinal._11;
m_Planes[2].b = matFinal._24 + matFinal._21;
m_Planes[2].c = matFinal._34 + matFinal._31;
m_Planes[2].d = matFinal._44 + matFinal._41;
D3DXPlaneNormalize(&m_Planes[2], &m_Planes[2]);

//Bottom clipping plane
m_Planes[3].a = matFinal._14 - matFinal._11;
m_Planes[3].b = matFinal._24 - matFinal._21;
m_Planes[3].c = matFinal._34 - matFinal._31;
m_Planes[3].d = matFinal._44 - matFinal._41;
D3DXPlaneNormalize(&m_Planes[3], &m_Planes[3]);

////Near
m_Planes[4].a = matFinal._14 - matFinal._12;
m_Planes[4].b = matFinal._24 - matFinal._22;
m_Planes[4].c = matFinal._34 - matFinal._32;
m_Planes[4].d = matFinal._44 - matFinal._42;
D3DXPlaneNormalize(&m_Planes[4], &m_Planes[4]);

//Far
m_Planes[5].a = matFinal._14 + matFinal._12;
m_Planes[5].b = matFinal._24 + matFinal._22;
m_Planes[5].c = matFinal._34 + matFinal._32;
m_Planes[5].d = matFinal._44 + matFinal._42;
D3DXPlaneNormalize(&m_Planes[5], &m_Planes[5]);

return true;
}

bool FrustumCulling::checkPoint(D3DXVECTOR3 &pos)
{
for(int t=0; t<6; t++)
{
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(pos.x, pos.y, pos.z)) < 0.0f)
return true;
}

return false;
}

bool FrustumCulling::checkSphere(D3DXVECTOR3 &pos, float fRadius)
{
for(int t=0; t<6; t++)
{
//se for menor que radius retorna true, senão false
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(pos.x, pos.y, pos.z)) < -fRadius)
return true;
}
return false;
}

bool FrustumCulling::checkBox(D3DXVECTOR3 &min, D3DXVECTOR3 &max)
{
for(int t=0; t<6; t++)
{
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(min.x, min.y, min.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(max.x, min.y, min.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(min.x, max.x, min.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(max.x, max.x, min.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(min.x, min.y, max.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(max.x, min.y, max.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(min.x, max.x, max.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(max.x, max.x, max.z)) >= 0.0f)
continue;

return true;
}

return false;
}

bool FrustumCulling::checkRectangle(D3DXVECTOR3 &Pos, D3DXVECTOR3 &Size)
{
for(int t=0; t<6; t++)
{
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(Pos.x-Size.x, Pos.y-Size.y, Pos.z-Size.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(Pos.x+Size.x, Pos.y-Size.y, Pos.z-Size.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(Pos.x-Size.x, Pos.y+Size.y, Pos.z-Size.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(Pos.x+Size.x, Pos.y+Size.y, Pos.z-Size.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(Pos.x-Size.x, Pos.y-Size.y, Pos.z+Size.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(Pos.x+Size.x, Pos.y-Size.y, Pos.z+Size.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(Pos.x-Size.x, Pos.y+Size.y, Pos.z+Size.z)) >= 0.0f)
continue;
if(D3DXPlaneDotCoord(&m_Planes[t], &D3DXVECTOR3(Pos.x+Size.x, Pos.y+Size.y, Pos.z+Size.z)) >= 0.0f)
continue;

return true;
}

return false;
}

and render loop i use checkSphere method

thank you :D

Share this post


Link to post
Share on other sites
code bool FrustumCulling::checkBox(D3DXVECTOR3 &min, D3DXVECTOR3 &max)
works incorrectly[it sometimes culls the nearast, that it shoudn't]
try my excample



void CCamera::UpdateFrustum()
{
D3DXMATRIX VP = GetViewProj ();

D3DXVECTOR4 col0(VP(0,0), VP(1,0), VP(2,0), VP(3,0));
D3DXVECTOR4 col1(VP(0,1), VP(1,1), VP(2,1), VP(3,1));
D3DXVECTOR4 col2(VP(0,2), VP(1,2), VP(2,2), VP(3,2));
D3DXVECTOR4 col3(VP(0,3), VP(1,3), VP(2,3), VP(3,3));

// Planes face inward.
mFrustumPlanes[0] = (D3DXPLANE)(col2); // near
mFrustumPlanes[1] = (D3DXPLANE)(col3 - col2); // far
mFrustumPlanes[2] = (D3DXPLANE)(col3 + col0); // left
mFrustumPlanes[3] = (D3DXPLANE)(col3 - col0); // right
mFrustumPlanes[4] = (D3DXPLANE)(col3 - col1); // top
mFrustumPlanes[5] = (D3DXPLANE)(col3 + col1); // bottom

for(int i = 0; i < 6; i++)
D3DXPlaneNormalize(&mFrustumPlanes[i], &mFrustumPlanes[i]);
}

bool CCamera::IsVisible(const e3d_BBox &box)
{
D3DXVECTOR3 P;
D3DXVECTOR3 Q;

for(int i = 0; i < 6; ++i)
{
// For each coordinate axis x, y, z...
for(int j = 0; j < 3; ++j)
{
// Make PQ point in the same direction as the plane normal on this axis.
if( mFrustumPlanes[i][j] >= 0.0f )
{
P[j] = box.m_vMin[j];
Q[j] = box.m_vMax[j];
}
else
{
P[j] = box.m_vMax[j];
Q[j] = box.m_vMin[j];
}
}
float kne=D3DXPlaneDotCoord(&mFrustumPlanes[i], &Q);
if( kne <0 ) return false;
}
return true;

Share this post


Link to post
Share on other sites
To get the distance between any two vectors you can use D3DXVec3Length() on the difference, i.e.

D3DXVECTOR3 cameraPos = m_pCamera->GetEyeVector();
D3DXVECTOR3 objectPos = m_pStaticMesh->GetWorldPosition();

float distance = D3DXVec3Length( &D3DXVECTOR3( cameraPos - objectPos ) );

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this