diff --git a/WickedEngine/cullingShaderHF.hlsli b/WickedEngine/cullingShaderHF.hlsli index 36a1d3847..63db4ab6f 100644 --- a/WickedEngine/cullingShaderHF.hlsli +++ b/WickedEngine/cullingShaderHF.hlsli @@ -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_ diff --git a/WickedEngine/globals.hlsli b/WickedEngine/globals.hlsli index 3ba81cf99..05e39e20d 100644 --- a/WickedEngine/globals.hlsli +++ b/WickedEngine/globals.hlsli @@ -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) diff --git a/WickedEngine/grassCullingCS.hlsl b/WickedEngine/grassCullingCS.hlsl index 040fb91e6..1c34195bc 100644 --- a/WickedEngine/grassCullingCS.hlsl +++ b/WickedEngine/grassCullingCS.hlsl @@ -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); } diff --git a/WickedEngine/pointspriteGS.hlsl b/WickedEngine/pointspriteGS.hlsl index 1239f18b8..db0fc7c99 100644 --- a/WickedEngine/pointspriteGS.hlsl +++ b/WickedEngine/pointspriteGS.hlsl @@ -30,8 +30,16 @@ void main(point GS_INPUT p[1], inout TriangleStream 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; } diff --git a/WickedEngine/wiFrustum.cpp b/WickedEngine/wiFrustum.cpp index 05a4049cb..a81b55f39 100644 --- a/WickedEngine/wiFrustum.cpp +++ b/WickedEngine/wiFrustum.cpp @@ -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); } diff --git a/WickedEngine/wiFrustum.h b/WickedEngine/wiFrustum.h index b93de0fc9..6c1aae3c4 100644 --- a/WickedEngine/wiFrustum.h +++ b/WickedEngine/wiFrustum.h @@ -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(); }; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 6d57ce3f0..e42625428 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -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); } diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index fd30623fd..3ea8a84cf 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -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) diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 69ca65fad..345e3a84a 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -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()