From 75e9bc899c93d56286359f5d9d058a9098f83860 Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Wed, 17 Jul 2024 09:33:37 +0200 Subject: [PATCH] Fixing transparency --- res/shaders/DrawListTask.slang | 2 + src/Editor/Asset/MeshLoader.cpp | 78 ++++++++++++++++----- src/Engine/Graphics/Graphics.h | 3 +- src/Engine/Graphics/RenderPass/BasePass.cpp | 21 +++--- src/Engine/Graphics/VertexData.cpp | 43 ++---------- src/Engine/Graphics/VertexData.h | 5 -- src/Engine/Graphics/Vulkan/Graphics.cpp | 4 +- src/Engine/Graphics/Vulkan/Graphics.h | 2 +- src/Engine/Graphics/Vulkan/RenderPass.cpp | 11 ++- src/Engine/Graphics/Vulkan/RenderPass.h | 3 +- src/Engine/Window/GameView.cpp | 12 ++-- 11 files changed, 101 insertions(+), 83 deletions(-) diff --git a/res/shaders/DrawListTask.slang b/res/shaders/DrawListTask.slang index f3b10d6..a9ea9a9 100644 --- a/res/shaders/DrawListTask.slang +++ b/res/shaders/DrawListTask.slang @@ -26,7 +26,9 @@ void taskMain( uint cull = p.cullingOffset + i; MeshletDescription meshlet = pScene.meshletInfos[m]; MeshletCullingInfo culling = pScene.cullingInfos[cull]; +#ifdef DEPTH_CULLING if(culling.wasVisible()) +#endif { uint index; InterlockedAdd(head, 1, index); diff --git a/src/Editor/Asset/MeshLoader.cpp b/src/Editor/Asset/MeshLoader.cpp index 6c76f34..4e8c1da 100644 --- a/src/Editor/Asset/MeshLoader.cpp +++ b/src/Editor/Asset/MeshLoader.cpp @@ -80,7 +80,7 @@ void MeshLoader::loadTextures(const aiScene* scene, const std::filesystem::path& } } -constexpr const char* KEY_BASE_COLOR = "k_b"; +constexpr const char* KEY_ALPHA = "k_alpha"; constexpr const char* KEY_DIFFUSE_COLOR = "k_d"; constexpr const char* KEY_SPECULAR_COLOR = "k_s"; constexpr const char* KEY_AMBIENT_COLOR = "k_a"; @@ -137,7 +137,7 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array& }; auto addTextureParameter = [&](std::string paramKey, aiTextureType type, int index, std::string& result, - StaticArray extractMask = {0, 1, 2, -1}) { + StaticArray extractMask = {0, 1, 2, -1}, std::string* alpha = nullptr) { aiString texPath; aiTextureMapping mapping; uint32 uvIndex = 0; @@ -218,7 +218,21 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array& expressions.add(new SwizzleExpression(extractMask)); expressions.back()->key = colorExtract; expressions.back()->inputs["target"].source = sampleKey; - // TODO: extract alpha, set opacity + + if (alpha != nullptr) + { + std::string alphaExtract = fmt::format("{0}Alpha{1}", paramKey, index); + expressions.add(new SwizzleExpression({3, -1, -1, -1})); + expressions.back()->key = alphaExtract; + expressions.back()->inputs["target"].source = sampleKey; + + //std::string alphaMul = fmt::format("{0}AlphaMul{1}", paramKey, index); + //expressions.add(new MulExpression()); + //expressions.back()->key = alphaMul; + //expressions.back()->inputs["lhs"].source = *alpha; + //expressions.back()->inputs["rhs"].source = alphaExtract; + *alpha = alphaExtract; + } if (blend == std::numeric_limits::max()) { result = colorExtract; @@ -273,22 +287,14 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array& }; // Diffuse addVectorParameter(KEY_DIFFUSE_COLOR, AI_MATKEY_COLOR_DIFFUSE); - std::string outputBase = KEY_BASE_COLOR; + std::string outputDiffuse = KEY_DIFFUSE_COLOR; + addScalarParameter(KEY_ALPHA, AI_MATKEY_OPACITY); + std::string outputAlpha = KEY_ALPHA; uint32 numDiffuseTextures = material->GetTextureCount(aiTextureType_DIFFUSE); for (uint32 i = 0; i < numDiffuseTextures; ++i) { - addTextureParameter(KEY_DIFFUSE_TEXTURE, aiTextureType_DIFFUSE, i, outputBase, {0, 1, 2, 3}); + addTextureParameter(KEY_DIFFUSE_TEXTURE, aiTextureType_DIFFUSE, i, outputDiffuse, {0, 1, 2, -1}, &outputAlpha); } - std::string outputDiffuse = KEY_DIFFUSE_COLOR; - expressions.add(new SwizzleExpression({0, 1, 2, -1})); - expressions.back()->key = outputDiffuse; - expressions.back()->inputs["target"].source = outputBase; - - std::string outputAlpha = "alpha"; - expressions.add(new SwizzleExpression({-1, -1, -1, 0})); - expressions.back()->key = outputDiffuse; - expressions.back()->inputs["target"].source = outputBase; - // Specular addVectorParameter(KEY_SPECULAR_COLOR, AI_MATKEY_COLOR_SPECULAR); std::string outputSpecular = KEY_SPECULAR_COLOR; @@ -387,8 +393,48 @@ void MeshLoader::loadMaterials(const aiScene* scene, const Array& } break; }; + uint32 twoSided = false; + float opacity = 1.0f; + const char* mat = material->GetName().C_Str(); + + if (strcmp(mat, "Leaves0119_14_S") == 0) { + opacity = 0.5f; + twoSided = true; + } + if (strcmp(mat, "TexturesCom_Leaves0119_1_alphamasked_S") == 0) { + opacity = 0.5f; + twoSided = true; + } + if (strcmp(mat, "TexturesCom_Leaves0119_2_alphamasked_S") == 0) { + opacity = 0.5f; + twoSided = true; + } + if (strcmp(mat, "3td_Africa_Grass01") == 0) { + opacity = 0.5f; + twoSided = true; + } + if (strcmp(mat, "DryWeeds-CC0") == 0) { + opacity = 0.5f; + twoSided = true; + } + if (strcmp(mat, "fgrass1_v2_256") == 0) { + opacity = 0.5f; + twoSided = true; + } + if (strcmp(mat, "arbre-feuille") == 0) { + opacity = 0.5f; + twoSided = true; + } + if (strcmp(mat, "arbre-feuille-variante") == 0) { + opacity = 0.5f; + twoSided = true; + } + if (strcmp(mat, "arbre-feuille-variante2") == 0) { + opacity = 0.5f; + twoSided = true; + } OMaterialAsset baseMat = new MaterialAsset(importPath, materialName); - baseMat->material = new Material(graphics, numTextures, numSamplers, numFloats, 1, 1, materialName, + baseMat->material = new Material(graphics, numTextures, numSamplers, numFloats, twoSided, opacity, materialName, std::move(expressions), std::move(parameters), std::move(brdf)); baseMat->material->compile(); graphics->getShaderCompiler()->registerMaterial(baseMat->material); diff --git a/src/Engine/Graphics/Graphics.h b/src/Engine/Graphics/Graphics.h index 8833f43..63b7a0f 100644 --- a/src/Engine/Graphics/Graphics.h +++ b/src/Engine/Graphics/Graphics.h @@ -55,7 +55,8 @@ class Graphics { virtual OWindow createWindow(const WindowCreateInfo& createInfo) = 0; virtual OViewport createViewport(PWindow owner, const ViewportCreateInfo& createInfo) = 0; - virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array dependencies, PViewport renderArea) = 0; + virtual ORenderPass createRenderPass(RenderTargetLayout layout, Array dependencies, PViewport renderArea, + std::string name = "") = 0; virtual void beginRenderPass(PRenderPass renderPass) = 0; virtual void endRenderPass() = 0; virtual void waitDeviceIdle() = 0; diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index ad24b0d..d728784 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -245,8 +245,16 @@ void BasePass::render() { graphics->executeCommands(std::move(commands)); commands.clear(); + Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender"); + skyboxCommand->setViewport(viewport); + skyboxCommand->bindPipeline(pipeline); + skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet}); + skyboxCommand->draw(36, 1, 0, 0); + commands.add(std::move(skyboxCommand)); + // Transparent rendering { + permutation.setDepthCulling(false); // ignore visibility infos for transparency Map sortedDraws; for (const auto& t : transparentData) { Vector toCenter = Vector(t.worldPosition) - cameraPos; @@ -280,10 +288,6 @@ void BasePass::render() { { .cullMode = Gfx::SeCullModeFlags(twoSided ? Gfx::SE_CULL_MODE_NONE : Gfx::SE_CULL_MODE_BACK_BIT), }, - .depthStencilState = - { - .depthCompareOp = Gfx::SE_COMPARE_OP_GREATER_OR_EQUAL, - }, .colorBlend = { .attachmentCount = 1, @@ -359,13 +363,6 @@ void BasePass::render() { commands.add(std::move(debugCommand)); } - Gfx::ORenderCommand skyboxCommand = graphics->createRenderCommand("SkyboxRender"); - skyboxCommand->setViewport(viewport); - skyboxCommand->bindPipeline(pipeline); - skyboxCommand->bindDescriptor({viewParamsSet, skyboxDataSet, textureSet}); - skyboxCommand->draw(36, 1, 0, 0); - - commands.add(std::move(skyboxCommand)); graphics->executeCommands(std::move(commands)); graphics->endRenderPass(); query->endQuery(); @@ -461,7 +458,7 @@ void BasePass::createRenderPass() { Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT, }, }; - renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport); + renderPass = graphics->createRenderPass(std::move(layout), std::move(dependency), viewport, "BasePass"); oLightIndexList = resources->requestBuffer("LIGHTCULLING_OLIGHTLIST"); tLightIndexList = resources->requestBuffer("LIGHTCULLING_TLIGHTLIST"); oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID"); diff --git a/src/Engine/Graphics/VertexData.cpp b/src/Engine/Graphics/VertexData.cpp index bfb718a..6d98f75 100644 --- a/src/Engine/Graphics/VertexData.cpp +++ b/src/Engine/Graphics/VertexData.cpp @@ -17,8 +17,8 @@ uint64 VertexData::meshletCount = 0; void VertexData::resetMeshData() { std::unique_lock l(materialDataLock); - transparentInstanceData.clear(); - transparentMeshData.clear(); + instanceData.clear(); + instanceMeshData.clear(); rayTracingScene.clear(); for (auto& mat : materialData) { for (auto& inst : mat.instances) { @@ -47,6 +47,7 @@ void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Compo .inverseTransformMatrix = glm::inverse(transformMatrix), }; + referencedInstance->updateDescriptor(); if (mat->hasTransparency()) { auto params = referencedInstance->getMaterialOffsets(); transparentData.add(TransparentDraw{ @@ -54,15 +55,15 @@ void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Compo .vertexData = this, .offsets = { - .instanceOffset = static_cast(transparentInstanceData.size()), + .instanceOffset = static_cast(instanceData.size()), .textureOffset = params.textureOffset, .samplerOffset = params.samplerOffset, .floatOffset = params.floatOffset, }, .worldPosition = Vector(inst.transformMatrix[3]), }); - transparentInstanceData.add(inst); - transparentMeshData.add(data); + instanceData.add(inst); + instanceMeshData.add(data); return; } if (materialData.size() <= mat->getId()) { @@ -82,7 +83,6 @@ void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Compo matInstanceData.instanceData.add(inst); matInstanceData.instanceMeshData.add(data); matInstanceData.cullingOffsets.add(meshletOffset); - referencedInstance->updateDescriptor(); for (size_t i = 0; i < 0; ++i) { auto bounding = meshlets[data.meshletOffset + i].bounding; StaticArray corners; @@ -126,9 +126,6 @@ void VertexData::updateMesh(entt::entity id, uint32 meshIndex, PMesh mesh, Compo void VertexData::createDescriptors() { std::unique_lock l(materialDataLock); - instanceData.clear(); - instanceMeshData.clear(); - Array cullingOffsets; for (auto& mat : materialData) { for (auto& instance : mat.instances) { @@ -185,24 +182,6 @@ void VertexData::createDescriptors() { instanceMeshDataBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_MEMORY_READ_BIT, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT); - transparentInstanceDataBuffer->rotateBuffer(sizeof(InstanceData) * transparentInstanceData.size()); - transparentInstanceDataBuffer->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = sizeof(InstanceData) * transparentInstanceData.size(), - .data = (uint8*)transparentInstanceData.data(), - }, - }); - - transparentMeshDataBuffer->rotateBuffer(sizeof(MeshData) * transparentMeshData.size()); - transparentMeshDataBuffer->updateContents(ShaderBufferCreateInfo{ - .sourceData = - { - .size = sizeof(MeshData) * transparentMeshData.size(), - .data = (uint8*)transparentMeshData.data(), - }, - }); - instanceDataLayout->reset(); descriptorSet = instanceDataLayout->allocateDescriptorSet(); descriptorSet->updateBuffer(0, instanceBuffer); @@ -370,16 +349,6 @@ void VertexData::init(Gfx::PGraphics _graphics) { .dynamic = true, .name = "MeshDataBuffer", }); - - transparentInstanceDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .dynamic = true, - .name = "TransparentInstanceBuffer", - }); - transparentMeshDataBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{ - .dynamic = true, - .name = "TransparentMeshBuffer", - }); - resizeBuffers(); graphics->getShaderCompiler()->registerVertexData(this); } diff --git a/src/Engine/Graphics/VertexData.h b/src/Engine/Graphics/VertexData.h index b9d60a7..71f6fc5 100644 --- a/src/Engine/Graphics/VertexData.h +++ b/src/Engine/Graphics/VertexData.h @@ -148,11 +148,6 @@ class VertexData { Gfx::OShaderBuffer instanceMeshDataBuffer; Array rayTracingScene; - - Array transparentInstanceData; - Gfx::OShaderBuffer transparentInstanceDataBuffer; - Array transparentMeshData; - Gfx::OShaderBuffer transparentMeshDataBuffer; Gfx::PDescriptorSet descriptorSet; uint64 idCounter; diff --git a/src/Engine/Graphics/Vulkan/Graphics.cpp b/src/Engine/Graphics/Vulkan/Graphics.cpp index d991293..aeb9e4a 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.cpp +++ b/src/Engine/Graphics/Vulkan/Graphics.cpp @@ -145,8 +145,8 @@ Gfx::OViewport Graphics::createViewport(Gfx::PWindow owner, const ViewportCreate } Gfx::ORenderPass Graphics::createRenderPass(Gfx::RenderTargetLayout layout, Array dependencies, - Gfx::PViewport renderArea) { - return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea); + Gfx::PViewport renderArea, std::string name) { + return new RenderPass(this, std::move(layout), std::move(dependencies), renderArea, name); } void Graphics::beginRenderPass(Gfx::PRenderPass renderPass) { PRenderPass rp = renderPass.cast(); diff --git a/src/Engine/Graphics/Vulkan/Graphics.h b/src/Engine/Graphics/Vulkan/Graphics.h index c386cdf..6e9b883 100644 --- a/src/Engine/Graphics/Vulkan/Graphics.h +++ b/src/Engine/Graphics/Vulkan/Graphics.h @@ -35,7 +35,7 @@ class Graphics : public Gfx::Graphics { virtual Gfx::OViewport createViewport(Gfx::PWindow owner, const ViewportCreateInfo& createInfo) override; virtual Gfx::ORenderPass createRenderPass(Gfx::RenderTargetLayout layout, Array dependencies, - Gfx::PViewport renderArea) override; + Gfx::PViewport renderArea, std::string name) override; virtual void beginRenderPass(Gfx::PRenderPass renderPass) override; virtual void endRenderPass() override; virtual void waitDeviceIdle() override; diff --git a/src/Engine/Graphics/Vulkan/RenderPass.cpp b/src/Engine/Graphics/Vulkan/RenderPass.cpp index 175918a..f135df6 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.cpp +++ b/src/Engine/Graphics/Vulkan/RenderPass.cpp @@ -11,7 +11,7 @@ using namespace Seele; using namespace Seele::Vulkan; RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Array _dependencies, - Gfx::PViewport viewport) + Gfx::PViewport viewport, std::string name) : Gfx::RenderPass(std::move(_layout), std::move(_dependencies)), graphics(graphics) { renderArea.extent.width = viewport->getWidth(); renderArea.extent.height = viewport->getHeight(); @@ -200,6 +200,15 @@ RenderPass::RenderPass(PGraphics graphics, Gfx::RenderTargetLayout _layout, Arra }; VK_CHECK(vkCreateRenderPass2(graphics->getDevice(), &info, nullptr, &renderPass)); + VkDebugUtilsObjectNameInfoEXT nameInfo = { + .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT, + .pNext = nullptr, + .objectType = VK_OBJECT_TYPE_RENDER_PASS, + .objectHandle = (uint64)renderPass, + .pObjectName = name.c_str(), + }; + assert(!name.empty()); + vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo); } RenderPass::~RenderPass() { diff --git a/src/Engine/Graphics/Vulkan/RenderPass.h b/src/Engine/Graphics/Vulkan/RenderPass.h index 2e81e2b..66fbf19 100644 --- a/src/Engine/Graphics/Vulkan/RenderPass.h +++ b/src/Engine/Graphics/Vulkan/RenderPass.h @@ -2,12 +2,11 @@ #include "Graphics.h" #include "Graphics/RenderTarget.h" - namespace Seele { namespace Vulkan { class RenderPass : public Gfx::RenderPass { public: - RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array dependencies, Gfx::PViewport viewport); + RenderPass(PGraphics graphics, Gfx::RenderTargetLayout layout, Array dependencies, Gfx::PViewport viewport, std::string name); virtual ~RenderPass(); uint32 getFramebufferHash(); void endRenderPass(); diff --git a/src/Engine/Window/GameView.cpp b/src/Engine/Window/GameView.cpp index 5a8a0a1..e40c96b 100644 --- a/src/Engine/Window/GameView.cpp +++ b/src/Engine/Window/GameView.cpp @@ -23,12 +23,12 @@ using namespace Seele; GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreateInfo& createInfo, std::string dllPath) : View(graphics, window, createInfo, "Game"), scene(new Scene(graphics)), gameInterface(dllPath) { reloadGame(); - //renderGraph.addPass(new CachedDepthPass(graphics, scene)); - //renderGraph.addPass(new DepthCullingPass(graphics, scene)); - //renderGraph.addPass(new VisibilityPass(graphics, scene)); - //renderGraph.addPass(new LightCullingPass(graphics, scene)); - //renderGraph.addPass(new BasePass(graphics, scene)); - renderGraph.addPass(new RayTracingPass(graphics, scene)); + renderGraph.addPass(new CachedDepthPass(graphics, scene)); + renderGraph.addPass(new DepthCullingPass(graphics, scene)); + renderGraph.addPass(new VisibilityPass(graphics, scene)); + renderGraph.addPass(new LightCullingPass(graphics, scene)); + renderGraph.addPass(new BasePass(graphics, scene)); + //renderGraph.addPass(new RayTracingPass(graphics, scene)); renderGraph.setViewport(viewport); renderGraph.createRenderPass(); }