This commit is contained in:
SirLynix
2022-11-19 17:10:27 +01:00
committed by Jérôme Leclercq
parent 4a10c1f8fe
commit e990a320cc
54 changed files with 618 additions and 154 deletions

View File

@@ -30,7 +30,7 @@ namespace Nz
class NAZARA_GRAPHICS_API DepthPipelinePass : public FramePipelinePass
{
public:
DepthPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer);
DepthPipelinePass(FramePipeline& owner, ElementRendererRegistry& elementRegistry, AbstractViewer* viewer, std::size_t passIndex, std::string passName);
DepthPipelinePass(const DepthPipelinePass&) = delete;
DepthPipelinePass(DepthPipelinePass&&) = delete;
~DepthPipelinePass() = default;
@@ -57,8 +57,9 @@ namespace Nz
NazaraSlot(MaterialInstance, OnMaterialInstanceShaderBindingInvalidated, onMaterialInstanceShaderBindingInvalidated);
};
std::size_t m_depthPassIndex;
std::size_t m_passIndex;
std::size_t m_lastVisibilityHash;
std::string m_passName;
std::vector<std::unique_ptr<ElementRendererData>> m_elementRendererData;
std::vector<ElementRenderer::RenderStates> m_renderStates;
std::vector<RenderElementOwner> m_renderElements;

View File

@@ -11,8 +11,10 @@
#include <Nazara/Core/Algorithm.hpp>
#include <Nazara/Graphics/Config.hpp>
#include <Nazara/Graphics/Enums.hpp>
#include <Nazara/Graphics/PredefinedShaderStructs.hpp>
#include <Nazara/Graphics/RenderElementPool.hpp>
#include <Nazara/Renderer/RenderBufferView.hpp>
#include <array>
#include <memory>
#include <optional>
#include <vector>
@@ -43,6 +45,14 @@ namespace Nz
struct RenderStates
{
RenderStates()
{
shadowMaps2D.fill(nullptr);
shadowMapsCube.fill(nullptr);
}
std::array<const Texture*, PredefinedLightData::MaxLightCount> shadowMaps2D;
std::array<const Texture*, PredefinedLightData::MaxLightCount> shadowMapsCube;
RenderBufferView lightData;
};
};

View File

@@ -95,6 +95,8 @@ namespace Nz
InstanceDataUbo,
LightDataUbo,
OverlayTexture,
Shadowmap2D,
ShadowmapCube,
SkeletalDataUbo,
ViewerDataUbo,

View File

@@ -50,6 +50,9 @@ namespace Nz
std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder) override;
std::size_t RegisterWorldInstance(WorldInstancePtr worldInstance) override;
const Light* RetrieveLight(std::size_t lightIndex) const override;
const Texture* RetrieveLightShadowmap(std::size_t lightIndex) const override;
void Render(RenderFrame& renderFrame) override;
void UnregisterLight(std::size_t lightIndex) override;
@@ -147,7 +150,7 @@ namespace Nz
std::unordered_map<MaterialInstance*, MaterialInstanceData> m_materialInstances;
std::vector<ElementRenderer::RenderStates> m_renderStates;
std::vector<FramePipelinePass::VisibleRenderable> m_visibleRenderables;
std::vector<const Light*> m_visibleLights;
std::vector<std::size_t> m_visibleLights;
robin_hood::unordered_set<TransferInterface*> m_transferSet;
BakedFrameGraph m_bakedFrameGraph;
Bitset<UInt64> m_shadowCastingLights;

View File

