Add support for depth clamping

This commit is contained in:
Jérôme Leclercq 2021-07-09 00:22:08 +02:00
parent 3a3279246f
commit 8458301a64
12 changed files with 74 additions and 2 deletions

View File

@ -75,6 +75,7 @@ int main()
std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>(Nz::BasicMaterial::GetSettings()); std::shared_ptr<Nz::Material> material = std::make_shared<Nz::Material>(Nz::BasicMaterial::GetSettings());
material->EnableDepthBuffer(true); material->EnableDepthBuffer(true);
material->EnableDepthClamp(true);
material->EnableFaceCulling(true); material->EnableFaceCulling(true);
Nz::TextureSamplerInfo samplerInfo; Nz::TextureSamplerInfo samplerInfo;

View File

@ -42,6 +42,7 @@ namespace Nz
inline void EnableBlending(bool blending); inline void EnableBlending(bool blending);
inline void EnableColorWrite(bool colorWrite); inline void EnableColorWrite(bool colorWrite);
inline void EnableDepthBuffer(bool depthBuffer); inline void EnableDepthBuffer(bool depthBuffer);
inline void EnableDepthClamp(bool depthClamp);
inline void EnableDepthSorting(bool depthSorting); inline void EnableDepthSorting(bool depthSorting);
inline void EnableDepthWrite(bool depthWrite); inline void EnableDepthWrite(bool depthWrite);
inline void EnableFaceCulling(bool faceCulling); inline void EnableFaceCulling(bool faceCulling);
@ -84,6 +85,7 @@ namespace Nz
inline bool IsBlendingEnabled() const; inline bool IsBlendingEnabled() const;
inline bool IsColorWriteEnabled() const; inline bool IsColorWriteEnabled() const;
inline bool IsDepthBufferEnabled() const; inline bool IsDepthBufferEnabled() const;
inline bool IsDepthClampEnabled() const;
inline bool IsDepthSortingEnabled() const; inline bool IsDepthSortingEnabled() const;
inline bool IsDepthWriteEnabled() const; inline bool IsDepthWriteEnabled() const;
inline bool IsFaceCullingEnabled() const; inline bool IsFaceCullingEnabled() const;

View File

