Explorar el Código

TestFramework: Switched depth buffer to infinite reverse z (#1246)

This pushes the far plane out to infinite and means that objects are no longer culled in the distance

See #1245
Jorrit Rouwe hace 11 meses
padre
commit
e3ed3b1d33

+ 0 - 1
Samples/SamplesApp.cpp

@@ -2519,7 +2519,6 @@ void SamplesApp::GetInitialCamera(CameraState &ioState) const
 	// Default if the test doesn't override it
 	ioState.mPos = GetWorldScale() * RVec3(30, 10, 30);
 	ioState.mForward = -Vec3(ioState.mPos).Normalized();
-	ioState.mFarPlane = 1000.0f;
 
 	mTest->GetInitialCamera(ioState);
 }

+ 1 - 1
TestFramework/Application/Application.cpp

@@ -301,7 +301,7 @@ void Application::UpdateCamera(float inDeltaTime)
 	JPH_PROFILE_FUNCTION();
 
 	// Determine speed
-	float speed = GetWorldScale() * mWorldCamera.mFarPlane / 50.0f * inDeltaTime;
+	float speed = 20.0f * GetWorldScale() * inDeltaTime;
 	bool shift = mKeyboard->IsKeyPressed(DIK_LSHIFT) || mKeyboard->IsKeyPressed(DIK_RSHIFT);
 	bool control = mKeyboard->IsKeyPressed(DIK_LCONTROL) || mKeyboard->IsKeyPressed(DIK_RCONTROL);
 	bool alt = mKeyboard->IsKeyPressed(DIK_LALT) || mKeyboard->IsKeyPressed(DIK_RALT);

+ 8 - 9
TestFramework/Renderer/Frustum.h

@@ -14,24 +14,23 @@ public:
 	/// Empty constructor
 					Frustum() = default;
 
-	/// Construct frustum from position, forward, up, field of view x and y and near and far plane.
+	/// Construct frustum from position, forward, up, field of view x and y and near plane.
 	/// Note that inUp does not need to be perpendicular to inForward but cannot be collinear.
-	inline			Frustum(Vec3Arg inPosition, Vec3Arg inForward, Vec3Arg inUp, float inFOVX, float inFOVY, float inNear, float inFar)
+	inline			Frustum(Vec3Arg inPosition, Vec3Arg inForward, Vec3Arg inUp, float inFOVX, float inFOVY, float inNear)
 	{
 		Vec3 right = inForward.Cross(inUp).Normalized();
 		Vec3 up = right.Cross(inForward).Normalized(); // Calculate the real up vector (inUp does not need to be perpendicular to inForward)
 
-		// Near and far plane
+		// Near plane
 		mPlanes[0] = Plane::sFromPointAndNormal(inPosition + inNear * inForward, inForward);
-		mPlanes[1] = Plane::sFromPointAndNormal(inPosition + inFar * inForward, -inForward);
 
 		// Top and bottom planes
-		mPlanes[2] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(right, 0.5f * inFOVY) * -up);
-		mPlanes[3] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(right, -0.5f * inFOVY) * up);
+		mPlanes[1] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(right, 0.5f * inFOVY) * -up);
+		mPlanes[2] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(right, -0.5f * inFOVY) * up);
 
 		// Left and right planes
-		mPlanes[4] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(up, 0.5f * inFOVX) * right);
-		mPlanes[5] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(up, -0.5f * inFOVX) * -right);
+		mPlanes[3] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(up, 0.5f * inFOVX) * right);
+		mPlanes[4] = Plane::sFromPointAndNormal(inPosition, Mat44::sRotation(up, -0.5f * inFOVX) * -right);
 	}
 
 	/// Test if frustum overlaps with axis aligned box. Note that this is a conservative estimate and can return true if the
@@ -54,5 +53,5 @@ public:
 	}
 
 private:
-	Plane			mPlanes[6];																	///< Planes forming the frustum
+	Plane			mPlanes[5];																	///< Planes forming the frustum
 };

+ 1 - 1
TestFramework/Renderer/PipelineState.cpp