@@ -41,7 +41,7 @@ namespace Nz
inline void InvalidateCommandBuffers();
inline void InvalidateElements();
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const std::vector<const Light*>& visibleLights, std::size_t visibilityHash);
void Prepare(RenderFrame& renderFrame, const Frustumf& frustum, const std::vector<FramePipelinePass::VisibleRenderable>& visibleRenderables, const std::vector<std::size_t>& visibleLights, std::size_t visibilityHash);
void RegisterMaterialInstance(const MaterialInstance& material);
FramePass& RegisterToFrameGraph(FrameGraph& frameGraph, std::size_t colorBufferIndex, std::size_t depthBufferIndex, bool hasDepthPrepass);
@@ -76,11 +76,25 @@ namespace Nz
UploadPool::Allocation* allocation = nullptr;
};
struct LightPerElementData
{
RenderBufferView lightUniformBuffer;
std::array<const Texture*, MaxLightCountPerDraw> shadowMaps;
std::size_t lightCount;
};
struct LightUboPool
{
std::vector<std::shared_ptr<RenderBuffer>> lightUboBuffers;
};
struct RenderableLight
{
const Light* light;
std::size_t lightIndex;
float contributionScore;
};
std::size_t m_forwardPassIndex;
std::size_t m_lastVisibilityHash;
std::shared_ptr<LightUboPool> m_lightUboPool;
@@ -88,10 +102,10 @@ namespace Nz
std::vector<ElementRenderer::RenderStates> m_renderStates;
std::vector<RenderElementOwner> m_renderElements;
std::unordered_map<const MaterialInstance*, MaterialPassEntry> m_materialInstances;
std::unordered_map<const RenderElement*, RenderBufferView> m_lightPerRenderElement;
std::unordered_map<const RenderElement*, LightPerElementData> m_lightPerRenderElement;
std::unordered_map<LightKey, RenderBufferView, LightKeyHasher> m_lightBufferPerLights;
std::vector<LightDataUbo> m_lightDataBuffers;
std::vector<const Light*> m_renderableLights;
std::vector<RenderableLight> m_renderableLights;
RenderQueue<const RenderElement*> m_renderQueue;
RenderQueueRegistry m_renderQueueRegistry;
AbstractViewer* m_viewer;

View File

@@ -39,6 +39,9 @@ namespace Nz
virtual std::size_t RegisterViewer(AbstractViewer* viewerInstance, Int32 renderOrder) = 0;
virtual std::size_t RegisterWorldInstance(WorldInstancePtr worldInstance) = 0;
virtual const Light* RetrieveLight(std::size_t lightIndex) const = 0;
virtual const Texture* RetrieveLightShadowmap(std::size_t lightIndex) const = 0;
virtual void Render(RenderFrame& renderFrame) = 0;
virtual void UnregisterLight(std::size_t lightIndex) = 0;

View File

@@ -74,6 +74,7 @@ namespace Nz
struct DefaultTextures
{
std::array<std::shared_ptr<Texture>, ImageTypeCount> depthTextures;
std::array<std::shared_ptr<Texture>, ImageTypeCount> whiteTextures;
};

View File

@@ -24,6 +24,7 @@ namespace Nz
std::size_t parameter2;
std::size_t parameter3;
std::size_t shadowMappingFlag;
std::size_t viewProjMatrix;
};
std::size_t lightsOffset;

View File

@@ -55,9 +55,11 @@ namespace Nz
private:
inline void UpdateBoundingVolume();
inline void UpdateViewProjMatrix();
Color m_color;
Quaternionf m_rotation;
Matrix4f m_viewProjMatrix;
RadianAnglef m_innerAngle;
RadianAnglef m_outerAngle;
Vector3f m_direction;

View File

