Frustum Culling - render only near

Started by
7 comments, last by renanrosa 14 years, 3 months ago
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 :)
Advertisement
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.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

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
nobody ? :(
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, &mFrustumPlanes);}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[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, &Q);		if( kne <0  ) return false;	}	return true;
Crazy dude smoking D3D11, AngelScript, PhysX, 3D Sound, Network, DB, FBX, and some other weird things, doing that on Visual Studio 2010 + Visual Assist X on Overclocked CPU
Original post by e3d_ALiVE
code bool FrustumCulling::checkBox(D3DXVECTOR3 &min, D3DXVECTOR3 &max)
works incorrectly ....

oh right, but i dont use this method.
Now, I want know how i get the distance between camera and object :(
ty
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 ) );
The distance from a point to a plane is the dot product of the plane and the point:
D3DXVECTOR3 vPos(1.0, 2.0, 3.0);float dist = D3DXPlaneDotCoord(&m_Planes[4], &vPos);
right, hi guys, worked with answer of the Steve_Segreto :)
thank for all :D

This topic is closed to new replies.

Advertisement