@@ -59,7 +59,7 @@ PipelineState::PipelineState(Renderer *inRenderer, ID3DBlob *inVertexShader, con
 
 	pso_desc.DepthStencilState.DepthEnable = inDepthTest == EDepthTest::On? TRUE : FALSE;
 	pso_desc.DepthStencilState.DepthWriteMask = inDepthTest == EDepthTest::On? D3D12_DEPTH_WRITE_MASK_ALL : D3D12_DEPTH_WRITE_MASK_ZERO;
-	pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_LESS;
+	pso_desc.DepthStencilState.DepthFunc = D3D12_COMPARISON_FUNC_GREATER;
 	pso_desc.DepthStencilState.StencilEnable = FALSE;
 
 	pso_desc.SampleMask = UINT_MAX;

+ 16 - 10
TestFramework/Renderer/Renderer.cpp

@@ -121,7 +121,7 @@ void Renderer::CreateDepthBuffer()
 	// Allocate depth stencil buffer
 	D3D12_CLEAR_VALUE clear_value = {};
 	clear_value.Format = DXGI_FORMAT_D32_FLOAT;
-	clear_value.DepthStencil.Depth = 1.0f;
+	clear_value.DepthStencil.Depth = 0.0f;
 	clear_value.DepthStencil.Stencil = 0;
 
 	D3D12_HEAP_PROPERTIES heap_properties = {};
@@ -352,10 +352,10 @@ void Renderer::Initialize()
 	samplers[1].AddressW = D3D12_TEXTURE_ADDRESS_MODE_WRAP;
 	samplers[1].ShaderRegister = 1;
 
-	// Sampler 2: Point filtering, using SampleCmp mode to compare if sampled value <= reference value (for shadows)
+	// Sampler 2: Point filtering, using SampleCmp mode to compare if sampled value >= reference value (for shadows)
 	samplers[2] = samplers[0];
 	samplers[2].Filter = D3D12_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
-	samplers[2].ComparisonFunc = D3D12_COMPARISON_FUNC_LESS_EQUAL;
+	samplers[2].ComparisonFunc = D3D12_COMPARISON_FUNC_GREATER_EQUAL;
 	samplers[2].ShaderRegister = 2;
 
 	D3D12_ROOT_SIGNATURE_DESC root_signature_desc = {};
@@ -440,6 +440,14 @@ void Renderer::OnWindowResize()
 	CreateDepthBuffer();
 }
 