@@ -97,8 +97,6 @@ namespace Nz
{
m_innerAngle = innerAngle;
m_innerAngleCos = m_innerAngle.GetCos();
UpdateBoundingVolume();
}
inline void SpotLight::UpdateOuterAngle(RadianAnglef outerAngle)
@@ -108,6 +106,7 @@ namespace Nz
m_outerAngleTan = m_outerAngle.GetTan();
UpdateBoundingVolume();
UpdateViewProjMatrix();
}
inline void SpotLight::UpdatePosition(const Vector3f& position)
@@ -115,6 +114,7 @@ namespace Nz
m_position = position;
UpdateBoundingVolume();
UpdateViewProjMatrix();
}
inline void SpotLight::UpdateRadius(float radius)
@@ -123,6 +123,7 @@ namespace Nz
m_invRadius = 1.f / m_radius;
UpdateBoundingVolume();
UpdateViewProjMatrix();
}
inline void SpotLight::UpdateRotation(const Quaternionf& rotation)
@@ -131,6 +132,7 @@ namespace Nz
m_direction = rotation * Vector3f::Forward();
UpdateBoundingVolume();
UpdateViewProjMatrix();
}
inline void SpotLight::UpdateBoundingVolume()
@@ -158,6 +160,19 @@ namespace Nz
Light::UpdateBoundingVolume(boundingVolume); //< will trigger OnLightDataInvalided
}
inline void SpotLight::UpdateViewProjMatrix()
{
Matrix4f biasMatrix(0.5f, 0.0f, 0.0f, 0.0f,
0.0f, 0.5f, 0.0f, 0.0f,
0.0f, 0.0f, 1.0f, 0.0f,
0.5f, 0.5f, 0.0f, 1.0f);
Matrix4f projection = Matrix4f::Perspective(m_outerAngle * 2.f, 1.f, 1.f, m_radius);
Matrix4f view = Matrix4f::TransformInverse(m_position, m_rotation);
m_viewProjMatrix = view * projection * biasMatrix;
}
}
#include <Nazara/Graphics/DebugOff.hpp>

View File

@@ -33,6 +33,7 @@ namespace Nz
private:
std::vector<ShaderBinding::Binding> m_bindingCache;
std::vector<ShaderBinding::TextureBinding> m_textureBindingCache;
RenderElementPool<RenderSubmesh> m_submeshPool;
};

View File

