From 0cf13bcff535d64b40db8c7986a4152b94af6286 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Thu, 6 May 2021 17:02:10 +0200 Subject: [PATCH] Adding basic depth prepass --- res/shaders/ComputeFrustums.slang | 2 - res/shaders/DepthPrepass.slang | 4 - res/shaders/ForwardPlus.slang | 3 +- res/shaders/LightCulling.slang | 2 - res/shaders/lib/Common.slang | 4 +- res/shaders/lib/LightEnv.slang | 4 +- res/shaders/lib/Material.slang | 2 +- res/shaders/lib/PrimitiveSceneData.slang | 2 +- res/shaders/lib/StaticMeshVertexInput.slang | 54 +++-- src/Engine/Asset/MeshLoader.cpp | 1 + src/Engine/Containers/Array.h | 2 +- src/Engine/Containers/List.h | 4 + src/Engine/Graphics/Graphics.h | 3 +- src/Engine/Graphics/GraphicsInitializer.h | 12 +- src/Engine/Graphics/GraphicsResources.cpp | 19 +- src/Engine/Graphics/GraphicsResources.h | 33 +++- src/Engine/Graphics/RenderPass/BasePass.cpp | 74 ++++--- src/Engine/Graphics/RenderPass/BasePass.h | 35 ++-- src/Engine/Graphics/RenderPass/CMakeLists.txt | 8 +- .../Graphics/RenderPass/DepthPrepass.cpp | 185 ++++++++++++++++++ src/Engine/Graphics/RenderPass/DepthPrepass.h | 68 +++++++ .../Graphics/RenderPass/LightCullingPass.cpp | 83 ++++++++ .../Graphics/RenderPass/LightCullingPass.h | 51 +++++ .../Graphics/RenderPass/RenderGraph.cpp | 39 ++++ src/Engine/Graphics/RenderPass/RenderGraph.h | 21 ++ src/Engine/Graphics/RenderPass/RenderPass.cpp | 13 ++ src/Engine/Graphics/RenderPass/RenderPass.h | 35 ++++ src/Engine/Graphics/StaticMeshVertexInput.cpp | 10 +- src/Engine/Graphics/StaticMeshVertexInput.h | 2 +- src/Engine/Graphics/VertexShaderInput.cpp | 2 +- .../Graphics/Vulkan/VulkanDescriptorSets.cpp | 8 +- .../Graphics/Vulkan/VulkanDescriptorSets.h | 3 +- src/Engine/Graphics/Vulkan/VulkanGraphics.cpp | 10 +- src/Engine/Graphics/Vulkan/VulkanGraphics.h | 3 +- .../Graphics/Vulkan/VulkanGraphicsResources.h | 2 +- src/Engine/Graphics/Vulkan/VulkanPipeline.cpp | 22 +++ src/Engine/Graphics/Vulkan/VulkanPipeline.h | 12 ++ .../Graphics/Vulkan/VulkanPipelineCache.cpp | 21 ++ .../Graphics/Vulkan/VulkanPipelineCache.h | 1 + src/Engine/Graphics/Vulkan/VulkanShader.cpp | 2 +- src/Engine/Graphics/Vulkan/VulkanViewport.cpp | 2 +- src/Engine/Material/BRDF.cpp | 4 +- src/Engine/Material/Material.cpp | 2 +- src/Engine/Scene/Actor/Actor.cpp | 11 +- src/Engine/Scene/Components/Component.cpp | 5 +- src/Engine/Scene/Scene.cpp | 26 +-- src/Engine/Scene/Scene.h | 3 + src/Engine/Scene/SceneUpdater.cpp | 75 +++++++ src/Engine/Scene/SceneUpdater.h | 18 +- src/Engine/Window/SceneRenderPath.cpp | 12 +- src/Engine/Window/SceneRenderPath.h | 6 +- src/Engine/main.cpp | 10 +- 52 files changed, 880 insertions(+), 155 deletions(-) create mode 100644 src/Engine/Graphics/RenderPass/LightCullingPass.cpp create mode 100644 src/Engine/Graphics/RenderPass/LightCullingPass.h create mode 100644 src/Engine/Graphics/RenderPass/RenderGraph.cpp create mode 100644 src/Engine/Graphics/RenderPass/RenderGraph.h create mode 100644 src/Engine/Graphics/RenderPass/RenderPass.cpp create mode 100644 src/Engine/Graphics/RenderPass/RenderPass.h diff --git a/res/shaders/ComputeFrustums.slang b/res/shaders/ComputeFrustums.slang index e35582b..7c3931e 100644 --- a/res/shaders/ComputeFrustums.slang +++ b/res/shaders/ComputeFrustums.slang @@ -1,5 +1,3 @@ - -import LightEnv; import Common; struct ComputeShaderInput diff --git a/res/shaders/DepthPrepass.slang b/res/shaders/DepthPrepass.slang index 39f5603..2c64826 100644 --- a/res/shaders/DepthPrepass.slang +++ b/res/shaders/DepthPrepass.slang @@ -4,10 +4,6 @@ import VERTEX_INPUT_IMPORT; import MATERIAL_IMPORT; import PrimitiveSceneData; -struct ModelParameter -{ - float4x4 modelMatrix; -} struct VertexStageOutput { diff --git a/res/shaders/ForwardPlus.slang b/res/shaders/ForwardPlus.slang index cccda9e..7a0852b 100644 --- a/res/shaders/ForwardPlus.slang +++ b/res/shaders/ForwardPlus.slang @@ -38,6 +38,7 @@ VertexStageOutput vertexMain( clipSpacePosition = mul(gViewParams.projectionMatrix, viewSpacePosition); output.position = clipSpacePosition; output.shaderAttributeInterpolation = input.getInterpolants(cache, vertexParams); + output.cache = cache; return output; } @@ -72,5 +73,5 @@ float4 fragmentMain( result += pointLight.illuminate(materialParams, brdf, viewDir); } - return float4(result, 1); + return float4(result, 0); } diff --git a/res/shaders/LightCulling.slang b/res/shaders/LightCulling.slang index 945badf..f27c070 100644 --- a/res/shaders/LightCulling.slang +++ b/res/shaders/LightCulling.slang @@ -19,8 +19,6 @@ cbuffer DispatchParams layout(binding = 2) RWTexture2D depthTextureVS; -layout(binding = 3) -ConstantBuffer lights; layout(binding = 4) StructuredBuffer frustums; diff --git a/res/shaders/lib/Common.slang b/res/shaders/lib/Common.slang index fd8fc74..e0aa45a 100644 --- a/res/shaders/lib/Common.slang +++ b/res/shaders/lib/Common.slang @@ -8,7 +8,7 @@ struct ViewParameter float4x4 projectionMatrix; float4 cameraPos_WS; } -layout(set = 1, binding = 0, std430) +layout(set = INDEX_VIEW_PARAMS, binding = 0, std430) ConstantBuffer gViewParams; struct ScreenToViewParams @@ -16,7 +16,7 @@ struct ScreenToViewParams float4x4 inverseProjection; float2 screenDimensions; } -layout(set = 1, binding = 1, std430) +layout(set = INDEX_VIEW_PARAMS, binding = 1, std430) ConstantBuffer gScreenToViewParams; // Convert clip space coordinates to view space diff --git a/res/shaders/lib/LightEnv.slang b/res/shaders/lib/LightEnv.slang index a70b4ba..757e553 100644 --- a/res/shaders/lib/LightEnv.slang +++ b/res/shaders/lib/LightEnv.slang @@ -15,7 +15,7 @@ struct DirectionalLight : ILightEnv float3 illuminate(MaterialFragmentParameter input, B brdf, float3 wo) { - return intensity.xyz * brdf.evaluate(wo, direction.xyz, input.worldNormal, input.worldTangent, input.worldBiTangent, color.xyz); + return intensity.xyz * brdf.evaluate(wo, normalize(direction.xyz), input.worldNormal, input.worldTangent, input.worldBiTangent, color.xyz); } }; @@ -68,5 +68,5 @@ struct Lights uint numPointLights; }; -layout(set = 0, binding = 0, std430) +layout(set = INDEX_LIGHT_ENV, binding = 0, std430) ConstantBuffer gLightEnv; diff --git a/res/shaders/lib/Material.slang b/res/shaders/lib/Material.slang index 9a343c1..cfd2f47 100644 --- a/res/shaders/lib/Material.slang +++ b/res/shaders/lib/Material.slang @@ -18,5 +18,5 @@ interface IMaterial }; type_param TMaterial : IMaterial; -layout(set = 2, binding = 0, std430) +layout(set = INDEX_MATERIAL, binding = 0, std430) ParameterBlock gMaterial; diff --git a/res/shaders/lib/PrimitiveSceneData.slang b/res/shaders/lib/PrimitiveSceneData.slang index d0c72aa..3c7e2cb 100644 --- a/res/shaders/lib/PrimitiveSceneData.slang +++ b/res/shaders/lib/PrimitiveSceneData.slang @@ -5,5 +5,5 @@ struct PrimitiveSceneData float4 actorLocation; }; -layout(set = 3, binding = 0, std430) +layout(set = INDEX_SCENE_DATA, binding = 0, std430) ConstantBuffer gSceneData; diff --git a/res/shaders/lib/StaticMeshVertexInput.slang b/res/shaders/lib/StaticMeshVertexInput.slang index bc1d7c0..60e5acd 100644 --- a/res/shaders/lib/StaticMeshVertexInput.slang +++ b/res/shaders/lib/StaticMeshVertexInput.slang @@ -12,7 +12,6 @@ struct VertexValueCache //leading to a compiler error float3 tangentToLocal[3]; float3 tangentToWorld[3]; - float tangentToWorldSign; float4 color; float3x3 getTangentToLocal() @@ -46,8 +45,9 @@ struct VertexValueCache struct ShaderAttributeInterpolation { float3 worldPosition; - float3 tangentX; - float4 tangentZ; + float3 normal; + float3 tangent; + float3 biTangent; float4 color; #if NUM_MATERIAL_TEXCOORDS float4 packedTexCoords[(NUM_MATERIAL_TEXCOORDS+1) / 2]; @@ -72,16 +72,15 @@ struct ShaderAttributeInterpolation } } #endif - float3 tangentY = cross(tangentZ.xyz, tangentX) * tangentZ.w; - result.tangentToWorld[0] = cross(tangentY, tangentZ.xyz) * tangentZ.w; - result.tangentToWorld[1] = tangentY; - result.tangentToWorld[2] = tangentZ.xyz; + result.tangentToWorld[0] = tangent; + result.tangentToWorld[1] = biTangent; + result.tangentToWorld[2] = normal; result.clipPosition = clipSpacePosition; result.worldPosition = worldPosition; result.viewDir = gViewParams.cameraPos_WS.xyz - worldPosition; - result.worldNormal = tangentZ.xyz; - result.worldTangent = tangentX; - result.worldBiTangent = tangentY; + result.worldNormal = normal; + result.worldTangent = tangent; + result.worldBiTangent = biTangent; result.vertexColor = color; return result; } @@ -90,8 +89,9 @@ struct ShaderAttributeInterpolation struct VertexShaderInput { float4 position; - float3 tangentX; - float4 tangentZ; + float3 normal; + float3 tangent; + float3 biTangent; float4 color; #if NUM_MATERIAL_TEXCOORDS #if NUM_MATERIAL_TEXCOORDS > 1 @@ -118,15 +118,12 @@ struct VertexShaderInput float3 instanceTransform3; #endif // USE_INSTANCING - float3x3 calcTangentToLocal(out float tangentSign) + float3x3 calcTangentToLocal() { float3x3 result; - tangentSign = tangentZ.w; - - float3 tangentY = cross(tangentZ.xyz, tangentX) * tangentZ.w; - result[0] = cross(tangentY, tangentZ.xyz) * tangentZ.w; - result[1] = tangentY; - result[2] = tangentZ.xyz; + result[0] = tangent; + result[1] = biTangent; + result[2] = normal; return result; } @@ -149,17 +146,14 @@ struct VertexShaderInput cache.instanceOrigin = instanceOrigin; #endif - float tangentSign; - float3x3 tangentToLocal = calcTangentToLocal(tangentSign); + float3x3 tangentToLocal = calcTangentToLocal(); cache.tangentToLocal[0] = tangentToLocal[0]; cache.tangentToLocal[1] = tangentToLocal[1]; cache.tangentToLocal[2] = tangentToLocal[2]; - float3x3 localToWorld = float3x3(gSceneData.localToWorld[0].xyz, gSceneData.localToWorld[1].xyz, gSceneData.localToWorld[2].xyz); - float3x3 tangentToWorld = mul(tangentToLocal, localToWorld); - cache.tangentToWorld[0] = tangentToWorld[0]; - cache.tangentToWorld[1] = tangentToWorld[1]; - cache.tangentToWorld[2] = tangentToWorld[2]; - cache.tangentToWorldSign = tangentSign; + + cache.tangentToWorld[0] = mul(gSceneData.localToWorld, float4(tangentToLocal[0], 0.0f)).xyz; + cache.tangentToWorld[1] = mul(gSceneData.localToWorld, float4(tangentToLocal[1], 0.0f)).xyz; + cache.tangentToWorld[2] = mul(gSceneData.localToWorld, float4(tangentToLocal[2], 0.0f)).xyz; return cache; } @@ -186,8 +180,10 @@ struct VertexShaderInput ShaderAttributeInterpolation getInterpolants(VertexValueCache cache, MaterialVertexParameter vertexParams) { ShaderAttributeInterpolation result = (ShaderAttributeInterpolation)0; - result.tangentX = tangentX; - result.tangentZ = tangentZ; + float3x3 tangentToWorld = cache.getTangentToWorld(); + result.normal = mul(gSceneData.localToWorld, float4(normal, 0.0f)).xyz; + result.tangent = mul(gSceneData.localToWorld, float4(tangent, 0.0f)).xyz; + result.biTangent = mul(gSceneData.localToWorld, float4(biTangent, 0.0f)).xyz; result.color = color; result.worldPosition = vertexParams.worldPosition; for(int i = 0; i < NUM_MATERIAL_TEXCOORDS; ++i) diff --git a/src/Engine/Asset/MeshLoader.cpp b/src/Engine/Asset/MeshLoader.cpp index bbe841a..e13ad3e 100644 --- a/src/Engine/Asset/MeshLoader.cpp +++ b/src/Engine/Asset/MeshLoader.cpp @@ -164,6 +164,7 @@ void MeshLoader::loadGlobalMeshes(const aiScene* scene, Array& globalMesh { //TODO: use bitangent to calculate sign for 4th coordinate of tangentstream data.tangentBasisComponents[1] = createVertexStream(mesh->mNumVertices, mesh->mTangents, graphics); + data.tangentBasisComponents[2] = createVertexStream(mesh->mNumVertices, mesh->mBitangents, graphics); } if(mesh->HasVertexColors(0)) { diff --git a/src/Engine/Containers/Array.h b/src/Engine/Containers/Array.h index 3dd591d..07150cb 100644 --- a/src/Engine/Containers/Array.h +++ b/src/Engine/Containers/Array.h @@ -334,7 +334,7 @@ namespace Seele } void resize(size_t newSize) { - if (newSize < allocated) + if (newSize <= allocated) { arraySize = newSize; } diff --git a/src/Engine/Containers/List.h b/src/Engine/Containers/List.h index 1340ee2..30db0ae 100644 --- a/src/Engine/Containers/List.h +++ b/src/Engine/Containers/List.h @@ -37,6 +37,7 @@ public: , endIt(std::move(other.endIt)) , _size(std::move(other._size)) { + other._size = 0; } ~List() { @@ -75,6 +76,7 @@ public: beginIt = other.beginIt; endIt = other.endIt; _size = other._size; + other._size = 0; } return *this; } @@ -252,10 +254,12 @@ public: } void popBack() { + assert(_size > 0); remove(Iterator(tail->prev)); } void popFront() { + assert(_size > 0); remove(Iterator(root)); } Iterator insert(Iterator pos, const T &value) diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 42ffe1e..2367426 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -48,9 +48,10 @@ public: virtual PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) = 0; virtual PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) = 0; virtual PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) = 0; + virtual PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) = 0; virtual PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) = 0; - virtual PDescriptorLayout createDescriptorLayout() = 0; + virtual PDescriptorLayout createDescriptorLayout(const std::string& name = "") = 0; virtual PPipelineLayout createPipelineLayout() = 0; PVertexBuffer getNullVertexBuffer(); diff --git a/src/Engine/Graphics/GraphicsInitializer.h b/src/Engine/Graphics/GraphicsInitializer.h index 37f5c75..2be5ac1 100644 --- a/src/Engine/Graphics/GraphicsInitializer.h +++ b/src/Engine/Graphics/GraphicsInitializer.h @@ -120,6 +120,7 @@ struct ShaderCreateInfo { //It's possible to input multiple source files for materials or vertexFactories Array shaderCode; + std::string name; // Debug info std::string entryPoint; Array typeParameter; Map defines; @@ -231,7 +232,7 @@ struct GraphicsPipelineCreateInfo rasterizationState.cullMode = Gfx::SE_CULL_MODE_BACK_BIT; rasterizationState.polygonMode = Gfx::SE_POLYGON_MODE_FILL; rasterizationState.frontFace = Gfx::SE_FRONT_FACE_COUNTER_CLOCKWISE; - depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS; + depthStencilState.depthCompareOp = Gfx::SE_COMPARE_OP_LESS_OR_EQUAL; depthStencilState.minDepthBounds = 0.0f; depthStencilState.maxDepthBounds = 1.0f; depthStencilState.stencilTestEnable = false; @@ -246,4 +247,13 @@ struct GraphicsPipelineCreateInfo colorBlend.blendConstants[3] = 1.0f; } }; +struct ComputePipelineCreateInfo +{ + Gfx::PComputeShader computeShader; + Gfx::PPipelineLayout pipelineLayout; + ComputePipelineCreateInfo() + { + std::memset((void*)this, 0, sizeof(*this)); + } +}; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/GraphicsResources.cpp b/src/Engine/Graphics/GraphicsResources.cpp index b641160..365270c 100644 --- a/src/Engine/Graphics/GraphicsResources.cpp +++ b/src/Engine/Graphics/GraphicsResources.cpp @@ -2,6 +2,8 @@ #include "Material/MaterialInstance.h" #include "Material/Material.h" #include "Graphics.h" +#include "RenderPass/DepthPrepass.h" +#include "RenderPass/BasePass.h" using namespace Seele; using namespace Seele::Gfx; @@ -18,6 +20,16 @@ std::string getShaderNameFromRenderPassType(Gfx::RenderPassType type) return ""; } } +void modifyRenderPassMacros(Gfx::RenderPassType type, Map& defines) +{ + switch (type) + { + case Gfx::RenderPassType::DepthPrepass: + DepthPrepass::modifyRenderPassMacros(defines); + case Gfx::RenderPassType::BasePass: + BasePass::modifyRenderPassMacros(defines); + } +} ShaderMap::ShaderMap() { @@ -55,6 +67,8 @@ ShaderCollection& ShaderMap::createShaders( createInfo.defines["MATERIAL_IMPORT"] = material->getName().c_str(); createInfo.defines["NUM_MATERIAL_TEXCOORDS"] = "1"; createInfo.defines["USE_INSTANCING"] = "0"; + modifyRenderPassMacros(renderPass, createInfo.defines); + createInfo.name = getShaderNameFromRenderPassType(renderPass) + " Material " + material->getName(); std::ifstream codeStream("./shaders/" + getShaderNameFromRenderPassType(renderPass), std::ios::ate); auto fileSize = codeStream.tellg(); @@ -113,7 +127,8 @@ void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layo { descriptorSetLayouts.resize(setIndex + 1); } - if (descriptorSetLayouts[setIndex] != nullptr) + // After a second thought, merging descriptor layout bindings is not a good idea + /*if (descriptorSetLayouts[setIndex] != nullptr) { auto &thisBindings = descriptorSetLayouts[setIndex]->descriptorBindings; auto &otherBindings = layout->descriptorBindings; @@ -126,7 +141,7 @@ void PipelineLayout::addDescriptorLayout(uint32 setIndex, PDescriptorLayout layo } } } - else + else*/ { descriptorSetLayouts[setIndex] = layout; } diff --git a/src/Engine/Graphics/GraphicsResources.h b/src/Engine/Graphics/GraphicsResources.h index 3d6b0f0..544c32d 100644 --- a/src/Engine/Graphics/GraphicsResources.h +++ b/src/Engine/Graphics/GraphicsResources.h @@ -75,6 +75,14 @@ public: }; DEFINE_REF(FragmentShader) +class ComputeShader +{ +public: + ComputeShader() {} + virtual ~ComputeShader() {} +}; +DEFINE_REF(ComputeShader) + //Uniquely identifies a permutation of shaders //using the type parameters used to generate it struct ShaderPermutation @@ -204,8 +212,9 @@ DEFINE_REF(DescriptorSet) class DescriptorLayout { public: - DescriptorLayout() + DescriptorLayout(const std::string& name) : setIndex(0) + , name(name) { } virtual ~DescriptorLayout() {} @@ -232,6 +241,7 @@ protected: Array descriptorBindings; PDescriptorAllocator allocator; uint32 setIndex; + std::string name; friend class PipelineLayout; friend class DescriptorAllocator; }; @@ -441,6 +451,19 @@ protected: }; DEFINE_REF(GraphicsPipeline) +class ComputePipeline +{ +public: + ComputePipeline(const ComputePipelineCreateInfo& createInfo, PPipelineLayout layout) : createInfo(createInfo), layout(layout) {} + virtual ~ComputePipeline(){} + const ComputePipelineCreateInfo& getCreateInfo() const { return createInfo; } + PPipelineLayout getPipelineLayout() const { return layout; } +protected: + ComputePipelineCreateInfo createInfo; + PPipelineLayout layout; +}; +DEFINE_REF(ComputePipeline) + // IMPORTANT!! // WHEN DERIVING FROM ANY Gfx:: BASE CLASSES WITH MULTIPLE INHERITANCE // ALWAYS PUT THE Gfx:: BASE CLASS FIRST @@ -505,7 +528,7 @@ public: virtual void beginFrame() = 0; virtual void endFrame() = 0; virtual void onWindowCloseEvent() = 0; - virtual PTexture2D getBackBuffer() = 0; + virtual PTexture2D getBackBuffer() const = 0; virtual void setKeyCallback(std::function callback) = 0; virtual void setMouseMoveCallback(std::function callback) = 0; virtual void setMouseButtonCallback(std::function callback) = 0; @@ -559,7 +582,7 @@ public: SeAttachmentStoreOp storeOp = SE_ATTACHMENT_STORE_OP_STORE, SeAttachmentLoadOp stencilLoadOp = SE_ATTACHMENT_LOAD_OP_DONT_CARE, SeAttachmentStoreOp stencilStoreOp = SE_ATTACHMENT_STORE_OP_DONT_CARE) - : texture(texture), loadOp(loadOp), storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp) + : loadOp(loadOp), storeOp(storeOp), stencilLoadOp(stencilLoadOp), stencilStoreOp(stencilStoreOp), texture(texture) { } virtual ~RenderTargetAttachment() @@ -583,12 +606,12 @@ public: inline SeAttachmentStoreOp getStencilStoreOp() const { return stencilStoreOp; } SeClearValue clear; SeColorComponentFlags componentFlags; -protected: - PTexture2D texture; SeAttachmentLoadOp loadOp; SeAttachmentStoreOp storeOp; SeAttachmentLoadOp stencilLoadOp; SeAttachmentStoreOp stencilStoreOp; +protected: + PTexture2D texture; }; DEFINE_REF(RenderTargetAttachment) diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 3636a82..821f4c9 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -4,6 +4,7 @@ #include "Scene/Components/CameraComponent.h" #include "Scene/Actor/CameraActor.h" #include "Math/Vector.h" +#include "RenderGraph.h" using namespace Seele; @@ -46,10 +47,10 @@ void BasePassMeshProcessor::addMeshBatch( renderCommand->setViewport(target); for(uint32 i = 0; i < batch.elements.size(); ++i) { - pipelineLayout->addDescriptorLayout(2, material->getRenderMaterial()->getDescriptorLayout()); + pipelineLayout->addDescriptorLayout(BasePass::INDEX_MATERIAL, material->getRenderMaterial()->getDescriptorLayout()); pipelineLayout->create(); - descriptorSets[2] = material->getDescriptor(); - descriptorSets[3] = cachedPrimitiveSets[cachedPrimitiveIndex++]; + descriptorSets[BasePass::INDEX_MATERIAL] = material->getDescriptor(); + descriptorSets[BasePass::INDEX_SCENE_DATA] = cachedPrimitiveSets[cachedPrimitiveIndex++]; buildMeshDrawCommand(batch, // primitiveComponent, renderPass, @@ -78,42 +79,29 @@ void BasePassMeshProcessor::clearCommands() cachedPrimitiveIndex = 0; } -BasePass::BasePass(const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source) - : processor(new BasePassMeshProcessor(scene, viewport, graphics, false)) +BasePass::BasePass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source) + : RenderPass(renderGraph) + , processor(new BasePassMeshProcessor(scene, viewport, graphics, false)) , scene(scene) , graphics(graphics) , viewport(viewport) , descriptorSets(4) , source(source->getCameraComponent()) { - Gfx::PRenderTargetAttachment colorAttachment = new Gfx::SwapchainAttachment(viewport->getOwner()); - TextureCreateInfo depthBufferInfo; - depthBufferInfo.width = viewport->getSizeX(); - depthBufferInfo.height = viewport->getSizeY(); - depthBufferInfo.format = Gfx::SE_FORMAT_D32_SFLOAT; - depthBufferInfo.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; - depthBuffer = graphics->createTexture2D(depthBufferInfo); - Gfx::PRenderTargetAttachment depthAttachment = - new Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); - depthAttachment->clear.depthStencil.depth = 1.0f; - Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment); - renderPass = graphics->createRenderPass(layout); - UniformBufferCreateInfo uniformInitializer; - basePassLayout = graphics->createPipelineLayout(); - lightLayout = graphics->createDescriptorLayout(); + lightLayout = graphics->createDescriptorLayout("LightLayout"); lightLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); uniformInitializer.resourceData.size = sizeof(LightEnv); uniformInitializer.resourceData.data = nullptr; uniformInitializer.bDynamic = true; lightUniform = graphics->createUniformBuffer(uniformInitializer); lightLayout->create(); - basePassLayout->addDescriptorLayout(0, lightLayout); - descriptorSets[0] = lightLayout->allocatedDescriptorSet(); + basePassLayout->addDescriptorLayout(INDEX_LIGHT_ENV, lightLayout); + descriptorSets[INDEX_LIGHT_ENV] = lightLayout->allocatedDescriptorSet(); - viewLayout = graphics->createDescriptorLayout(); + viewLayout = graphics->createDescriptorLayout("ViewLayout"); viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); uniformInitializer.resourceData.size = sizeof(ViewParameter); uniformInitializer.resourceData.data = (uint8*)&viewParams; @@ -125,13 +113,13 @@ BasePass::BasePass(const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport v uniformInitializer.bDynamic = true; screenToViewParamBuffer = graphics->createUniformBuffer(uniformInitializer); viewLayout->create(); - basePassLayout->addDescriptorLayout(1, viewLayout); - descriptorSets[1] = viewLayout->allocatedDescriptorSet(); + basePassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout); + descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocatedDescriptorSet(); - primitiveLayout = graphics->createDescriptorLayout(); + primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout"); primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); primitiveLayout->create(); - basePassLayout->addDescriptorLayout(3, primitiveLayout); + basePassLayout->addDescriptorLayout(INDEX_SCENE_DATA, primitiveLayout); } BasePass::~BasePass() @@ -146,8 +134,8 @@ void BasePass::beginFrame() uniformUpdate.size = sizeof(LightEnv); uniformUpdate.data = (uint8*)&scene->getLightEnvironment(); lightUniform->updateContents(uniformUpdate); - descriptorSets[0]->updateBuffer(0, lightUniform); - descriptorSets[0]->writeChanges(); + descriptorSets[INDEX_LIGHT_ENV]->updateBuffer(0, lightUniform); + descriptorSets[INDEX_LIGHT_ENV]->writeChanges(); viewParams.viewMatrix = source->getViewMatrix(); viewParams.projectionMatrix = source->getProjectionMatrix(); @@ -160,9 +148,9 @@ void BasePass::beginFrame() uniformUpdate.size = sizeof(ScreenToViewParameter); uniformUpdate.data = (uint8*)&screenToViewParams; screenToViewParamBuffer->updateContents(uniformUpdate); - descriptorSets[1]->updateBuffer(0, viewParamBuffer); - descriptorSets[1]->updateBuffer(1, screenToViewParamBuffer); - descriptorSets[1]->writeChanges(); + descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer); + descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(1, screenToViewParamBuffer); + descriptorSets[INDEX_VIEW_PARAMS]->writeChanges(); for(auto &&meshBatch : scene->getStaticMeshes()) { meshBatch.material->updateDescriptorData(); @@ -183,3 +171,25 @@ void BasePass::render() void BasePass::endFrame() { } + +void BasePass::publishOutputs() +{ + colorAttachment = new Gfx::SwapchainAttachment(viewport->getOwner()); + renderGraph->registerRenderPassOutput("BASEPASS_COLOR", colorAttachment); +} + +void BasePass::createRenderPass() +{ + Gfx::PRenderTargetAttachment depthAttachment = renderGraph->requestRenderTarget("DEPTHPREPASS_DEPTH"); + depthAttachment->loadOp = Gfx::SE_ATTACHMENT_LOAD_OP_LOAD; + Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(colorAttachment, depthAttachment); + renderPass = graphics->createRenderPass(layout); +} + +void BasePass::modifyRenderPassMacros(Map& defines) +{ + defines["INDEX_LIGHT_ENV"] = "0"; + defines["INDEX_VIEW_PARAMS"] = "1"; + defines["INDEX_MATERIAL"] = "2"; + defines["INDEX_SCENE_DATA"] = "3"; +} diff --git a/src/Engine/Graphics/RenderPass/BasePass.h b/src/Engine/Graphics/RenderPass/BasePass.h index 229cfb0..a342b47 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.h +++ b/src/Engine/Graphics/RenderPass/BasePass.h @@ -1,6 +1,7 @@ #pragma once #include "MinimalEngine.h" #include "MeshProcessor.h" +#include "RenderPass.h" namespace Seele { @@ -30,28 +31,19 @@ private: DEFINE_REF(BasePassMeshProcessor) DECLARE_REF(CameraActor) DECLARE_REF(CameraComponent) -class BasePass +class BasePass : public RenderPass { public: - BasePass(const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source); - ~BasePass(); - void beginFrame(); - void render(); - void endFrame(); + BasePass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source); + virtual ~BasePass(); + virtual void beginFrame() override; + virtual void render() override; + virtual void endFrame() override; + virtual void publishOutputs() override; + virtual void createRenderPass() override; + static void modifyRenderPassMacros(Map& defines); private: - struct ViewParameter - { - Matrix4 viewMatrix; - Matrix4 projectionMatrix; - Vector4 cameraPosition; - } viewParams; - struct ScreenToViewParameter - { - Matrix4 inverseProjectionMatrix; - Vector2 screenDimensions; - } screenToViewParams; - - Gfx::PRenderPass renderPass; + Gfx::PRenderTargetAttachment colorAttachment; Gfx::PTexture2D depthBuffer; UPBasePassMeshProcessor processor; const PScene scene; @@ -61,16 +53,21 @@ private: PCameraComponent source; Gfx::PPipelineLayout basePassLayout; // Set 0: Light environment + static constexpr uint32 INDEX_LIGHT_ENV = 0; Gfx::PDescriptorLayout lightLayout; Gfx::PUniformBuffer lightUniform; // Set 1: viewParameter + static constexpr uint32 INDEX_VIEW_PARAMS = 1; Gfx::PDescriptorLayout viewLayout; Gfx::PUniformBuffer viewParamBuffer; Gfx::PUniformBuffer screenToViewParamBuffer; // Set 2: materials, generated + static constexpr uint32 INDEX_MATERIAL = 2; // Set 3: primitive scene data + static constexpr uint32 INDEX_SCENE_DATA = 3; Gfx::PDescriptorLayout primitiveLayout; Gfx::PUniformBuffer primitiveUniformBuffer; + friend class BasePassMeshProcessor; }; DEFINE_REF(BasePass) } // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/CMakeLists.txt b/src/Engine/Graphics/RenderPass/CMakeLists.txt index 375a2f0..0da5f4a 100644 --- a/src/Engine/Graphics/RenderPass/CMakeLists.txt +++ b/src/Engine/Graphics/RenderPass/CMakeLists.txt @@ -4,5 +4,11 @@ target_sources(SeeleEngine BasePass.cpp DepthPrepass.h DepthPrepass.cpp + LightCullingPass.h + LightCullingPass.cpp MeshProcessor.h - MeshProcessor.cpp) \ No newline at end of file + MeshProcessor.cpp + RenderGraph.h + RenderGraph.cpp + RenderPass.h + RenderPass.cpp) \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp index e69de29..f52fa2b 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.cpp +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.cpp @@ -0,0 +1,185 @@ +#include "DepthPrepass.h" +#include "Graphics/Graphics.h" +#include "Window/Window.h" +#include "Scene/Components/CameraComponent.h" +#include "Scene/Actor/CameraActor.h" +#include "Math/Vector.h" +#include "RenderGraph.h" + +using namespace Seele; + +DepthPrepassMeshProcessor::DepthPrepassMeshProcessor(const PScene scene, Gfx::PViewport viewport, Gfx::PGraphics graphics) + : MeshProcessor(scene, graphics) + , target(viewport) + , cachedPrimitiveIndex(0) +{ +} + +DepthPrepassMeshProcessor::~DepthPrepassMeshProcessor() +{ +} + +void DepthPrepassMeshProcessor::addMeshBatch( + const MeshBatch& batch, +// const PPrimitiveComponent primitiveComponent, + const Gfx::PRenderPass renderPass, + Gfx::PPipelineLayout pipelineLayout, + Gfx::PDescriptorLayout primitiveLayout, + Array& descriptorSets, + int32 /*staticMeshId*/) +{ + const PMaterialAsset material = batch.material; + //const Gfx::MaterialShadingModel shadingModel = material->getShadingModel(); + + const PVertexShaderInput vertexInput = batch.vertexInput; + + const Gfx::ShaderCollection* collection = material->getRenderMaterial()->getShaders(Gfx::RenderPassType::DepthPrepass, vertexInput->getType()); + assert(collection != nullptr); + for(uint32 i = 0; i < batch.elements.size(); ++i) + { + Gfx::PDescriptorSet descriptorSet = primitiveLayout->allocatedDescriptorSet(); + descriptorSet->updateBuffer(0, batch.elements[i].uniformBuffer); + descriptorSet->writeChanges(); + cachedPrimitiveSets.add(descriptorSet); + } + Gfx::PRenderCommand renderCommand = graphics->createRenderCommand(); + renderCommand->setViewport(target); + for(uint32 i = 0; i < batch.elements.size(); ++i) + { + pipelineLayout->addDescriptorLayout(DepthPrepass::INDEX_MATERIAL, material->getRenderMaterial()->getDescriptorLayout()); + pipelineLayout->create(); + descriptorSets[DepthPrepass::INDEX_MATERIAL] = material->getDescriptor(); + descriptorSets[DepthPrepass::INDEX_SCENE_DATA] = cachedPrimitiveSets[cachedPrimitiveIndex++]; + buildMeshDrawCommand(batch, +// primitiveComponent, + renderPass, + pipelineLayout, + renderCommand, + descriptorSets, + collection->vertexShader, + collection->controlShader, + collection->evalutionShader, + collection->geometryShader, + collection->fragmentShader, + true); + } + renderCommands.add(renderCommand); +} + +Array DepthPrepassMeshProcessor::getRenderCommands() +{ + return renderCommands; +} + +void DepthPrepassMeshProcessor::clearCommands() +{ + renderCommands.clear(); + cachedPrimitiveSets.clear(); + cachedPrimitiveIndex = 0; +} + +DepthPrepass::DepthPrepass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source) + : RenderPass(renderGraph) + , processor(new DepthPrepassMeshProcessor(scene, viewport, graphics)) + , scene(scene) + , graphics(graphics) + , viewport(viewport) + , descriptorSets(3) + , source(source->getCameraComponent()) +{ + UniformBufferCreateInfo uniformInitializer; + + depthPrepassLayout = graphics->createPipelineLayout(); + + viewLayout = graphics->createDescriptorLayout("ViewLayout"); + viewLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + uniformInitializer.resourceData.size = sizeof(ViewParameter); + uniformInitializer.resourceData.data = (uint8*)&viewParams; + uniformInitializer.bDynamic = true; + viewParamBuffer = graphics->createUniformBuffer(uniformInitializer); + viewLayout->addDescriptorBinding(1, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + uniformInitializer.resourceData.size = sizeof(ScreenToViewParameter); + uniformInitializer.resourceData.data = (uint8*)&screenToViewParams; + uniformInitializer.bDynamic = true; + screenToViewParamBuffer = graphics->createUniformBuffer(uniformInitializer); + viewLayout->create(); + depthPrepassLayout->addDescriptorLayout(INDEX_VIEW_PARAMS, viewLayout); + descriptorSets[INDEX_VIEW_PARAMS] = viewLayout->allocatedDescriptorSet(); + + primitiveLayout = graphics->createDescriptorLayout("PrimitiveLayout"); + primitiveLayout->addDescriptorBinding(0, Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + primitiveLayout->create(); + depthPrepassLayout->addDescriptorLayout(INDEX_SCENE_DATA, primitiveLayout); +} + +DepthPrepass::~DepthPrepass() +{ +} + +void DepthPrepass::beginFrame() +{ + processor->clearCommands(); + primitiveLayout->reset(); + BulkResourceData uniformUpdate; + + viewParams.viewMatrix = source->getViewMatrix(); + viewParams.projectionMatrix = source->getProjectionMatrix(); + viewParams.cameraPosition = Vector4(source->getCameraPosition(), 0); + screenToViewParams.inverseProjectionMatrix = glm::inverse(viewParams.projectionMatrix); + screenToViewParams.screenDimensions = Vector2(static_cast(viewport->getSizeX()), static_cast(viewport->getSizeY())); + uniformUpdate.size = sizeof(ViewParameter); + uniformUpdate.data = (uint8*)&viewParams; + viewParamBuffer->updateContents(uniformUpdate); + uniformUpdate.size = sizeof(ScreenToViewParameter); + uniformUpdate.data = (uint8*)&screenToViewParams; + screenToViewParamBuffer->updateContents(uniformUpdate); + descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(0, viewParamBuffer); + descriptorSets[INDEX_VIEW_PARAMS]->updateBuffer(1, screenToViewParamBuffer); + descriptorSets[INDEX_VIEW_PARAMS]->writeChanges(); + for(auto &&meshBatch : scene->getStaticMeshes()) + { + meshBatch.material->updateDescriptorData(); + } +} + +void DepthPrepass::render() +{ + graphics->beginRenderPass(renderPass); + for (auto &&meshBatch : scene->getStaticMeshes()) + { + processor->addMeshBatch(meshBatch, renderPass, depthPrepassLayout, primitiveLayout, descriptorSets); + } + graphics->executeCommands(processor->getRenderCommands()); + graphics->endRenderPass(); +} + +void DepthPrepass::endFrame() +{ +} + +void DepthPrepass::publishOutputs() +{ + TextureCreateInfo depthBufferInfo; + depthBufferInfo.width = viewport->getSizeX(); + depthBufferInfo.height = viewport->getSizeY(); + depthBufferInfo.format = Gfx::SE_FORMAT_D32_SFLOAT; + depthBufferInfo.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT; + depthBuffer = graphics->createTexture2D(depthBufferInfo); + depthAttachment = + new Gfx::RenderTargetAttachment(depthBuffer, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR, Gfx::SE_ATTACHMENT_STORE_OP_STORE); + depthAttachment->clear.depthStencil.depth = 1.0f; + renderGraph->registerRenderPassOutput("DEPTHPREPASS_DEPTH", depthAttachment); +} + +void DepthPrepass::createRenderPass() +{ + Gfx::PRenderTargetLayout layout = new Gfx::RenderTargetLayout(depthAttachment); + renderPass = graphics->createRenderPass(layout); +} + +void DepthPrepass::modifyRenderPassMacros(Map& defines) +{ + defines["INDEX_VIEW_PARAMS"] = "0"; + defines["INDEX_MATERIAL"] = "1"; + defines["INDEX_SCENE_DATA"] = "2"; +} diff --git a/src/Engine/Graphics/RenderPass/DepthPrepass.h b/src/Engine/Graphics/RenderPass/DepthPrepass.h index e69de29..75b3f11 100644 --- a/src/Engine/Graphics/RenderPass/DepthPrepass.h +++ b/src/Engine/Graphics/RenderPass/DepthPrepass.h @@ -0,0 +1,68 @@ +#pragma once +#include "MinimalEngine.h" +#include "MeshProcessor.h" +#include "RenderPass.h" + +namespace Seele +{ +class DepthPrepassMeshProcessor : public MeshProcessor +{ +public: + DepthPrepassMeshProcessor(const PScene scene, Gfx::PViewport viewport, Gfx::PGraphics graphics); + virtual ~DepthPrepassMeshProcessor(); + + virtual void addMeshBatch( + const MeshBatch& batch, + const Gfx::PRenderPass renderPass, + Gfx::PPipelineLayout pipelineLayout, + Gfx::PDescriptorLayout primitiveLayout, + Array& descriptorSets, + int32 staticMeshId = -1) override; + + Array getRenderCommands(); + void clearCommands(); +private: + Array renderCommands; + Array cachedPrimitiveSets; + Gfx::PViewport target; + uint32 cachedPrimitiveIndex; +}; +DEFINE_REF(DepthPrepassMeshProcessor) +DECLARE_REF(CameraActor) +DECLARE_REF(CameraComponent) +class DepthPrepass : public RenderPass +{ +public: + DepthPrepass(PRenderGraph renderGraph, const PScene scene, Gfx::PGraphics graphics, Gfx::PViewport viewport, PCameraActor source); + ~DepthPrepass(); + virtual void beginFrame() override; + virtual void render() override; + virtual void endFrame() override; + virtual void publishOutputs() override; + virtual void createRenderPass() override; + static void modifyRenderPassMacros(Map& defines); +private: + Gfx::PRenderTargetAttachment depthAttachment; + Gfx::PTexture2D depthBuffer; + UPDepthPrepassMeshProcessor processor; + const PScene scene; + Gfx::PGraphics graphics; + Gfx::PViewport viewport; + Array descriptorSets; + PCameraComponent source; + Gfx::PPipelineLayout depthPrepassLayout; + // Set 0: viewParameter + static constexpr uint32 INDEX_VIEW_PARAMS = 0; + Gfx::PDescriptorLayout viewLayout; + Gfx::PUniformBuffer viewParamBuffer; + Gfx::PUniformBuffer screenToViewParamBuffer; + // Set 1: materials, generated + static constexpr uint32 INDEX_MATERIAL = 1; + // Set 2: primitive scene data + static constexpr uint32 INDEX_SCENE_DATA = 2; + Gfx::PDescriptorLayout primitiveLayout; + Gfx::PUniformBuffer primitiveUniformBuffer; + friend class DepthPrepassMeshProcessor; +}; +DEFINE_REF(DepthPrepass) +} // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.cpp b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp new file mode 100644 index 0000000..8dabda9 --- /dev/null +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.cpp @@ -0,0 +1,83 @@ +#include "LightCullingPass.h" +#include "Graphics/Graphics.h" +#include "Scene/Actor/CameraActor.h" +#include "Scene/Components/CameraComponent.h" + +using namespace Seele; + +LightCullingPass::LightCullingPass(PRenderGraph renderGraph, Gfx::PViewport viewport, Gfx::PGraphics graphics, PCameraActor camera) + : RenderPass(renderGraph) + , viewport(viewport) + , graphics(graphics) + , source(camera->getCameraComponent()) +{ +} + +LightCullingPass::~LightCullingPass() +{ + +} + +void LightCullingPass::beginFrame() +{ + uint32_t viewportWidth = viewport->getSizeX(); + uint32_t viewportHeight = viewport->getSizeY(); + + glm::uvec3 numThreads = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1)); + glm::uvec3 numThreadGroups = glm::ceil(glm::vec3(numThreads.x / (float)BLOCK_SIZE, numThreads.y / (float)BLOCK_SIZE, 1)); + + dispatchParams.numThreads = numThreads; + dispatchParams.numThreadGroups = numThreadGroups; + ScreenToView screenToView; + screenToView.inverseProjection = glm::inverse(source->getProjectionMatrix()); + screenToView.screenDimensions = glm::vec2(viewportWidth, viewportHeight); + + frustumShader = renderDevice->createComputeShader(loadPlaintext("./_Game/shaders/ComputeFrustums.slang"), "computeFrustums"); + frustumDescriptorLayout = renderDevice->createDescriptorLayout(); + frustumDescriptorLayout->addDescriptorBinding(0, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + frustumDescriptorLayout->addDescriptorBinding(1, VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER); + frustumDescriptorLayout->addDescriptorBinding(2, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER); + frustumLayout = renderDevice->createPipelineLayout(); + frustumLayout->addPushConstants(init::PushConstantRange(VK_SHADER_STAGE_COMPUTE_BIT, sizeof(DispatchParams), 0)); + frustumLayout->addDescriptorLayout(0, frustumDescriptorLayout); + frustumLayout->create(); + frustumShader->setPipelineLayout(frustumLayout); + RHIResourceCreateInfo frustumInfo; + frustumBuffer = renderDevice->createStructuredBuffer(sizeof(Frustum), sizeof(Frustum) * numThreads.x * numThreads.y * numThreads.z, BufferUsageFlags::BUF_UnorderedAccess, frustumInfo); + dispatchParamsBuffer = renderDevice->createUniformBuffer(&dispatchParams, sizeof(DispatchParams), UniformBuffer_MultiFrame); + screenToViewParams = renderDevice->createUniformBuffer(&screenToView, sizeof(ScreenToView), UniformBuffer_MultiFrame); + frustumDescriptorSet = frustumDescriptorLayout->allocateDescriptorSet(); + frustumDescriptorSet->updateBuffer(0, dispatchParamsBuffer); + frustumDescriptorSet->updateBuffer(1, screenToViewParams); + frustumDescriptorSet->updateBuffer(2, frustumBuffer); + frustumDescriptorSet->writeChanges(); + renderDevice->setComputeShader(frustumShader); + renderDevice->bindComputeDescriptors(frustumLayout, frustumDescriptorSet); + renderDevice->dispatchComputeShader(numThreadGroups.x, numThreadGroups.y, numThreadGroups.z); + renderDevice->pipelineBarrier(frustumBuffer, VK_ACCESS_SHADER_WRITE_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_SHADER_READ_BIT, VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT); +} + +void LightCullingPass::render() +{ + +} + +void LightCullingPass::endFrame() +{ + +} + +void LightCullingPass::publishOutputs() +{ + +} + +void LightCullingPass::createRenderPass() +{ + +} + +void LightCullingPass::modifyRenderPassMacros(Map& defines) +{ + +} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/LightCullingPass.h b/src/Engine/Graphics/RenderPass/LightCullingPass.h new file mode 100644 index 0000000..661a1a3 --- /dev/null +++ b/src/Engine/Graphics/RenderPass/LightCullingPass.h @@ -0,0 +1,51 @@ +#pragma once +#include "RenderPass.h" + +namespace Seele +{ +DECLARE_REF(CameraActor) +DECLARE_REF(CameraComponent) +DECLARE_NAME_REF(Gfx, Viewport) +DECLARE_NAME_REF(Gfx, Graphics) +class LightCullingPass : public RenderPass +{ +public: + LightCullingPass(PRenderGraph renderGraph, Gfx::PViewport viewport, Gfx::PGraphics graphics, PCameraActor camera); + virtual ~LightCullingPass(); + virtual void beginFrame() override; + virtual void render() override; + virtual void endFrame() override; + virtual void publishOutputs() override; + virtual void createRenderPass() override; + static void modifyRenderPassMacros(Map& defines); +private: + static constexpr uint32 BLOCK_SIZE = 8; + _declspec(align(16)) struct DispatchParams + { + glm::uvec3 numThreadGroups; + uint32_t pad0; + glm::uvec3 numThreads; + uint32_t pad1; + } dispatchParams; + __declspec(align(16)) struct Plane + { + Vector n; + float d; + Vector p0; + Vector p1; + Vector p2; + }; + __declspec(align(16)) struct Frustum + { + Plane planes[4]; + }; + struct ScreenToView + { + Matrix4 inverseProjection; + Vector2 screenDimensions; + }; + Gfx::PViewport viewport; + Gfx::PGraphics graphics; + PCameraComponent source; +}; +} // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/RenderGraph.cpp b/src/Engine/Graphics/RenderPass/RenderGraph.cpp new file mode 100644 index 0000000..08441f2 --- /dev/null +++ b/src/Engine/Graphics/RenderPass/RenderGraph.cpp @@ -0,0 +1,39 @@ +#include "RenderGraph.h" + +using namespace Seele; + + +RenderGraph::RenderGraph() +{ +} + +RenderGraph::~RenderGraph() +{ +} + +void RenderGraph::setup() +{ + for(auto pass : renderPasses) + { + pass->publishOutputs(); + } + for(auto pass : renderPasses) + { + pass->createRenderPass(); + } +} + +Gfx::PRenderTargetAttachment RenderGraph::requestRenderTarget(const std::string& outputName) +{ + if(registeredAttachments.find(outputName) == registeredAttachments.end()) + { + std::cout << "Attachment " << outputName << " not found" << std::endl; + return nullptr; + } + return registeredAttachments[outputName]; +} + +void RenderGraph::registerRenderPassOutput(const std::string& outputName, Gfx::PRenderTargetAttachment attachment) +{ + registeredAttachments[outputName] = attachment; +} \ No newline at end of file diff --git a/src/Engine/Graphics/RenderPass/RenderGraph.h b/src/Engine/Graphics/RenderPass/RenderGraph.h new file mode 100644 index 0000000..27d3268 --- /dev/null +++ b/src/Engine/Graphics/RenderPass/RenderGraph.h @@ -0,0 +1,21 @@ +#pragma once +#include "MinimalEngine.h" +#include "Graphics/GraphicsResources.h" +#include "RenderPass.h" + +namespace Seele +{ +class RenderGraph +{ +public: + RenderGraph(); + ~RenderGraph(); + void setup(); + Gfx::PRenderTargetAttachment requestRenderTarget(const std::string& outputName); + void registerRenderPassOutput(const std::string& ouputName, Gfx::PRenderTargetAttachment attachment); +private: + Map registeredAttachments; + List renderPasses; +}; +DEFINE_REF(RenderGraph) +} // namespace Seele diff --git a/src/Engine/Graphics/RenderPass/RenderPass.cpp b/src/Engine/Graphics/RenderPass/RenderPass.cpp new file mode 100644 index 0000000..71fb066 --- /dev/null +++ b/src/Engine/Graphics/RenderPass/RenderPass.cpp @@ -0,0 +1,13 @@ +#include "RenderPass.h" + +using namespace Seele; + +RenderPass::RenderPass(PRenderGraph renderGraph) + : renderGraph(renderGraph) +{ +} + +RenderPass::~RenderPass() +{ +} + diff --git a/src/Engine/Graphics/RenderPass/RenderPass.h b/src/Engine/Graphics/RenderPass/RenderPass.h new file mode 100644 index 0000000..75f3263 --- /dev/null +++ b/src/Engine/Graphics/RenderPass/RenderPass.h @@ -0,0 +1,35 @@ +#pragma once +#include "MinimalEngine.h" +#include "Math/Math.h" + +namespace Seele +{ +DECLARE_NAME_REF(Gfx, RenderPass) +DECLARE_REF(RenderGraph) +class RenderPass +{ +public: + RenderPass(PRenderGraph rendergraph); + virtual ~RenderPass(); + virtual void beginFrame() = 0; + virtual void render() = 0; + virtual void endFrame() = 0; + virtual void publishOutputs() = 0; + virtual void createRenderPass() = 0; +protected: + struct ViewParameter + { + Matrix4 viewMatrix; + Matrix4 projectionMatrix; + Vector4 cameraPosition; + } viewParams; + struct ScreenToViewParameter + { + Matrix4 inverseProjectionMatrix; + Vector2 screenDimensions; + } screenToViewParams; + Gfx::PRenderPass renderPass; + PRenderGraph renderGraph; +}; +DEFINE_REF(RenderPass) +} // namespace Seele diff --git a/src/Engine/Graphics/StaticMeshVertexInput.cpp b/src/Engine/Graphics/StaticMeshVertexInput.cpp index 348d210..4958c9b 100644 --- a/src/Engine/Graphics/StaticMeshVertexInput.cpp +++ b/src/Engine/Graphics/StaticMeshVertexInput.cpp @@ -30,8 +30,8 @@ void StaticMeshVertexInput::init(Gfx::PGraphics graphics) elements.add(accessStreamComponent(data.positionStream, 0)); } - uint8 tangentBasisAttributes[2] = {1, 2}; - for(int32 axisIndex = 0; axisIndex < 2; axisIndex++) + uint8 tangentBasisAttributes[3] = {1, 2, 3}; + for(int32 axisIndex = 0; axisIndex < 3; axisIndex++) { if(data.tangentBasisComponents[axisIndex].vertexBuffer != nullptr) { @@ -41,15 +41,15 @@ void StaticMeshVertexInput::init(Gfx::PGraphics graphics) if(data.colorComponent.vertexBuffer != nullptr) { - elements.add(accessStreamComponent(data.colorComponent, 3)); + elements.add(accessStreamComponent(data.colorComponent, 4)); } else { - elements.add(accessStreamComponent(VertexStreamComponent(graphics->getNullVertexBuffer(), 0, 0, Gfx::SE_FORMAT_R32G32B32A32_SFLOAT), 3)); + elements.add(accessStreamComponent(VertexStreamComponent(graphics->getNullVertexBuffer(), 0, 0, Gfx::SE_FORMAT_R32G32B32A32_SFLOAT), 4)); } if(data.textureCoordinates.size()) { - const int32 baseTexCoordAttribute = 4; + const int32 baseTexCoordAttribute = 5; for(uint32 coordinateIndex = 0; coordinateIndex < data.textureCoordinates.size(); ++coordinateIndex) { elements.add(accessStreamComponent( diff --git a/src/Engine/Graphics/StaticMeshVertexInput.h b/src/Engine/Graphics/StaticMeshVertexInput.h index 6a85edc..bec9aa3 100644 --- a/src/Engine/Graphics/StaticMeshVertexInput.h +++ b/src/Engine/Graphics/StaticMeshVertexInput.h @@ -7,7 +7,7 @@ enum { MAX_TEXCOORDS = 4 }; struct StaticMeshDataType { VertexStreamComponent positionStream; - VertexStreamComponent tangentBasisComponents[2]; + VertexStreamComponent tangentBasisComponents[3]; //Dont forget these are 4 component vectors Array textureCoordinates; diff --git a/src/Engine/Graphics/VertexShaderInput.cpp b/src/Engine/Graphics/VertexShaderInput.cpp index 7d8dbb7..0bd1584 100644 --- a/src/Engine/Graphics/VertexShaderInput.cpp +++ b/src/Engine/Graphics/VertexShaderInput.cpp @@ -101,7 +101,7 @@ Gfx::VertexElement VertexShaderInput::accessPositionStreamComponent(const Vertex vertexStream.stride = component.stride; vertexStream.offset = component.offset; - return Gfx::VertexElement((uint8)streams.indexOf(streams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride); + return Gfx::VertexElement((uint8)positionStreams.indexOf(positionStreams.addUnique(vertexStream)), component.offset, component.type, attributeIndex, vertexStream.stride); } void VertexShaderInput::initDeclaration(Gfx::PGraphics graphics, Array& elements) diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp index 2bad8c1..5fcf94f 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.cpp @@ -8,8 +8,9 @@ using namespace Seele; using namespace Seele::Vulkan; -DescriptorLayout::DescriptorLayout(PGraphics graphics) - : graphics(graphics) +DescriptorLayout::DescriptorLayout(PGraphics graphics, const std::string& name) + : Gfx::DescriptorLayout(name) + , graphics(graphics) , layoutHandle(VK_NULL_HANDLE) { } @@ -67,6 +68,7 @@ void PipelineLayout::create() // There could be unused descriptor set indices if(descriptorSetLayouts[i] == nullptr) { + vulkanDescriptorLayouts[i] = VK_NULL_HANDLE; continue; } PDescriptorLayout layout = descriptorSetLayouts[i].cast(); @@ -81,7 +83,7 @@ void PipelineLayout::create() { vkPushConstants[i].offset = pushConstants[i].offset; vkPushConstants[i].size = pushConstants[i].size; - vkPushConstants[i].stageFlags = cast((VkShaderStageFlagBits)pushConstants[i].stageFlags); + vkPushConstants[i].stageFlags = (VkShaderStageFlagBits)pushConstants[i].stageFlags; } createInfo.pushConstantRangeCount = (uint32)vkPushConstants.size(); createInfo.pPushConstantRanges = vkPushConstants.data(); diff --git a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h index 4abd2ce..1a265d2 100644 --- a/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h +++ b/src/Engine/Graphics/Vulkan/VulkanDescriptorSets.h @@ -9,7 +9,7 @@ DECLARE_REF(Graphics) class DescriptorLayout : public Gfx::DescriptorLayout { public: - DescriptorLayout(PGraphics graphics); + DescriptorLayout(PGraphics graphics, const std::string& name); virtual ~DescriptorLayout(); virtual void create(); inline VkDescriptorSetLayout getHandle() const @@ -22,6 +22,7 @@ private: PGraphics graphics; Array bindings; VkDescriptorSetLayout layoutHandle; + std::string name; friend class DescriptorAllocator; }; DEFINE_REF(DescriptorLayout) diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp index d44d847..843ed98 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.cpp @@ -164,6 +164,12 @@ Gfx::PGraphicsPipeline Graphics::createGraphicsPipeline(const GraphicsPipelineCr return pipeline; } +Gfx::PComputePipeline Graphics::createComputePipeline(const ComputePipelineCreateInfo& createInfo) +{ + PComputePipeline pipeline = pipelineCache->createPipeline(createInfo); + return pipeline; +} + Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo&) { PSamplerState sampler = new SamplerState(); // TODO: proper sampler creation @@ -172,9 +178,9 @@ Gfx::PSamplerState Graphics::createSamplerState(const SamplerCreateInfo&) VK_CHECK(vkCreateSampler(handle, &vkInfo, nullptr, &sampler->sampler)); return sampler; } -Gfx::PDescriptorLayout Graphics::createDescriptorLayout() +Gfx::PDescriptorLayout Graphics::createDescriptorLayout(const std::string& name) { - PDescriptorLayout layout = new DescriptorLayout(this); + PDescriptorLayout layout = new DescriptorLayout(this, name); return layout; } Gfx::PPipelineLayout Graphics::createPipelineLayout() diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphics.h b/src/Engine/Graphics/Vulkan/VulkanGraphics.h index f743e80..7a3ab27 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphics.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphics.h @@ -60,9 +60,10 @@ public: virtual Gfx::PGeometryShader createGeometryShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PFragmentShader createFragmentShader(const ShaderCreateInfo& createInfo) override; virtual Gfx::PGraphicsPipeline createGraphicsPipeline(const GraphicsPipelineCreateInfo& createInfo) override; + virtual Gfx::PComputePipeline createComputePipeline(const ComputePipelineCreateInfo& createInfo) override; virtual Gfx::PSamplerState createSamplerState(const SamplerCreateInfo& createInfo) override; - virtual Gfx::PDescriptorLayout createDescriptorLayout() override; + virtual Gfx::PDescriptorLayout createDescriptorLayout(const std::string& name = "") override; virtual Gfx::PPipelineLayout createPipelineLayout() override; protected: diff --git a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h index 8cfa8ca..535de4a 100644 --- a/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h +++ b/src/Engine/Graphics/Vulkan/VulkanGraphicsResources.h @@ -319,7 +319,7 @@ public: virtual ~Window(); virtual void beginFrame() override; virtual void endFrame() override; - virtual Gfx::PTexture2D getBackBuffer() override; + virtual Gfx::PTexture2D getBackBuffer() const override; virtual void onWindowCloseEvent() override; virtual void setKeyCallback(std::function callback) override; virtual void setMouseMoveCallback(std::function callback) override; diff --git a/src/Engine/Graphics/Vulkan/VulkanPipeline.cpp b/src/Engine/Graphics/Vulkan/VulkanPipeline.cpp index f715867..09ec5fb 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipeline.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanPipeline.cpp @@ -24,4 +24,26 @@ void GraphicsPipeline::bind(VkCommandBuffer handle) VkPipelineLayout GraphicsPipeline::getLayout() const { return layout.cast()->getHandle(); +} + +ComputePipeline::ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo) + : Gfx::ComputePipeline(createInfo, pipelineLayout) + , graphics(graphics) + , pipeline(handle) +{ + +} + +ComputePipeline::~ComputePipeline() +{ +} + +void ComputePipeline::bind(VkCommandBuffer handle) +{ + vkCmdBindPipeline(handle, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); +} + +VkPipelineLayout ComputePipeline::getLayout() const +{ + return layout.cast()->getHandle(); } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanPipeline.h b/src/Engine/Graphics/Vulkan/VulkanPipeline.h index fc43d52..4a06988 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipeline.h +++ b/src/Engine/Graphics/Vulkan/VulkanPipeline.h @@ -19,5 +19,17 @@ private: VkPipeline pipeline; }; DEFINE_REF(GraphicsPipeline) +class ComputePipeline : public Gfx::ComputePipeline +{ +public: + ComputePipeline(PGraphics graphics, VkPipeline handle, PPipelineLayout pipelineLayout, const ComputePipelineCreateInfo& createInfo); + virtual ~ComputePipeline(); + void bind(VkCommandBuffer handle); + VkPipelineLayout getLayout() const; +private: + PGraphics graphics; + VkPipeline pipeline; +}; +DEFINE_REF(ComputePipeline) } // namespace Vulkan } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp index ff71ade..9ecb70c 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.cpp @@ -352,4 +352,25 @@ PGraphicsPipeline PipelineCache::createPipeline(const GraphicsPipelineCreateInfo PGraphicsPipeline result = new GraphicsPipeline(graphics, pipelineHandle, layout, gfxInfo); return result; +} + +PComputePipeline PipelineCache::createPipeline(const ComputePipelineCreateInfo& computeInfo) +{ + VkComputePipelineCreateInfo createInfo; + createInfo.sType = VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO; + createInfo.pNext = 0; + createInfo.flags = 0; + createInfo.basePipelineIndex = 0; + createInfo.basePipelineHandle = VK_NULL_HANDLE; + auto layout = computeInfo.pipelineLayout.cast(); + createInfo.layout = layout->getHandle(); + auto computeStage = computeInfo.computeShader.cast(); + createInfo.stage = init::PipelineShaderStageCreateInfo( + VK_SHADER_STAGE_COMPUTE_BIT, + computeStage->getModuleHandle(), + computeStage->getEntryPointName()); + VkPipeline pipelineHandle; + VK_CHECK(vkCreateComputePipelines(graphics->getDevice(), cache, 1, &createInfo, nullptr, &pipelineHandle)); + PComputePipeline result = new ComputePipeline(graphics, pipelineHandle, layout, computeInfo); + return result; } \ No newline at end of file diff --git a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h index e5a3105..e156360 100644 --- a/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h +++ b/src/Engine/Graphics/Vulkan/VulkanPipelineCache.h @@ -11,6 +11,7 @@ public: PipelineCache(PGraphics graphics, const std::string& cacheFilePath); ~PipelineCache(); PGraphicsPipeline createPipeline(const GraphicsPipelineCreateInfo& createInfo); + PComputePipeline createPipeline(const ComputePipelineCreateInfo& createInfo); private: VkPipelineCache cache; PGraphics graphics; diff --git a/src/Engine/Graphics/Vulkan/VulkanShader.cpp b/src/Engine/Graphics/Vulkan/VulkanShader.cpp index 12f8f9e..cf3ab4a 100644 --- a/src/Engine/Graphics/Vulkan/VulkanShader.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanShader.cpp @@ -118,9 +118,9 @@ void Shader::create(const ShaderCreateInfo& createInfo) if(spCompile(request)) { char const* diagnostics = spGetDiagnosticOutput(request); + std::cout << "Compile error for shader " << createInfo.name << std::endl; std::cout << diagnostics << std::endl; } - size_t dataSize = 0; const uint32* data = reinterpret_cast(spGetEntryPointCode(request, entryPointIndex, &dataSize)); diff --git a/src/Engine/Graphics/Vulkan/VulkanViewport.cpp b/src/Engine/Graphics/Vulkan/VulkanViewport.cpp index 835de55..f3b5f4e 100644 --- a/src/Engine/Graphics/Vulkan/VulkanViewport.cpp +++ b/src/Engine/Graphics/Vulkan/VulkanViewport.cpp @@ -104,7 +104,7 @@ void Window::onWindowCloseEvent() { } -Gfx::PTexture2D Window::getBackBuffer() +Gfx::PTexture2D Window::getBackBuffer() const { return backBufferImages[currentImageIndex]; } diff --git a/src/Engine/Material/BRDF.cpp b/src/Engine/Material/BRDF.cpp index b5c8426..6372e60 100644 --- a/src/Engine/Material/BRDF.cpp +++ b/src/Engine/Material/BRDF.cpp @@ -66,7 +66,7 @@ void BlinnPhong::generateMaterialCode(std::ofstream& codeStream, json codeJson) }; accessorStream << "float3 getBaseColor(MaterialFragmentParameter input) {\n"; - generateAccessor(accessorStream, "baseColor", "float3(0, 0, 0)"); + generateAccessor(accessorStream, "baseColor", "float3(0.5f, 0.5f, 0.5f)"); accessorStream << "}"; accessorStream << "float getMetallic(MaterialFragmentParameter input) {\n"; @@ -121,7 +121,7 @@ void BlinnPhong::generateMaterialCode(std::ofstream& codeStream, json codeJson) codeStream << name << " result;" << std::endl; codeStream << "result.baseColor = getBaseColor(geometry);" << std::endl; codeStream << "result.metallic = getMetallic(geometry);" << std::endl; - codeStream << "result.normal = geometry.transformNormalTexture(getNormal(geometry));" << std::endl; + codeStream << "result.normal = getNormal(geometry);" << std::endl; codeStream << "result.specular = getSpecular(geometry);" << std::endl; codeStream << "result.roughness = getRoughness(geometry);" << std::endl; codeStream << "result.sheen = getSheen(geometry);" << std::endl; diff --git a/src/Engine/Material/Material.cpp b/src/Engine/Material/Material.cpp index 0229d13..581004c 100644 --- a/src/Engine/Material/Material.cpp +++ b/src/Engine/Material/Material.cpp @@ -43,11 +43,11 @@ void Material::load() void Material::compile() { setStatus(Status::Loading); - layout = WindowManager::getGraphics()->createDescriptorLayout(); auto& stream = getReadStream(); json j; stream >> j; materialName = j["name"].get(); + layout = WindowManager::getGraphics()->createDescriptorLayout(materialName + "Layout"); //Shader file needs to conform to the slang standard, which prohibits _ materialName.erase(std::remove(materialName.begin(), materialName.end(), '_'), materialName.end()); std::ofstream codeStream("./shaders/generated/"+materialName+".slang"); diff --git a/src/Engine/Scene/Actor/Actor.cpp b/src/Engine/Scene/Actor/Actor.cpp index 4ba2f06..ac84b84 100644 --- a/src/Engine/Scene/Actor/Actor.cpp +++ b/src/Engine/Scene/Actor/Actor.cpp @@ -14,16 +14,17 @@ Actor::~Actor() } void Actor::tick(float deltaTime) { - rootComponent->tick(deltaTime); - for(auto child : children) - { - child->tick(deltaTime); - } + addWorldRotation(glm::vec3(0, 1 * deltaTime, 0)); } void Actor::notifySceneAttach(PScene scene) { owningScene = scene; + scene->getSceneUpdater()->registerActorUpdate(this); rootComponent->notifySceneAttach(scene); + for(auto child : children) + { + child->notifySceneAttach(scene); + } } PScene Actor::getScene() diff --git a/src/Engine/Scene/Components/Component.cpp b/src/Engine/Scene/Components/Component.cpp index acd4c71..11f0f13 100644 --- a/src/Engine/Scene/Components/Component.cpp +++ b/src/Engine/Scene/Components/Component.cpp @@ -15,10 +15,6 @@ Component::~Component() } void Component::tick(float deltaTime) { - for (auto child : children) - { - child->tick(deltaTime); - } } PComponent Component::getParent() { @@ -40,6 +36,7 @@ PActor Component::getOwner() void Component::notifySceneAttach(PScene scene) { owningScene = scene; + scene->getSceneUpdater()->registerComponentUpdate(this); for (auto child : children) { child->notifySceneAttach(scene); diff --git a/src/Engine/Scene/Scene.cpp b/src/Engine/Scene/Scene.cpp index b134e81..d29492b 100644 --- a/src/Engine/Scene/Scene.cpp +++ b/src/Engine/Scene/Scene.cpp @@ -7,15 +7,26 @@ using namespace Seele; +inline float frand() +{ + return (float)rand()/RAND_MAX; +} + Scene::Scene(Gfx::PGraphics graphics) : graphics(graphics) + , updater(new SceneUpdater()) { - lightEnv.directionalLights[0].color = Vector4(1, 0, 0, 1); - lightEnv.directionalLights[0].direction = Vector4(0, 0, 0, 1); + lightEnv.directionalLights[0].color = Vector4(1, 1, 1, 1); + lightEnv.directionalLights[0].direction = Vector4(1, 0, 0, 1); lightEnv.directionalLights[0].intensity = Vector4(1, 1, 1, 1); lightEnv.numDirectionalLights = 1; - lightEnv.numPointLights = 0; srand((unsigned int)time(NULL)); + for(uint32 i = 0; i < MAX_POINT_LIGHTS; ++i) + { + lightEnv.pointLights[i].colorRange = Vector4(frand(), frand(), frand(), frand() * 30); + lightEnv.pointLights[i].positionWS = Vector4(frand() * 200-100, frand(), frand() * 200-100, 1); + } + lightEnv.numPointLights = MAX_POINT_LIGHTS; } Scene::~Scene() @@ -24,14 +35,7 @@ Scene::~Scene() void Scene::tick(double deltaTime) { - lightEnv.directionalLights[0].direction.x += ((rand() / (double)RAND_MAX) - 0.5f) * 100.f * deltaTime; - lightEnv.directionalLights[0].direction.y += ((rand() / (double)RAND_MAX) - 0.5f) * 100.f * deltaTime; - lightEnv.directionalLights[0].direction.z += ((rand() / (double)RAND_MAX) - 0.5f) * 100.f * deltaTime; - std::cout << lightEnv.directionalLights[0].direction << std::endl; - for (auto actor : rootActors) - { - actor->tick(static_cast(deltaTime)); - } + updater->runUpdates(static_cast(deltaTime)); } void Scene::addActor(PActor actor) diff --git a/src/Engine/Scene/Scene.h b/src/Engine/Scene/Scene.h index ea8e8de..498fdfc 100644 --- a/src/Engine/Scene/Scene.h +++ b/src/Engine/Scene/Scene.h @@ -5,6 +5,7 @@ #include "Components/PrimitiveComponent.h" #include "Graphics/MeshBatch.h" #include "Material/Material.h" +#include "SceneUpdater.h" namespace Seele { @@ -46,11 +47,13 @@ public: const Array& getPrimitives() const { return primitives; } const Array& getStaticMeshes() const { return staticMeshes; } const LightEnv& getLightEnvironment() const { return lightEnv; } + UPSceneUpdater& getSceneUpdater() { return updater; } private: Array staticMeshes; Array rootActors; Array primitives; LightEnv lightEnv; Gfx::PGraphics graphics; + UPSceneUpdater updater; }; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/Scene/SceneUpdater.cpp b/src/Engine/Scene/SceneUpdater.cpp index e69de29..a5f0879 100644 --- a/src/Engine/Scene/SceneUpdater.cpp +++ b/src/Engine/Scene/SceneUpdater.cpp @@ -0,0 +1,75 @@ +#include "SceneUpdater.h" +#include "Components/Component.h" +#include "Actor/Actor.h" + +using namespace Seele; + +SceneUpdater::SceneUpdater() + : pendingUpdatesSem(0) +{ + running.store(true); + workers.resize(std::thread::hardware_concurrency()); + for (size_t i = 0; i < workers.size(); i++) + { + workers[i] = std::thread(&SceneUpdater::work, this); + } +} + +SceneUpdater::~SceneUpdater() +{ + running.store(false); + for (size_t i = 0; i < workers.size(); i++) + { + workers[i].join(); + } +} + +void SceneUpdater::registerComponentUpdate(PComponent component) +{ + std::unique_lock lck(pendingUpdatesLock); + updatesRan.add([component](float delta) mutable { component->tick(delta); }); +} + +void SceneUpdater::registerActorUpdate(PActor actor) +{ + std::unique_lock lck(pendingUpdatesLock); + updatesRan.add([actor](float delta) mutable { actor->tick(delta); }); +} + +void SceneUpdater::runUpdates(float delta) +{ + + std::unique_lock pendingLock(pendingUpdatesLock); + frameDelta = delta; + pendingUpdates = std::move(updatesRan); + updatesRan = List>(); + + std::unique_lock lck(frameFinishedLock); + pendingLock.unlock(); + pendingUpdatesSem.release(pendingUpdates.size()); + frameFinishedCV.wait(lck); +} + +void SceneUpdater::work() +{ + while(running.load()) + { + pendingUpdatesSem.acquire(); + std::function function; + { + std::unique_lock lck(pendingUpdatesLock); + function = std::move(pendingUpdates.front()); + pendingUpdates.popFront(); + if(pendingUpdates.empty()) + { + std::unique_lock lck(frameFinishedLock); + frameFinishedCV.notify_all(); + } + } + function(frameDelta); + { + std::unique_lock lck(pendingUpdatesLock); + updatesRan.add(std::move(function)); + } + } +} diff --git a/src/Engine/Scene/SceneUpdater.h b/src/Engine/Scene/SceneUpdater.h index 4a27880..a1034ea 100644 --- a/src/Engine/Scene/SceneUpdater.h +++ b/src/Engine/Scene/SceneUpdater.h @@ -1,16 +1,30 @@ #pragma once -#include "Containers/Array.h" +#include "Containers/List.h" +#include namespace Seele { +DECLARE_REF(Component); +DECLARE_REF(Actor); class SceneUpdater { public: SceneUpdater(); ~SceneUpdater(); + void registerComponentUpdate(PComponent component); + void registerActorUpdate(PActor actor); + void runUpdates(float delta); private: Array workers; - List pendingUpdates; + std::mutex pendingUpdatesLock; + std::counting_semaphore<> pendingUpdatesSem; + List> pendingUpdates; + List> updatesRan; void work(); + float frameDelta; + std::atomic_bool running; + std::mutex frameFinishedLock; + std::condition_variable frameFinishedCV; }; +DEFINE_REF(SceneUpdater) } // namespace Seele diff --git a/src/Engine/Window/SceneRenderPath.cpp b/src/Engine/Window/SceneRenderPath.cpp index d37d5c8..c1c4c30 100644 --- a/src/Engine/Window/SceneRenderPath.cpp +++ b/src/Engine/Window/SceneRenderPath.cpp @@ -2,6 +2,7 @@ #include "Scene/Scene.h" #include "Material/Material.h" #include "Asset/AssetRegistry.h" +#include "Graphics/RenderPass/RenderGraph.h" using namespace Seele; @@ -9,7 +10,10 @@ SceneRenderPath::SceneRenderPath(PScene scene, Gfx::PGraphics graphics, Gfx::PVi : RenderPath(graphics, target) , scene(scene) { - basePass = new BasePass(scene, graphics, target, source); + renderGraph = new RenderGraph(); + depthPrepass = new DepthPrepass(renderGraph, scene, graphics, target, source); + basePass = new BasePass(renderGraph, scene, graphics, target, source); + renderGraph->setup(); } SceneRenderPath::~SceneRenderPath() @@ -28,15 +32,15 @@ void SceneRenderPath::init() void SceneRenderPath::beginFrame() { - basePass->beginFrame(); + depthPrepass->beginFrame(); } void SceneRenderPath::render() { - basePass->render(); + depthPrepass->render(); } void SceneRenderPath::endFrame() { - basePass->endFrame(); + depthPrepass->endFrame(); } diff --git a/src/Engine/Window/SceneRenderPath.h b/src/Engine/Window/SceneRenderPath.h index 82eb549..ac3d9fb 100644 --- a/src/Engine/Window/SceneRenderPath.h +++ b/src/Engine/Window/SceneRenderPath.h @@ -1,6 +1,7 @@ #pragma once #include "RenderPath.h" #include "Graphics/RenderPass/BasePass.h" +#include "Graphics/RenderPass/DepthPrepass.h" namespace Seele { @@ -19,6 +20,9 @@ public: protected: PScene scene; - UPBasePass basePass; + PRenderGraph renderGraph; + PDepthPrepass depthPrepass; + PBasePass basePass; + }; } // namespace Seele \ No newline at end of file diff --git a/src/Engine/main.cpp b/src/Engine/main.cpp index f2da2e4..2a951ce 100644 --- a/src/Engine/main.cpp +++ b/src/Engine/main.cpp @@ -27,10 +27,16 @@ int main() window->addView(sceneView); sceneView->setFocused(); AssetRegistry::init("D:\\Private\\Programming\\C++\\TestSeeleProject\\"); - AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Arissa\\Arissa.fbx"); - PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Arissa")); + AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Ely\\Ely.fbx"); + AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Cube\\cube.obj"); + AssetRegistry::importFile("D:\\Private\\Programming\\Unreal Engine\\Assets\\Plane\\plane.obj"); + PPrimitiveComponent plane = new PrimitiveComponent(AssetRegistry::findMesh("plane")); + plane->setWorldScale(Vector(100, 100, 100)); + plane->addWorldTranslation(Vector(0, -10, 0)); + PPrimitiveComponent arissa = new PrimitiveComponent(AssetRegistry::findMesh("Ely")); arissa->addWorldTranslation(Vector(0, 0, 100)); arissa->setWorldScale(Vector(0.1f, 0.1f, 0.1f)); + sceneView->getScene()->addPrimitiveComponent(plane); sceneView->getScene()->addPrimitiveComponent(arissa); core.renderLoop(); core.shutdown();