+static Mat44 sPerspectiveInfiniteReverseZ(float inFovY, float inAspect, float inNear)
+{
+	float height = 1.0f / Tan(0.5f * inFovY);
+	float width = height / inAspect;
+
+	return Mat44(Vec4(width, 0.0f, 0.0f, 0.0f), Vec4(0.0f, height, 0.0f, 0.0f), Vec4(0.0f, 0.0f, 0, -1.0f), Vec4(0.0f, 0.0f, inNear, 0.0f));
+}
+
 void Renderer::BeginFrame(const CameraState &inCamera, float inWorldScale)
 {
 	JPH_PROFILE_FUNCTION();
@@ -480,7 +488,7 @@ void Renderer::BeginFrame(const CameraState &inCamera, float inWorldScale)
 	// Clear the back buffer.
 	const float blue[] = { 0.098f, 0.098f, 0.439f, 1.000f };
 	mCommandList->ClearRenderTargetView(mRenderTargetViews[mFrameIndex], blue, 0, nullptr);
-	mCommandList->ClearDepthStencilView(mDepthStencilView, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
+	mCommandList->ClearDepthStencilView(mDepthStencilView, D3D12_CLEAR_FLAG_DEPTH, 0.0f, 0, 0, nullptr);
 
 	// Light properties
 	Vec3 light_pos = inWorldScale * Vec3(250, 250, 250);
@@ -489,26 +497,24 @@ void Renderer::BeginFrame(const CameraState &inCamera, float inWorldScale)
 	Vec3 light_fwd = (light_tgt - light_pos).Normalized();
 	float light_fov = DegreesToRadians(20.0f);
 	float light_near = 1.0f;
-	float light_far = 1000.0f;
 
 	// Camera properties
 	float camera_fovy = inCamera.mFOVY;
 	float camera_aspect = static_cast<float>(GetWindowWidth()) / GetWindowHeight();
 	float camera_fovx = 2.0f * ATan(camera_aspect * Tan(0.5f * camera_fovy));
 	float camera_near = 0.01f * inWorldScale;
-	float camera_far = inCamera.mFarPlane * inWorldScale;
 
 	// Set constants for vertex shader in projection mode
 	VertexShaderConstantBuffer *vs = mVertexShaderConstantBufferProjection[mFrameIndex]->Map<VertexShaderConstantBuffer>();
 
 	// Camera projection and view
-	vs->mProjection = Mat44::sPerspective(camera_fovy, camera_aspect, camera_near, camera_far);
+	vs->mProjection = sPerspectiveInfiniteReverseZ(camera_fovy, camera_aspect, camera_near);
 	Vec3 cam_pos = Vec3(inCamera.mPos - mBaseOffset);
 	Vec3 tgt = cam_pos + inCamera.mForward;
 	vs->mView = Mat44::sLookAt(cam_pos, tgt, inCamera.mUp);
 
 	// Light projection and view
-	vs->mLightProjection = Mat44::sPerspective(light_fov, 1.0f, light_near, light_far);
+	vs->mLightProjection = sPerspectiveInfiniteReverseZ(light_fov, 1.0f, light_near);
 	vs->mLightView = Mat44::sLookAt(light_pos, light_tgt, light_up);
 
 	mVertexShaderConstantBufferProjection[mFrameIndex]->Unmap();
@@ -539,10 +545,10 @@ void Renderer::BeginFrame(const CameraState &inCamera, float inWorldScale)
 	mPixelShaderConstantBuffer[mFrameIndex]->Bind(1);
 
 	// Calculate camera frustum
-	mCameraFrustum = Frustum(cam_pos, inCamera.mForward, inCamera.mUp, camera_fovx, camera_fovy, camera_near, camera_far);
+	mCameraFrustum = Frustum(cam_pos, inCamera.mForward, inCamera.mUp, camera_fovx, camera_fovy, camera_near);
 
 	// Calculate light frustum
-	mLightFrustum = Frustum(light_pos, light_fwd, light_up, light_fov, light_fov, light_near, light_far);
+	mLightFrustum = Frustum(light_pos, light_fwd, light_up, light_fov, light_fov, light_near);
 }
 
 void Renderer::EndFrame()

+ 1 - 2
TestFramework/Renderer/Renderer.h

@@ -19,13 +19,12 @@ class Texture;
 /// Camera setup
 struct CameraState
 {
-									CameraState() : mPos(RVec3::sZero()), mForward(0, 0, -1), mUp(0, 1, 0), mFOVY(DegreesToRadians(70.0f)), mFarPlane(100.0f) { }
+									CameraState() : mPos(RVec3::sZero()), mForward(0, 0, -1), mUp(0, 1, 0), mFOVY(DegreesToRadians(70.0f)) { }
 
 	RVec3							mPos;								///< Camera position
 	Vec3							mForward;							///< Camera forward vector
 	Vec3							mUp;								///< Camera up vector
 	float							mFOVY;								///< Field of view in radians in up direction
-	float							mFarPlane;							///< Distance of far plane
 };
 
 /// Responsible for rendering primitives to the screen

+ 2 - 2
TestFramework/Renderer/Texture.cpp

@@ -138,7 +138,7 @@ Texture::Texture(Renderer *inRenderer, int inWidth, int inHeight) :
 	// Allocate depth stencil buffer
 	D3D12_CLEAR_VALUE clear_value = {};
 	clear_value.Format = DXGI_FORMAT_D32_FLOAT;
-	clear_value.DepthStencil.Depth = 1.0f;
+	clear_value.DepthStencil.Depth = 0;
 	clear_value.DepthStencil.Stencil = 0;
 
 	D3D12_HEAP_PROPERTIES heap_properties = {};
@@ -201,7 +201,7 @@ void Texture::Bind(int inSlot) const
 
 void Texture::ClearRenderTarget()
 {
-	mRenderer->GetCommandList()->ClearDepthStencilView(mDSV, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
+	mRenderer->GetCommandList()->ClearDepthStencilView(mDSV, D3D12_CLEAR_FLAG_DEPTH, 0, 0, 0, nullptr);
 }
 
 void Texture::SetAsRenderTarget(bool inSet) const