@@ -16,7 +16,7 @@ namespace Nz
{
class OpenGLRenderPipelineLayout;
class NAZARA_OPENGLRENDERER_API OpenGLShaderBinding : public ShaderBinding
class NAZARA_OPENGLRENDERER_API OpenGLShaderBinding final : public ShaderBinding
{
public:
inline OpenGLShaderBinding(OpenGLRenderPipelineLayout& owner, std::size_t poolIndex, std::size_t bindingIndex);
@@ -38,6 +38,7 @@ namespace Nz
OpenGLShaderBinding& operator=(OpenGLShaderBinding&&) = delete;
private:
void HandleTextureBinding(UInt32 bindingIndex, const TextureBinding& textureBinding);
void Release() override;
OpenGLRenderPipelineLayout& m_owner;

View File

@@ -33,7 +33,7 @@ namespace Nz
inline GLenum ToOpenGL(BlendEquation blendEquation);
inline GLenum ToOpenGL(BlendFunc blendFunc);
inline GLenum ToOpenGL(FaceFilling filling);
inline GLenum ToOpenGL(FaceSide side);
inline GLenum ToOpenGL(FaceCulling side);
inline GLenum ToOpenGL(FrontFace face);
inline GLenum ToOpenGL(IndexType indexType);
inline GLenum ToOpenGL(PrimitiveMode primitiveMode);

View File

@@ -92,16 +92,16 @@ namespace Nz
return {};
}
inline GLenum ToOpenGL(FaceSide side)
inline GLenum ToOpenGL(FaceCulling side)
{
switch (side)
{
case FaceSide::None:
case FaceCulling::None:
break;
case FaceSide::Back: return GL_BACK;
case FaceSide::Front: return GL_FRONT;
case FaceSide::FrontAndBack: return GL_FRONT_AND_BACK;
case FaceCulling::Back: return GL_BACK;
case FaceCulling::Front: return GL_FRONT;
case FaceCulling::FrontAndBack: return GL_FRONT_AND_BACK;
}
NazaraError("Unhandled FaceSide 0x" + NumberToString(UnderlyingCast(side), 16));

View File

@@ -141,6 +141,7 @@ typedef void (GL_APIENTRYP PFNGLSPECIALIZESHADERPROC) (GLuint shader, const GLch
cb(glLinkProgram, PFNGLLINKPROGRAMPROC) \
cb(glMapBufferRange, PFNGLMAPBUFFERRANGEPROC) \
cb(glPixelStorei, PFNGLPIXELSTOREIPROC) \
cb(glPolygonOffset, PFNGLPOLYGONOFFSETPROC) \
cb(glProgramBinary, PFNGLPROGRAMBINARYPROC) \
cb(glProgramParameteri, PFNGLPROGRAMPARAMETERIPROC) \
cb(glReadPixels, PFNGLREADPIXELSPROC) \

View File

@@ -21,8 +21,9 @@ namespace Nz
{
struct Binding
{
UInt32 setIndex = 0;
UInt32 arraySize = 1;
UInt32 bindingIndex;
UInt32 setIndex = 0;
ShaderBindingType type;
nzsl::ShaderStageTypeFlags shaderStageFlags;
};

View File

@@ -20,13 +20,13 @@ namespace Nz
struct RenderStates
{
ColorComponentMask colorWriteMask = ColorComponentAll;
FaceCulling faceCulling = FaceCulling::Back;
FaceFilling faceFilling = FaceFilling::Fill;
FaceSide cullingSide = FaceSide::Back;
FrontFace frontFace = FrontFace::CounterClockwise;
RendererComparison depthCompare = RendererComparison::LessOrEqual;
PrimitiveMode primitiveMode = PrimitiveMode::TriangleList;
struct
struct
{
BlendEquation modeAlpha = BlendEquation::Add;
BlendEquation modeColor = BlendEquation::Add;
@@ -48,13 +48,15 @@ namespace Nz
} stencilBack, stencilFront;
bool blending = false;
bool depthBias = false;
bool depthBuffer = false;
bool depthClamp = false;
bool depthWrite = true;
bool faceCulling = false;
bool scissorTest = false;
bool stencilTest = false;
float depthBiasConstantFactor = 0.f;
float depthBiasSlopeFactor = 0.f;
float lineWidth = 1.f;
float pointSize = 1.f;
};

View File

@@ -17,9 +17,9 @@ namespace Nz
#define NazaraRenderStateFloatMember(field, maxDiff) if (!NumberEquals(lhs.field, rhs.field, maxDiff)) return false
NazaraRenderStateBoolMember(blending);
NazaraRenderStateBoolMember(depthBias);
NazaraRenderStateBoolMember(depthBuffer);
NazaraRenderStateBoolMember(depthClamp);
NazaraRenderStateBoolMember(faceCulling);
NazaraRenderStateBoolMember(scissorTest);
NazaraRenderStateBoolMember(stencilTest);
@@ -27,6 +27,7 @@ namespace Nz
NazaraRenderStateBoolMember(depthWrite);
NazaraRenderStateMember(colorWriteMask);
NazaraRenderStateMember(faceCulling);
NazaraRenderStateMember(faceFilling);
if (lhs.blending) //< Remember, at this time we know lhs.blending == rhs.blending
@@ -42,8 +43,11 @@ namespace Nz
if (lhs.depthBuffer)
NazaraRenderStateMember(depthCompare);
if (lhs.faceCulling)
NazaraRenderStateMember(cullingSide);
if (lhs.depthBias)
{
NazaraRenderStateMember(depthBiasConstantFactor);
NazaraRenderStateMember(depthBiasSlopeFactor);
}
if (lhs.stencilTest)
{
@@ -95,15 +99,16 @@ namespace std
#define NazaraRenderStateUInt32(member) Nz::HashCombine(seed, pipelineInfo.member)
NazaraRenderStateBool(blending);
NazaraRenderStateBool(depthBias);
NazaraRenderStateBool(depthBuffer);
NazaraRenderStateBool(depthClamp);
NazaraRenderStateBool(faceCulling);
NazaraRenderStateBool(scissorTest);
NazaraRenderStateBool(stencilTest);
NazaraRenderStateBoolDep(depthBuffer, depthWrite);
NazaraRenderStateUInt8(colorWriteMask);
NazaraRenderStateEnum(faceCulling);
NazaraRenderStateEnum(faceFilling);
if (pipelineInfo.blending) //< we don't care about blending state if blending isn't enabled
@@ -119,8 +124,11 @@ namespace std
if (pipelineInfo.depthBuffer)
NazaraRenderStateEnum(depthCompare);
if (pipelineInfo.faceCulling)
NazaraRenderStateEnum(cullingSide);
if (pipelineInfo.depthBias)
{
NazaraRenderStateFloat(depthBiasConstantFactor, 0.001f);
NazaraRenderStateFloat(depthBiasSlopeFactor, 0.001f);
}
if (pipelineInfo.stencilTest) //< we don't care about stencil state if stencil isn't enabled
{

View File

@@ -56,6 +56,12 @@ namespace Nz
const TextureSampler* sampler;
};
struct TextureBindings
{
UInt32 arraySize;
const TextureBinding* textureBindings;
};
struct UniformBufferBinding
{
RenderBuffer* buffer;
@@ -66,7 +72,7 @@ namespace Nz
struct Binding
{
UInt32 bindingIndex;
std::variant<StorageBufferBinding, TextureBinding, UniformBufferBinding> content;
std::variant<StorageBufferBinding, TextureBinding, TextureBindings, UniformBufferBinding> content;
};
protected:

View File

@@ -24,6 +24,8 @@ namespace Nz
SamplerWrap wrapModeU = SamplerWrap::Clamp;
SamplerWrap wrapModeV = SamplerWrap::Clamp;
SamplerWrap wrapModeW = SamplerWrap::Clamp;
bool depthCompare = false;
RendererComparison depthComparison = RendererComparison::LessOrEqual;
inline bool operator==(const TextureSamplerInfo& samplerInfo) const;
inline bool operator!=(const TextureSamplerInfo& samplerInfo) const;

View File

@@ -32,6 +32,12 @@ namespace Nz
if (wrapModeW != samplerInfo.wrapModeW)
return false;
if (depthCompare != samplerInfo.depthCompare)
return false;
if (depthComparison != samplerInfo.depthComparison)
return false;
return true;
}
@@ -54,6 +60,8 @@ struct std::hash<Nz::TextureSamplerInfo>
Nz::HashCombine(seed, sampler.wrapModeU);
Nz::HashCombine(seed, sampler.wrapModeV);
Nz::HashCombine(seed, sampler.wrapModeW);
Nz::HashCombine(seed, sampler.depthCompare);
Nz::HashCombine(seed, sampler.depthComparison);
return seed;
}

View File

@@ -147,7 +147,7 @@ namespace Nz
Max = Point
};
enum class FaceSide
enum class FaceCulling
{
None,

View File

@@ -23,7 +23,7 @@ namespace Nz
inline VkAttachmentStoreOp ToVulkan(AttachmentStoreOp storeOp);
inline VkBufferUsageFlags ToVulkan(BufferType bufferType);
inline VkFormat ToVulkan(ComponentType componentType);
inline VkCullModeFlagBits ToVulkan(FaceSide faceSide);
inline VkCullModeFlagBits ToVulkan(FaceCulling faceSide);
inline VkPolygonMode ToVulkan(FaceFilling faceFilling);
inline VkFrontFace ToVulkan(FrontFace frontFace);
inline VkIndexType ToVulkan(IndexType indexType);

View File

@@ -130,14 +130,14 @@ namespace Nz
return VK_FORMAT_UNDEFINED;
}
inline VkCullModeFlagBits ToVulkan(FaceSide faceSide)
inline VkCullModeFlagBits ToVulkan(FaceCulling faceSide)
{
switch (faceSide)
{
case FaceSide::None: return VK_CULL_MODE_NONE;
case FaceSide::Back: return VK_CULL_MODE_BACK_BIT;
case FaceSide::Front: return VK_CULL_MODE_FRONT_BIT;
case FaceSide::FrontAndBack: return VK_CULL_MODE_FRONT_AND_BACK;
case FaceCulling::None: return VK_CULL_MODE_NONE;
case FaceCulling::Back: return VK_CULL_MODE_BACK_BIT;
case FaceCulling::Front: return VK_CULL_MODE_FRONT_BIT;
case FaceCulling::FrontAndBack: return VK_CULL_MODE_FRONT_AND_BACK;
}
NazaraError("Unhandled FaceSide 0x" + NumberToString(UnderlyingCast(faceSide), 16));