From fcdb132d4985d1394f200ac14cb60524c6871c0f Mon Sep 17 00:00:00 2001 From: Dynamitos Date: Wed, 21 Aug 2024 10:24:37 +0200 Subject: [PATCH] Fixed water rendering somewhat --- res/shaders/WaterCommon.slang | 12 +++++++++--- res/shaders/WaterCompute.slang | 18 ++---------------- res/shaders/WaterMesh.slang | 14 +++++++++----- res/shaders/WaterPass.slang | 18 +++++++++--------- res/shaders/WaterTask.slang | 16 +++++++++++++--- src/Editor/main.cpp | 19 +++++++++++-------- src/Engine/Graphics/RenderPass/BasePass.cpp | 4 ++-- .../Graphics/RenderPass/WaterRenderer.cpp | 15 +++++++-------- 8 files changed, 62 insertions(+), 54 deletions(-) diff --git a/res/shaders/WaterCommon.slang b/res/shaders/WaterCommon.slang index bfad738..83152f0 100644 --- a/res/shaders/WaterCommon.slang +++ b/res/shaders/WaterCommon.slang @@ -1,9 +1,15 @@ struct WaterPayload { - float2 offset; + float3 offset; + float extent; +}; + +struct WaterTile +{ + int2 location; float extent; float height; -}; +} struct WaterVertex { @@ -58,7 +64,7 @@ struct MaterialParams Texture2DArray slopeTextures; TextureCube environmentMap; SamplerState sampler; - StructuredBuffer tiles; + StructuredBuffer tiles; }; layout(set = 1) ParameterBlock pWaterMaterial; diff --git a/res/shaders/WaterCompute.slang b/res/shaders/WaterCompute.slang index 202369a..bbcf6da 100644 --- a/res/shaders/WaterCompute.slang +++ b/res/shaders/WaterCompute.slang @@ -157,7 +157,7 @@ void CS_InitializeSpectrum(uint3 id : SV_DISPATCHTHREADID) { pParams.initialSpectrumTextures[uint3(id.xy, i)] = float4(float2(gauss2.x, gauss1.y) * sqrt(2 * spectrum * abs(dOmegadk) / kLength * deltaK * deltaK), 0.0f, 0.0f); } else { - pParams.initialSpectrumTextures[uint3(id.xy, i)] = 0.0f; + pParams.initialSpectrumTextures[uint3(id.xy, i)] = 1.0f; } } } @@ -221,20 +221,6 @@ void CS_UpdateSpectrumForFFT(uint3 id : SV_DISPATCHTHREADID) { } } -float2 ComplexExp(float2 a) { - return float2(cos(a.y), sin(a.y) * exp(a.x)); -} - - -float4 ComputeTwiddleFactorAndInputIndices(uint2 id) { - uint b = pParams.N >> (id.x + 1); - float2 mult = 2 * PI * float2(0.0f, 1.0f) / pParams.N; - uint i = (2 * b * (id.y / b) + id.y % b) % pParams.N; - float2 twiddle = ComplexExp(-mult * ((id.y / b) * b)); - - return float4(twiddle, i, i + b); -} - #define SIZE 1024 #define LOG_SIZE 10 @@ -264,7 +250,7 @@ float4 FFT(uint threadIndex, float4 input) { ButterflyValues(step, threadIndex, inputsIndices, twiddle); float4 v = fftGroupBuffer[uint(flag)][inputsIndices.y]; - fftGroupBuffer[uint(flag)][threadIndex] = fftGroupBuffer[uint(flag)][inputsIndices.x] + float4(ComplexMult(twiddle, v.xy), ComplexMult(twiddle, v.zw)); + fftGroupBuffer[uint(!flag)][threadIndex] = fftGroupBuffer[uint(flag)][inputsIndices.x] + float4(ComplexMult(twiddle, v.xy), ComplexMult(twiddle, v.zw)); flag = !flag; GroupMemoryBarrierWithGroupSync(); diff --git a/res/shaders/WaterMesh.slang b/res/shaders/WaterMesh.slang index 3936895..dc3d0c2 100644 --- a/res/shaders/WaterMesh.slang +++ b/res/shaders/WaterMesh.slang @@ -29,7 +29,7 @@ uint3(53, 42, 54), uint3(42, 43, 54), uint3(54, 43, 55), uint3(43, 44, 55), uint [shader("mesh")] void meshMain( in uint threadID: SV_GroupThreadID, - in uint groupID: SV_GroupID, + in uint3 groupID: SV_GroupID, in payload WaterPayload params, out vertices WaterVertex vertices[TILE_VERTS], out indices uint3 indices[TILE_PRIMS], @@ -44,8 +44,8 @@ void meshMain( for(uint i = threadID; i < TILE_VERTS; i += MESH_GROUP_SIZE) { float2 base = VERT[i]; - float2 worldTransformed = params.offset + (params.extent * base); - float3 worldPos = float3(worldTransformed.x, params.height, worldTransformed.y); + float3 objectPos = float3(base.x, 0, base.y); + float3 worldPos = params.offset + objectPos * params.extent + float3(groupID.x * params.extent, 0, groupID.y * params.extent); 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; float3 displacement3 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(worldPos.xz * pWaterMaterial.tile3, 2)).xyz * pWaterMaterial.contributeDisplacement3; @@ -53,7 +53,11 @@ void meshMain( float3 displacement = displacement1 + displacement2 + displacement3 + displacement4; float4 clipPos = mul(vp, float4(worldPos, 1)); - float depth = 1 - clamp(1 / (clipPos.z / clipPos.w), 0, 1); + float ndcDepth = clipPos.z / clipPos.w; + + float depth = 1 - (-ndcDepth + 1.0f) / 2.0f; + + displacement = lerp(0.0f, displacement, pow(saturate(depth), pWaterMaterial.displacementDepthAttenuation)); worldPos += displacement; @@ -61,7 +65,7 @@ void meshMain( v.position_WS = worldPos; v.position_CS = mul(vp, float4(worldPos, 1)); v.texCoord = worldPos.xz; - v.depth = clipPos.z / clipPos.w; + v.depth = depth; vertices[i] = v; } } \ No newline at end of file diff --git a/res/shaders/WaterPass.slang b/res/shaders/WaterPass.slang index a8d2557..320077d 100644 --- a/res/shaders/WaterPass.slang +++ b/res/shaders/WaterPass.slang @@ -30,20 +30,20 @@ float4 main(WaterVertex vert) : SV_TARGET { float VdotH = clamp(dot(viewDir, halfwayDir), 0, 1); - float4 displacementFoam1 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile1, 0)); + float4 displacementFoam1 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile1, 0)); displacementFoam1.a += pWaterMaterial.foamSubtract0; - float4 displacementFoam2 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile2, 0)); + float4 displacementFoam2 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile2, 0)); displacementFoam2.a += pWaterMaterial.foamSubtract1; - float4 displacementFoam3 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile3, 0)); + float4 displacementFoam3 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile3, 0)); displacementFoam3.a += pWaterMaterial.foamSubtract2; - float4 displacementFoam4 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile4, 0)); + float4 displacementFoam4 = pWaterMaterial.displacementTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile4, 0)); displacementFoam4.a += pWaterMaterial.foamSubtract3; float4 displacementFoam = displacementFoam1 + displacementFoam2 + displacementFoam3 + displacementFoam4; - float2 slopes1 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile1, 0)); - float2 slopes2 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile2, 1)); - float2 slopes3 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile3, 2)); - float2 slopes4 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile4, 3)); + float2 slopes1 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile1, 0)); + float2 slopes2 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile2, 1)); + float2 slopes3 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile3, 2)); + float2 slopes4 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile4, 3)); float2 slopes = slopes1 + slopes2 + slopes3 + slopes4; slopes *= pWaterMaterial.normalStrength; @@ -51,7 +51,7 @@ float4 main(WaterVertex vert) : SV_TARGET { float3 macroNormal = float3(0, 1, 0); float3 mesoNormal = normalize(float3(-slopes.x, 1.0f, -slopes.y)); - mesoNormal = normalize(lerp(float3(0, 1, 0), mesoNormal, pow(saturate(depth), pWaterMaterial.normalDepthAttenuation))); + mesoNormal = normalize(lerp(macroNormal, mesoNormal, pow(saturate(depth), pWaterMaterial.normalDepthAttenuation))); mesoNormal = normalize(mesoNormal); float NdotL = clamp(dot(mesoNormal, lightDir), 0, 1); diff --git a/res/shaders/WaterTask.slang b/res/shaders/WaterTask.slang index cc38ad4..c8bac92 100644 --- a/res/shaders/WaterTask.slang +++ b/res/shaders/WaterTask.slang @@ -1,8 +1,8 @@ +import Bounding; import Common; import Scene; import WaterCommon; -groupshared WaterPayload p; [numthreads(1, 1, 1)] [shader("amplification")] @@ -10,6 +10,16 @@ void taskMain( uint threadID: SV_GroupThreadID, uint groupID: SV_GroupID, ) { - p = pWaterMaterial.tiles[groupID]; - DispatchMesh(1, 1, 1, p); + WaterTile tile = pWaterMaterial.tiles[groupID]; + GroupMemoryBarrierWithGroupSync(); + AABB bounding; + bounding.minCorner = float3(tile.location.x, tile.height, tile.location.y) * tile.extent; + bounding.maxCorner = float3(tile.location.x + 1, tile.height, tile.location.y + 1) * tile.extent; + float3 median = (bounding.minCorner + bounding.maxCorner) / 2; + float distance = distance(median, pViewParams.cameraPos_WS.xyz); + uint numMeshes = max(10 - uint(distance / tile.extent), 1); + WaterPayload payload; + payload.offset = bounding.minCorner; + payload.extent = tile.extent / numMeshes; + DispatchMesh(numMeshes, numMeshes, 1, payload); } diff --git a/src/Editor/main.cpp b/src/Editor/main.cpp index acf907a..42a61f2 100644 --- a/src/Editor/main.cpp +++ b/src/Editor/main.cpp @@ -11,9 +11,9 @@ #include "Graphics/Vulkan/Graphics.h" #endif #include "Graphics/StaticMeshVertexData.h" +#include "Graphics/Vulkan/Buffer.h" #include "Graphics/Vulkan/Graphics.h" #include "Window/PlayView.h" -#include "Graphics/Vulkan/Buffer.h" #include "Window/WindowManager.h" #include #include @@ -64,14 +64,17 @@ int main() { .filePath = sourcePath / "import/textures/skyboxsun5deg_tn.jpg", .type = TextureImportType::TEXTURE_CUBEMAP, }); - //ssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb", - // .importPath = "Whitechapel", - //); + AssetImporter::importMesh(MeshImportArgs{ + .filePath = sourcePath / "import/models/sheepsbody.fbx", + }); // AssetImporter::importMesh(MeshImportArgs{ - // .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj", - // .importPath = "suburbs", - // }); + // .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", + // }); vd->commitMeshes(); WindowCreateInfo mainWindowInfo = { .width = 1920, diff --git a/src/Engine/Graphics/RenderPass/BasePass.cpp b/src/Engine/Graphics/RenderPass/BasePass.cpp index ffd831c..a08eb31 100644 --- a/src/Engine/Graphics/RenderPass/BasePass.cpp +++ b/src/Engine/Graphics/RenderPass/BasePass.cpp @@ -98,7 +98,7 @@ void BasePass::beginFrame(const Component::Camera& cam) { opaqueCulling = lightCullingLayout->allocateDescriptorSet(); transparentCulling = lightCullingLayout->allocateDescriptorSet(); - waterRenderer->beginFrame(); + //waterRenderer->beginFrame(); // Debug vertices { @@ -248,7 +248,7 @@ void BasePass::render() { } } - commands.add(waterRenderer->render(viewParamsSet)); + //commands.add(waterRenderer->render(viewParamsSet)); // Skybox { diff --git a/src/Engine/Graphics/RenderPass/WaterRenderer.cpp b/src/Engine/Graphics/RenderPass/WaterRenderer.cpp index 4745044..462b875 100644 --- a/src/Engine/Graphics/RenderPass/WaterRenderer.cpp +++ b/src/Engine/Graphics/RenderPass/WaterRenderer.cpp @@ -344,23 +344,23 @@ WaterRenderer::WaterRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescri WaterRenderer::~WaterRenderer() {} void WaterRenderer::beginFrame() { - struct WaterPayload { - Vector2 offset; + struct WaterTile { + IVector2 offset; float extent; float height; }; - Array payloads; + Array payloads; scene->view([&](Component::WaterTile& tile) { - payloads.add(WaterPayload{ + payloads.add(WaterTile{ .offset = Vector2(tile.location), - .extent = 1, + .extent = Component::WaterTile::DIMENSIONS, .height = tile.height, }); }); waterTiles = graphics->createShaderBuffer(ShaderBufferCreateInfo{ .sourceData = { - .size = payloads.size() * sizeof(WaterPayload), + .size = payloads.size() * sizeof(WaterTile), .data = (uint8*)payloads.data(), }, .numElements = payloads.size(), @@ -413,8 +413,6 @@ void WaterRenderer::beginFrame() { assembleCommand->dispatch(threadGroupsX, threadGroupsY, 1); graphics->executeCommands(std::move(assembleCommand)); - graphics->waitDeviceIdle(); - // transition for mipmap gen displacementTextures->changeLayout( Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, @@ -464,6 +462,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 =