updated hair particle system culling shader

This commit is contained in:
turanszkij
2017-06-04 14:56:00 +02:00
parent f651b5b1c1
commit 80e82d573c
9 changed files with 82 additions and 26 deletions
+27 -13
View File
@@ -82,7 +82,7 @@ bool SphereInsidePlane(Sphere sphere, Plane plane)
return dot(plane.N, sphere.c) - plane.d < -sphere.r;
}
// Check to see of a light is partially contained within the frustum.
bool SphereInsideFrustum(Sphere sphere, Frustum frustum, float zNear, float zFar)
bool SphereInsideFrustum(Sphere sphere, Frustum frustum, float zNear, float zFar) // this can only be used in view space
{
bool result = true;
@@ -102,6 +102,20 @@ bool SphereInsideFrustum(Sphere sphere, Frustum frustum, float zNear, float zFar
return result;
}
bool SphereInsideFrustum(Sphere sphere, Plane planes[6]) // this can be used in world space
{
bool result = true;
for (int i = 0; i < 6 && result; i++)
{
if (SphereInsidePlane(sphere, planes[i]))
{
result = false;
}
}
return result;
}
// Check to see if a point is fully behind (inside the negative halfspace of) a plane.
bool PointInsidePlane(float3 p, Plane plane)
{
@@ -213,17 +227,17 @@ bool IntersectAABB(AABB a, AABB b)
static const float4 frustumCorners[4] = {
float4(-1, -1, 1, 1),
float4(1, -1, 1, 1),
float4(-1, 1, 1, 1),
float4(1, 1, 1, 1)
};
static const Frustum frustum = {
ComputePlane(float3(0,0,0), frustumCorners[2].xyz, frustumCorners[0].xyz),
ComputePlane(float3(0,0,0), frustumCorners[1].xyz, frustumCorners[3].xyz),
ComputePlane(float3(0,0,0), frustumCorners[0].xyz, frustumCorners[1].xyz),
ComputePlane(float3(0,0,0), frustumCorners[3].xyz, frustumCorners[2].xyz)
};
//static const float4 frustumCorners[4] = {
// float4(-1, -1, 1, 1),
// float4(1, -1, 1, 1),
// float4(-1, 1, 1, 1),
// float4(1, 1, 1, 1)
//};
//static const Frustum frustum = {
// ComputePlane(float3(0,0,0), frustumCorners[2].xyz, frustumCorners[0].xyz),
// ComputePlane(float3(0,0,0), frustumCorners[1].xyz, frustumCorners[3].xyz),
// ComputePlane(float3(0,0,0), frustumCorners[0].xyz, frustumCorners[1].xyz),
// ComputePlane(float3(0,0,0), frustumCorners[3].xyz, frustumCorners[2].xyz)
//};
#endif // _CULLING_SHADER_HF_
+3 -1
View File
@@ -78,7 +78,8 @@ CBUFFER(FrameCB, CBSLOT_RENDERER_FRAME)
float4x4 g_xFrame_MainCamera_VP; // View*Projection
float4x4 g_xFrame_MainCamera_View;
float4x4 g_xFrame_MainCamera_Proj;
float3 g_xFrame_MainCamera_CamPos; float xPadding3_FrameCB;
float3 g_xFrame_MainCamera_CamPos;
float g_xFrame_MainCamera_DistanceFromOrigin;
float4x4 g_xFrame_MainCamera_PrevV;
float4x4 g_xFrame_MainCamera_PrevP;
float4x4 g_xFrame_MainCamera_PrevVP; // PrevView*PrevProjection
@@ -91,6 +92,7 @@ CBUFFER(FrameCB, CBSLOT_RENDERER_FRAME)
float g_xFrame_MainCamera_ZNearP;
float3 g_xFrame_MainCamera_Up;
float g_xFrame_MainCamera_ZFarP;
float4 g_xFrame_FrustumPlanesWS[6]; // Frustum planes in world space in order: left,right,top,bottom,near,far
};
// The following buffer contains properties for a temporary camera (eg. main camera, reflection camera, shadow camera...)
CBUFFER(Camera_CommonCB, CBSLOT_RENDERER_CAMERA)
+19 -4
View File
@@ -5,7 +5,7 @@
static const uint vertexBuffer_stride = 16 * 3; // pos, normal, tangent
RAWBUFFER(vertexBuffer, 0);
RWRAWBUFFER(argumentBuffer, 0);
RWRAWBUFFER(argumentBuffer, 0); // indirect draw args
RWRAWBUFFER(indexBuffer, 1);
@@ -15,14 +15,29 @@ void main( uint3 DTid : SV_DispatchThreadID )
const uint fetchAddress = DTid.x * vertexBuffer_stride;
float4 pos = float4(asfloat(vertexBuffer.Load3(fetchAddress)), 1);
pos = mul(pos, xWorld);
if (distance(g_xFrame_MainCamera_CamPos, pos.xyz) > LOD2)
{
return;
}
float len = asfloat(vertexBuffer.Load(fetchAddress + 16 + 12));
const Plane planes[6] = {
{ g_xFrame_FrustumPlanesWS[0].xyz, -g_xFrame_FrustumPlanesWS[0].w }, // left plane
{ g_xFrame_FrustumPlanesWS[1].xyz, -g_xFrame_FrustumPlanesWS[1].w }, // right plane
{ g_xFrame_FrustumPlanesWS[2].xyz, -g_xFrame_FrustumPlanesWS[2].w }, // top plane
{ g_xFrame_FrustumPlanesWS[3].xyz, -g_xFrame_FrustumPlanesWS[3].w }, // bottom plane
{ g_xFrame_FrustumPlanesWS[4].xyz, -g_xFrame_FrustumPlanesWS[4].w }, // near plane
{ g_xFrame_FrustumPlanesWS[5].xyz, -g_xFrame_FrustumPlanesWS[5].w }, // far plane
};
Sphere sphere = { mul(pos, g_xCamera_View).xyz, len };
if (SphereInsideFrustum(sphere, frustum, 1, LOD2))
const Sphere sphere = { pos.xyz, len };
if (SphereInsideFrustum(sphere, planes))
{
uint prevValue;
argumentBuffer.InterlockedAdd(0, 1, prevValue);
argumentBuffer.InterlockedAdd(0, 1, prevValue); // index count
indexBuffer.Store(prevValue * 4, DTid.x);
}
+10 -2
View File
@@ -30,8 +30,16 @@ void main(point GS_INPUT p[1], inout TriangleStream<VertextoPixel> triStream, ui
{
float quadLength = p[0].inSizOpMir.x*0.5f;
Sphere sphere = { mul(float4(p[0].pos.xyz,1), g_xCamera_View).xyz, quadLength };
if (!SphereInsideFrustum(sphere, frustum, 1, g_xFrame_MainCamera_ZFarP))
const Plane planes[6] = {
{ g_xFrame_FrustumPlanesWS[0].xyz, -g_xFrame_FrustumPlanesWS[0].w }, // left plane
{ g_xFrame_FrustumPlanesWS[1].xyz, -g_xFrame_FrustumPlanesWS[1].w }, // right plane
{ g_xFrame_FrustumPlanesWS[2].xyz, -g_xFrame_FrustumPlanesWS[2].w }, // top plane
{ g_xFrame_FrustumPlanesWS[3].xyz, -g_xFrame_FrustumPlanesWS[3].w }, // bottom plane
{ g_xFrame_FrustumPlanesWS[4].xyz, -g_xFrame_FrustumPlanesWS[4].w }, // near plane
{ g_xFrame_FrustumPlanesWS[5].xyz, -g_xFrame_FrustumPlanesWS[5].w }, // far plane
};
Sphere sphere = { p[0].pos.xyz, quadLength };
if (!SphereInsideFrustum(sphere, planes))
{
return;
}
+6 -2
View File
@@ -121,8 +121,12 @@ int Frustum::CheckBox(const AABB& box)
return(BOX_FRUSTUM_INTERSECTS);
}
XMFLOAT4 Frustum::getFarPlane(){return m_planes[1];}
XMFLOAT4 Frustum::getNearPlane(){return m_planes[0];}
const XMFLOAT4& Frustum::getLeftPlane() { return m_planesNorm[2]; }
const XMFLOAT4& Frustum::getRightPlane() { return m_planesNorm[3]; }
const XMFLOAT4& Frustum::getTopPlane() { return m_planesNorm[4]; }
const XMFLOAT4& Frustum::getBottomPlane() { return m_planesNorm[5]; }
const XMFLOAT4& Frustum::getFarPlane(){return m_planesNorm[1];}
const XMFLOAT4& Frustum::getNearPlane(){return m_planesNorm[0];}
XMFLOAT3 Frustum::getCamPos(){
return XMFLOAT3(-view._41,-view._42,-view._43);
}
+6 -2
View File
@@ -22,8 +22,12 @@ public:
#define BOX_FRUSTUM_INSIDE 2
int CheckBox(const AABB& box);
XMFLOAT4 getFarPlane();
XMFLOAT4 getNearPlane();
const XMFLOAT4& getLeftPlane();
const XMFLOAT4& getRightPlane();
const XMFLOAT4& getTopPlane();
const XMFLOAT4& getBottomPlane();
const XMFLOAT4& getFarPlane();
const XMFLOAT4& getNearPlane();
XMFLOAT3 getCamPos();
};
+7
View File
@@ -5311,6 +5311,7 @@ void wiRenderer::UpdateFrameCB(GRAPHICSTHREAD threadID)
cb.mView = XMMatrixTranspose(camera->GetView());
cb.mProj = XMMatrixTranspose(camera->GetProjection());
cb.mCamPos = camera->translation;
cb.mCamDistanceFromOrigin = XMVectorGetX(XMVector3Length(XMLoadFloat3(&cb.mCamPos)));
cb.mPrevV = XMMatrixTranspose(prevCam->GetView());
cb.mPrevP = XMMatrixTranspose(prevCam->GetProjection());
cb.mPrevVP = XMMatrixTranspose(prevCam->GetViewProjection());
@@ -5323,6 +5324,12 @@ void wiRenderer::UpdateFrameCB(GRAPHICSTHREAD threadID)
cb.mUp = camera->Up;
cb.mZNearP = camera->zNearP;
cb.mZFarP = camera->zFarP;
cb.mFrustumPlanesWS[0] = camera->frustum.getLeftPlane();
cb.mFrustumPlanesWS[1] = camera->frustum.getRightPlane();
cb.mFrustumPlanesWS[2] = camera->frustum.getTopPlane();
cb.mFrustumPlanesWS[3] = camera->frustum.getBottomPlane();
cb.mFrustumPlanesWS[4] = camera->frustum.getNearPlane();
cb.mFrustumPlanesWS[5] = camera->frustum.getFarPlane();
GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_FRAME], &cb, threadID);
}
+3 -1
View File
@@ -126,7 +126,8 @@ public:
XMMATRIX mVP;
XMMATRIX mView;
XMMATRIX mProj;
XMFLOAT3 mCamPos; float pad3;
XMFLOAT3 mCamPos;
float mCamDistanceFromOrigin;
XMMATRIX mPrevV;
XMMATRIX mPrevP;
XMMATRIX mPrevVP;
@@ -139,6 +140,7 @@ public:
float mZNearP;
XMFLOAT3 mUp;
float mZFarP;
XMFLOAT4 mFrustumPlanesWS[6];
CB_SETBINDSLOT(CBSLOT_RENDERER_FRAME)
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wiVersion
// minor features, major updates
const int minor = 11;
// minor bug fixes, alterations, refactors, updates
const int revision = 68;
const int revision = 69;
long GetVersion()