From 88eacd067ec78c9639cb051e821ef128bed81d8f Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Fri, 30 Aug 2024 09:29:41 +0200 Subject: [PATCH] Finished water for real this time --- res/shaders/WaterMesh.slang | 28 +++++++++++++++++-- res/shaders/WaterTask.slang | 9 +++--- src/Editor/Asset/TextureLoader.cpp | 4 +-- src/Editor/main.cpp | 14 +++++----- src/Engine/Graphics/RenderPass/BasePass.cpp | 4 +-- .../Graphics/RenderPass/WaterRenderer.cpp | 4 ++- src/Engine/ThreadPool.cpp | 16 ++++++++++- src/Engine/ThreadPool.h | 3 ++ 8 files changed, 61 insertions(+), 21 deletions(-) diff --git a/res/shaders/WaterMesh.slang b/res/shaders/WaterMesh.slang index 583fc40..d9ccb93 100644 --- a/res/shaders/WaterMesh.slang +++ b/res/shaders/WaterMesh.slang @@ -49,11 +49,33 @@ void meshMain( float lodDisplacement = 0; float3 camPos = pViewParams.cameraPos_WS.xyz; - float cameraDistance = distance(worldPos, float3(camPos.x, 0, camPos.z)) / params.extent; + float cameraDistance = distance(worldPos, camPos); + float threshold = 0; + if(params.numMeshes == 3) + { + threshold = 10; + } + if(params.numMeshes == 2) + { + threshold = 30; + } + if(params.numMeshes == 1) + { + threshold = 70; + } + if(params.numMeshes < 4) { - lodDisplacement = exp(-(1 / (cameraDistance + 4))); + if(cameraDistance > threshold) + { + lodDisplacement = clamp(exp(-(1 / (cameraDistance + threshold))), 0, 1) - 1; + } + else + { + lodDisplacement = -1; + } } + float3 displacement1 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(worldPos.xz * pWaterMaterial.tile1, 0)).xyz * pWaterMaterial.contributeDisplacement1; float3 displacement2 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(worldPos.xz * pWaterMaterial.tile2, 1)).xyz * pWaterMaterial.contributeDisplacement2; @@ -69,7 +91,7 @@ void meshMain( displacement = lerp(0.0f, displacement, pow(saturate(depth), pWaterMaterial.displacementDepthAttenuation)); worldPos += displacement; - worldPos.y = lodDisplacement; + worldPos.y += lodDisplacement; WaterVertex v; v.position_WS = worldPos; diff --git a/res/shaders/WaterTask.slang b/res/shaders/WaterTask.slang index 2e76fdf..f8d85a0 100644 --- a/res/shaders/WaterTask.slang +++ b/res/shaders/WaterTask.slang @@ -19,26 +19,25 @@ void taskMain( float tileDistance = distance / tile.extent; uint numMeshes = groupID.y + 1; - if(numMeshes == 4 && (tileDistance > 8)) + if(numMeshes == 4 && tileDistance > 2) { return; } - if(numMeshes == 3) + if(numMeshes == 3 && (tileDistance > 4 || tileDistance < 1)) { return; } - if(numMeshes == 2) + if(numMeshes == 2 && (tileDistance > 8 || tileDistance < 3)) { return; } - if(numMeshes == 1) + if(numMeshes == 1 && tileDistance < 7) { return; } WaterPayload payload; payload.offset = bounding.minCorner; payload.extent = tile.extent / numMeshes; - // todo: hardcoded max lod payload.numMeshes = numMeshes; DispatchMesh(numMeshes, numMeshes, 1, payload); } diff --git a/src/Editor/Asset/TextureLoader.cpp b/src/Editor/Asset/TextureLoader.cpp index c288da2..af9297d 100644 --- a/src/Editor/Asset/TextureLoader.cpp +++ b/src/Editor/Asset/TextureLoader.cpp @@ -112,11 +112,11 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) { .structSize = sizeof(ktxBasisParams), .uastc = true, .threadCount = 1, - .uastcFlags = KTX_PACK_UASTC_LEVEL_DEFAULT, + .uastcFlags = KTX_PACK_UASTC_LEVEL_FASTER, .uastcRDO = true, }; KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams)); - KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 20)); + KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 2)); char writer[100]; snprintf(writer, sizeof(writer), "%s version %s", "SeeleEngine", "0.0.1"); diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index 26e17c6..2c88337 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -64,19 +64,19 @@ int main() { .filePath = sourcePath / "import/textures/skyboxsun5deg_tn.jpg", .type = TextureImportType::TEXTURE_CUBEMAP, }); + //AssetImporter::importMesh(MeshImportArgs{ + // .filePath = sourcePath / "import/models/ship.fbx", + // .importPath = "ship", + //}); AssetImporter::importMesh(MeshImportArgs{ - .filePath = sourcePath / "import/models/ship.fbx", - .importPath = "ship", + .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", + .importPath = "Whitechapel", }); - // AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", - // .importPath = "Whitechapel", - //); // AssetImporter::importMesh(MeshImportArgs{ // .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj", // .importPath = "suburbs", // }); - + getThreadPool().waitIdle(); vd->commitMeshes(); WindowCreateInfo mainWindowInfo = { .width = 1920, diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index 8d528b8..a08eb31 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -26,7 +26,7 @@ void Seele::addDebugVertex(DebugVertex vert) { gDebugVertices.add(vert); } void Seele::addDebugVertices(Array verts) { gDebugVertices.addAll(verts); } BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) { - //waterRenderer = new WaterRenderer(graphics, scene, viewParamsLayout); + waterRenderer = new WaterRenderer(graphics, scene, viewParamsLayout); basePassLayout = graphics->createPipelineLayout("BasePassLayout"); basePassLayout->addDescriptorLayout(viewParamsLayout); @@ -472,7 +472,7 @@ void BasePass::createRenderPass() { oLightGrid = resources->requestTexture("LIGHTCULLING_OLIGHTGRID"); tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID"); - //waterRenderer->setViewport(viewport, renderPass); + waterRenderer->setViewport(viewport, renderPass); // Debug rendering { diff --git a/src/Engine/Graphics/RenderPass/WaterRenderer.cpp b/src/Engine/Graphics/RenderPass/WaterRenderer.cpp index d891243..5e2c711 100644 --- a/src/Engine/Graphics/RenderPass/WaterRenderer.cpp +++ b/src/Engine/Graphics/RenderPass/WaterRenderer.cpp @@ -358,6 +358,8 @@ void WaterRenderer::beginFrame() { .height = tile.height, }); }); + if (payloads.size() == 0) + return; waterTiles = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { @@ -435,7 +437,6 @@ void WaterRenderer::beginFrame() { boyancyData->changeLayout(Gfx::SE_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_SHADER_STAGE_MESH_BIT_EXT); - updateMaterialDescriptor(); } @@ -463,6 +464,7 @@ void WaterRenderer::setViewport(Gfx::PViewport _viewport, Gfx::PRenderPass rende }, .rasterizationState = { + //.polygonMode = Gfx::SE_POLYGON_MODE_LINE, .cullMode = Gfx::SE_CULL_MODE_BACK_BIT, }, .colorBlend = diff --git a/src/Engine/ThreadPool.cpp b/src/Engine/ThreadPool.cpp index 07b1fce..205efcc 100644 --- a/src/Engine/ThreadPool.cpp +++ b/src/Engine/ThreadPool.cpp @@ -54,11 +54,25 @@ void ThreadPool::runAsync(std::function func) { queueCV.notify_one(); } +void ThreadPool::waitIdle() { + std::unique_lock l(queueLock); + while (numWaiting < workers.size()) + { + idleCV.wait(l); + } +} + void ThreadPool::work() { while (running) { std::unique_lock l(queueLock); while (queue.empty()) { + numWaiting++; + if (numWaiting == workers.size()) + { + idleCV.notify_all(); + } queueCV.wait(l); + numWaiting--; if (!running) { return; } @@ -72,7 +86,7 @@ void ThreadPool::work() { std::unique_lock t(taskLock); entry.task->numRemaining--; if (entry.task->numRemaining == 0) { - completedCV.notify_one(); + completedCV.notify_all(); } } } diff --git a/src/Engine/ThreadPool.h b/src/Engine/ThreadPool.h index 0eef80b..62bfc2e 100644 --- a/src/Engine/ThreadPool.h +++ b/src/Engine/ThreadPool.h @@ -11,6 +11,7 @@ class ThreadPool { ~ThreadPool(); void runAndWait(List> functions); void runAsync(std::function func); + void waitIdle(); private: struct TaskGroup { uint64 numRemaining = 0; @@ -22,6 +23,8 @@ class ThreadPool { std::mutex queueLock; std::condition_variable queueCV; + std::atomic_uint32_t numWaiting = 0; + std::condition_variable idleCV; List queue; void work();