ocean fixes

This commit is contained in:
Turánszki János
2024-07-23 16:59:38 +02:00
parent ed6e930c96
commit dafc77f4b9
4 changed files with 50 additions and 43 deletions
@@ -8,6 +8,7 @@ struct PSIn
float4 pos : SV_POSITION;
float3 pos3D : WORLDPOSITION;
float2 uv : TEXCOORD0;
uint behind : BEHIND;
};
float3 intersectPlaneClampInfinite(in float3 rayOrigin, in float3 rayDirection, in float3 planeNormal, float planeHeight)
+6 -6
View File
@@ -6,15 +6,15 @@ Texture2D<float4> texture_displacementmap : register(t0);
PSIn main(uint vertexID : SV_VertexID)
{
PSIn Out;
// Retrieve grid dimensions and 1/gridDimensions:
float2 dim = xOceanScreenSpaceParams.xy;
float2 invdim = xOceanScreenSpaceParams.zw;
uint2 grid_coord = unflatten2D(vertexID, dim.xy);
// Assemble screen space grid:
Out.pos = float4((grid_coord + 0.5) * invdim, 0, 1);
Out.pos.xy = Out.pos.xy * 2 - 1;
Out.pos = float4(grid_coord / float2(dim - 1), 1, 1);
Out.pos.xy = uv_to_clipspace(Out.pos.xy);
float4 originalpos = Out.pos;
Out.pos.xy *= max(1, xOceanSurfaceDisplacementTolerance); // extrude screen space grid to tolerate displacement
// Perform ray tracing of screen grid and plane surface to unproject to world space:
@@ -24,7 +24,7 @@ PSIn main(uint vertexID : SV_VertexID)
const float3 d = normalize(o.xyz - unproj.xyz);
float3 worldPos = intersectPlaneClampInfinite(o, d, float3(0, 1, 0), xOceanWaterHeight);
float2 uv = worldPos.xz * xOceanPatchSizeRecip;
if (grid_coord.x > 0 && grid_coord.x < dim.x - 1 && grid_coord.y > 0 && grid_coord.y < dim.y - 1) // don't displace the side edges, to avoid holes
{
+42 -36
View File
@@ -9,6 +9,7 @@
#include "wiVector.h"
#include <algorithm>
#include <mutex>
using namespace wi::graphics;
using namespace wi::scene;
@@ -205,40 +206,6 @@ namespace wi
cb_desc.bind_flags = BindFlag::CONSTANT_BUFFER;
cb_desc.size = sizeof(OceanCB);
device->CreateBuffer(&cb_desc, nullptr, &constantBuffer);
const uint2 dim = uint2(160 * params.surfaceDetail, 90 * params.surfaceDetail);
const uint index_count = (dim.x - 1) * (dim.y - 1) * 6;
const uint64_t indexbuffer_required_size = index_count * sizeof(uint32_t);
if (indexBuffer.GetDesc().size != indexbuffer_required_size)
{
wi::vector<uint32_t> index_data(index_count);
size_t counter = 0;
for (uint32_t x = 0; x < dim.x - 1; x++)
{
for (uint32_t y = 0; y < dim.y - 1; y++)
{
uint32_t lowerLeft = x + y * dim.x;
uint32_t lowerRight = (x + 1) + y * dim.x;
uint32_t topLeft = x + (y + 1) * dim.x;
uint32_t topRight = (x + 1) + (y + 1) * dim.x;
index_data[counter++] = topLeft;
index_data[counter++] = lowerLeft;
index_data[counter++] = lowerRight;
index_data[counter++] = topLeft;
index_data[counter++] = lowerRight;
index_data[counter++] = topRight;
}
}
GPUBufferDesc desc;
desc.bind_flags = BindFlag::INDEX_BUFFER;
desc.size = indexbuffer_required_size;
device->CreateBuffer(&desc, index_data.data(), &indexBuffer);
device->SetName(&indexBuffer, "Ocean::indexBuffer");
}
}
XMFLOAT3 Ocean::GetDisplacedPosition(const XMFLOAT3& worldPosition) const
@@ -358,7 +325,10 @@ namespace wi
cb.xOceanWaterColor = params.waterColor;
cb.xOceanExtinctionColor = XMFLOAT4(1 - params.extinctionColor.x, 1 - params.extinctionColor.y, 1 - params.extinctionColor.z, 1);
cb.xOceanTexelLength = params.patch_length / params.dmap_dim;
cb.xOceanScreenSpaceParams = XMFLOAT4((float)dim.x, (float)dim.y, 1.0f / (float)dim.x, 1.0f / (float)dim.y);
cb.xOceanScreenSpaceParams.x = (float)dim.x;
cb.xOceanScreenSpaceParams.y = (float)dim.y;
cb.xOceanScreenSpaceParams.z = 1.0f / cb.xOceanScreenSpaceParams.x;
cb.xOceanScreenSpaceParams.w = 1.0f / cb.xOceanScreenSpaceParams.y;
cb.xOceanPatchSizeRecip = 1.0f / params.patch_length;
cb.xOceanMapHalfTexel = 0.5f / params.dmap_dim;
cb.xOceanWaterHeight = params.waterHeight;
@@ -460,6 +430,42 @@ namespace wi
device->BindPipelineState(&PSO, cmd);
}
const uint2 dim = uint2(160 * params.surfaceDetail, 90 * params.surfaceDetail);
const uint index_count = dim.x * dim.y * 6;
const uint64_t indexbuffer_required_size = index_count * sizeof(uint32_t);
static std::mutex locker;
locker.lock(); // in case two threads draw the ocean the same time, index buffer creation must be locked
if (indexBuffer.GetDesc().size != indexbuffer_required_size)
{
wi::vector<uint32_t> index_data(index_count);
size_t counter = 0;
for (uint32_t x = 0; x < dim.x - 1; x++)
{
for (uint32_t y = 0; y < dim.y - 1; y++)
{
uint32_t lowerLeft = x + y * dim.x;
uint32_t lowerRight = (x + 1) + y * dim.x;
uint32_t topLeft = x + (y + 1) * dim.x;
uint32_t topRight = (x + 1) + (y + 1) * dim.x;
index_data[counter++] = topLeft;
index_data[counter++] = lowerLeft;
index_data[counter++] = lowerRight;
index_data[counter++] = topLeft;
index_data[counter++] = lowerRight;
index_data[counter++] = topRight;
}
}
GPUBufferDesc desc;
desc.bind_flags = BindFlag::INDEX_BUFFER;
desc.size = indexbuffer_required_size;
device->CreateBuffer(&desc, index_data.data(), &indexBuffer);
device->SetName(&indexBuffer, "Ocean::indexBuffer");
}
locker.unlock();
device->BindConstantBuffer(&constantBuffer, CB_GETBINDSLOT(OceanCB), cmd);
device->BindResource(&displacementMap, 0, cmd);
@@ -467,7 +473,7 @@ namespace wi
device->BindIndexBuffer(&indexBuffer, IndexBufferFormat::UINT32, 0, cmd);
device->DrawIndexed(uint32_t(indexBuffer.desc.size / sizeof(uint32_t)), 0, 0, cmd);
device->DrawIndexed(index_count, 0, 0, cmd);
device->EventEnd(cmd);
}
+1 -1
View File
@@ -9,7 +9,7 @@ namespace wi::version
// minor features, major updates, breaking compatibility changes
const int minor = 71;
// minor bug fixes, alterations, refactors, updates
const int revision = 519;
const int revision = 520;
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);