@ -115,6 +115,28 @@ namespace Nz
InvalidatePipeline(); InvalidatePipeline();
} }
/*!
* \brief Enable/Disable depth clamp for this material
*
* When enabled, all fragments generated by this material will be clamped to znear or zfar
* instead of being clipped out when outside this range.
*
* This can be useful to prevent clipping near or far primitives.
*
* \param depthClamp Defines if this material will use depth clamping
*
* \remark Invalidates the pipeline
* \remark Depth clamping requires RenderDeviceFeatures::depthClamping to be true
*
* \see IsDepthClampEnabled
*/
inline void Material::EnableDepthClamp(bool depthClamp)
{
m_pipelineInfo.depthClamp = depthClamp;
InvalidatePipeline();
}
/*! /*!
* \brief Enable/Disable depth sorting for this material * \brief Enable/Disable depth sorting for this material
* *
@ -524,6 +546,15 @@ namespace Nz
return m_pipelineInfo.depthBuffer; return m_pipelineInfo.depthBuffer;
} }
/*!
* \brief Checks whether this material has depth clamping enabled
* \return true If it is the case
*/
inline bool Material::IsDepthClampEnabled() const
{
return false;
}
/*! /*!
* \brief Checks whether this material has depth sorting enabled * \brief Checks whether this material has depth sorting enabled
* \return true If it is the case * \return true If it is the case

View File

@ -48,6 +48,7 @@ namespace Nz::GL
enum class Extension enum class Extension
{ {
DepthClamp,
SpirV, SpirV,
TextureCompressionS3tc, TextureCompressionS3tc,
TextureFilterAnisotropic, TextureFilterAnisotropic,

View File

@ -16,6 +16,7 @@ namespace Nz
struct RenderDeviceFeatures struct RenderDeviceFeatures
{ {
bool anisotropicFiltering = false; bool anisotropicFiltering = false;
bool depthClamping = false;
bool nonSolidFaceFilling = false; bool nonSolidFaceFilling = false;
}; };

View File

@ -7,9 +7,9 @@
#ifndef NAZARA_RENDERPIPELINE_HPP #ifndef NAZARA_RENDERPIPELINE_HPP
#define NAZARA_RENDERPIPELINE_HPP #define NAZARA_RENDERPIPELINE_HPP
#include <Nazara/Utility/Enums.hpp>
#include <Nazara/Renderer/RenderPipelineLayout.hpp> #include <Nazara/Renderer/RenderPipelineLayout.hpp>
#include <Nazara/Renderer/RenderStates.hpp> #include <Nazara/Renderer/RenderStates.hpp>
#include <Nazara/Utility/Enums.hpp>
namespace Nz namespace Nz
{ {
@ -26,6 +26,8 @@ namespace Nz
std::vector<VertexBufferData> vertexBuffers; std::vector<VertexBufferData> vertexBuffers;
}; };
class RenderDevice;
class NAZARA_RENDERER_API RenderPipeline class NAZARA_RENDERER_API RenderPipeline
{ {
public: public:
@ -33,6 +35,9 @@ namespace Nz
virtual ~RenderPipeline(); virtual ~RenderPipeline();
virtual const RenderPipelineInfo& GetPipelineInfo() const = 0; virtual const RenderPipelineInfo& GetPipelineInfo() const = 0;
protected:
static void ValidatePipelineInfo(const RenderDevice& device, RenderPipelineInfo& pipelineInfo);
}; };
} }

View File

@ -49,6 +49,7 @@ namespace Nz
bool blending = false; bool blending = false;
bool colorWrite = true; bool colorWrite = true;
bool depthBuffer = false; bool depthBuffer = false;
bool depthClamp = false;
bool depthWrite = true; bool depthWrite = true;
bool faceCulling = false; bool faceCulling = false;
bool scissorTest = false; bool scissorTest = false;

View File

@ -19,6 +19,7 @@ namespace Nz
NazaraRenderStateBoolMember(blending); NazaraRenderStateBoolMember(blending);
NazaraRenderStateBoolMember(colorWrite); NazaraRenderStateBoolMember(colorWrite);
NazaraRenderStateBoolMember(depthBuffer); NazaraRenderStateBoolMember(depthBuffer);
NazaraRenderStateBoolMember(depthClamp);
NazaraRenderStateBoolMember(faceCulling); NazaraRenderStateBoolMember(faceCulling);
NazaraRenderStateBoolMember(scissorTest); NazaraRenderStateBoolMember(scissorTest);
NazaraRenderStateBoolMember(stencilTest); NazaraRenderStateBoolMember(stencilTest);
@ -95,6 +96,7 @@ namespace std
NazaraRenderStateBool(blending); NazaraRenderStateBool(blending);
NazaraRenderStateBool(colorWrite); NazaraRenderStateBool(colorWrite);
NazaraRenderStateBool(depthBuffer); NazaraRenderStateBool(depthBuffer);
NazaraRenderStateBool(depthClamp);
NazaraRenderStateBool(faceCulling); NazaraRenderStateBool(faceCulling);
NazaraRenderStateBool(scissorTest); NazaraRenderStateBool(scissorTest);
NazaraRenderStateBool(stencilTest); NazaraRenderStateBool(stencilTest);

View File

@ -53,6 +53,7 @@ namespace Nz
RenderDeviceFeatures enabledFeatures; RenderDeviceFeatures enabledFeatures;
enabledFeatures.anisotropicFiltering = renderDeviceInfo[bestRenderDeviceIndex].features.anisotropicFiltering; enabledFeatures.anisotropicFiltering = renderDeviceInfo[bestRenderDeviceIndex].features.anisotropicFiltering;
enabledFeatures.depthClamping = renderDeviceInfo[bestRenderDeviceIndex].features.depthClamping;
enabledFeatures.nonSolidFaceFilling = renderDeviceInfo[bestRenderDeviceIndex].features.nonSolidFaceFilling; enabledFeatures.nonSolidFaceFilling = renderDeviceInfo[bestRenderDeviceIndex].features.nonSolidFaceFilling;
m_renderDevice = renderer->InstanciateRenderDevice(bestRenderDeviceIndex, enabledFeatures); m_renderDevice = renderer->InstanciateRenderDevice(bestRenderDeviceIndex, enabledFeatures);

View File

@ -281,6 +281,16 @@ namespace Nz::GL
m_extensionStatus.fill(ExtensionStatus::NotSupported); m_extensionStatus.fill(ExtensionStatus::NotSupported);
// Depth clamp
if (m_params.type == ContextType::OpenGL && m_params.glMajorVersion >= 3 && m_params.glMajorVersion >= 2)
m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Core;
else if (m_supportedExtensions.count("GL_ARB_depth_clamp"))
m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::ARB;
else if (m_supportedExtensions.count("GL_EXT_depth_clamp"))
m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::EXT;
else if (m_supportedExtensions.count("GL_NV_depth_clamp"))
m_extensionStatus[UnderlyingCast(Extension::DepthClamp)] = ExtensionStatus::Vendor;
// SpirV // SpirV
if (m_params.type == ContextType::OpenGL && m_params.glMajorVersion >= 4 && m_params.glMajorVersion >= 6) if (m_params.type == ContextType::OpenGL && m_params.glMajorVersion >= 4 && m_params.glMajorVersion >= 6)
m_extensionStatus[UnderlyingCast(Extension::SpirV)] = ExtensionStatus::Core; m_extensionStatus[UnderlyingCast(Extension::SpirV)] = ExtensionStatus::Core;
@ -599,6 +609,17 @@ namespace Nz::GL
m_state.renderStates.depthBuffer = renderStates.depthBuffer; m_state.renderStates.depthBuffer = renderStates.depthBuffer;
} }
// Depth clamp
if (m_state.renderStates.depthClamp != renderStates.depthClamp)
{
if (renderStates.depthClamp)
glEnable(GL_DEPTH_CLAMP_EXT);
else
glDisable(GL_DEPTH_CLAMP_EXT);
m_state.renderStates.depthClamp = renderStates.depthClamp;
}
// Face culling // Face culling
if (m_state.renderStates.faceCulling != renderStates.faceCulling) if (m_state.renderStates.faceCulling != renderStates.faceCulling)
{ {

View File

@ -54,6 +54,7 @@ namespace Nz
deviceInfo.name = physDevice.properties.deviceName; deviceInfo.name = physDevice.properties.deviceName;
deviceInfo.features.anisotropicFiltering = physDevice.features.samplerAnisotropy; deviceInfo.features.anisotropicFiltering = physDevice.features.samplerAnisotropy;
deviceInfo.features.depthClamping = physDevice.features.depthClamp;
deviceInfo.features.nonSolidFaceFilling = physDevice.features.fillModeNonSolid; deviceInfo.features.nonSolidFaceFilling = physDevice.features.fillModeNonSolid;
deviceInfo.limits.minUniformBufferOffsetAlignment = physDevice.properties.limits.minUniformBufferOffsetAlignment; deviceInfo.limits.minUniformBufferOffsetAlignment = physDevice.properties.limits.minUniformBufferOffsetAlignment;
@ -578,6 +579,9 @@ namespace Nz
if (enabledFeatures.anisotropicFiltering) if (enabledFeatures.anisotropicFiltering)
deviceFeatures.samplerAnisotropy = VK_TRUE; deviceFeatures.samplerAnisotropy = VK_TRUE;
if (enabledFeatures.depthClamping)
deviceFeatures.depthClamp = VK_TRUE;
if (enabledFeatures.nonSolidFaceFilling) if (enabledFeatures.nonSolidFaceFilling)
deviceFeatures.fillModeNonSolid = VK_TRUE; deviceFeatures.fillModeNonSolid = VK_TRUE;

View File

@ -5,6 +5,7 @@
#include <Nazara/VulkanRenderer/VulkanRenderPipeline.hpp> #include <Nazara/VulkanRenderer/VulkanRenderPipeline.hpp>
#include <Nazara/Core/ErrorFlags.hpp> #include <Nazara/Core/ErrorFlags.hpp>
#include <Nazara/VulkanRenderer/Utils.hpp> #include <Nazara/VulkanRenderer/Utils.hpp>
#include <Nazara/VulkanRenderer/VulkanDevice.hpp>
#include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.hpp> #include <Nazara/VulkanRenderer/VulkanRenderPipelineLayout.hpp>
#include <Nazara/VulkanRenderer/VulkanShaderModule.hpp> #include <Nazara/VulkanRenderer/VulkanShaderModule.hpp>
#include <cassert> #include <cassert>
@ -142,10 +143,11 @@ namespace Nz
{ {
VkPipelineRasterizationStateCreateInfo createInfo = {}; VkPipelineRasterizationStateCreateInfo createInfo = {};
createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO; createInfo.sType = VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO;
createInfo.polygonMode = ToVulkan(pipelineInfo.faceFilling);
createInfo.cullMode = (pipelineInfo.faceCulling) ? ToVulkan(pipelineInfo.cullingSide) : VK_CULL_MODE_NONE; createInfo.cullMode = (pipelineInfo.faceCulling) ? ToVulkan(pipelineInfo.cullingSide) : VK_CULL_MODE_NONE;
createInfo.depthClampEnable = pipelineInfo.depthClamp;
createInfo.frontFace = ToVulkan(pipelineInfo.frontFace); createInfo.frontFace = ToVulkan(pipelineInfo.frontFace);
createInfo.lineWidth = pipelineInfo.lineWidth; createInfo.lineWidth = pipelineInfo.lineWidth;
createInfo.polygonMode = ToVulkan(pipelineInfo.faceFilling);
return createInfo; return createInfo;
} }