Fixed water rendering somewhat
This commit is contained in:
@@ -1,9 +1,15 @@
|
|||||||
struct WaterPayload
|
struct WaterPayload
|
||||||
{
|
{
|
||||||
float2 offset;
|
float3 offset;
|
||||||
|
float extent;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct WaterTile
|
||||||
|
{
|
||||||
|
int2 location;
|
||||||
float extent;
|
float extent;
|
||||||
float height;
|
float height;
|
||||||
};
|
}
|
||||||
|
|
||||||
struct WaterVertex
|
struct WaterVertex
|
||||||
{
|
{
|
||||||
@@ -58,7 +64,7 @@ struct MaterialParams
|
|||||||
Texture2DArray<float2> slopeTextures;
|
Texture2DArray<float2> slopeTextures;
|
||||||
TextureCube environmentMap;
|
TextureCube environmentMap;
|
||||||
SamplerState sampler;
|
SamplerState sampler;
|
||||||
StructuredBuffer<WaterPayload> tiles;
|
StructuredBuffer<WaterTile> tiles;
|
||||||
};
|
};
|
||||||
layout(set = 1)
|
layout(set = 1)
|
||||||
ParameterBlock<MaterialParams> pWaterMaterial;
|
ParameterBlock<MaterialParams> pWaterMaterial;
|
||||||
|
|||||||
@@ -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);
|
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 {
|
} 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 SIZE 1024
|
||||||
#define LOG_SIZE 10
|
#define LOG_SIZE 10
|
||||||
|
|
||||||
@@ -264,7 +250,7 @@ float4 FFT(uint threadIndex, float4 input) {
|
|||||||
ButterflyValues(step, threadIndex, inputsIndices, twiddle);
|
ButterflyValues(step, threadIndex, inputsIndices, twiddle);
|
||||||
|
|
||||||
float4 v = fftGroupBuffer[uint(flag)][inputsIndices.y];
|
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;
|
flag = !flag;
|
||||||
GroupMemoryBarrierWithGroupSync();
|
GroupMemoryBarrierWithGroupSync();
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ uint3(53, 42, 54), uint3(42, 43, 54), uint3(54, 43, 55), uint3(43, 44, 55), uint
|
|||||||
[shader("mesh")]
|
[shader("mesh")]
|
||||||
void meshMain(
|
void meshMain(
|
||||||
in uint threadID: SV_GroupThreadID,
|
in uint threadID: SV_GroupThreadID,
|
||||||
in uint groupID: SV_GroupID,
|
in uint3 groupID: SV_GroupID,
|
||||||
in payload WaterPayload params,
|
in payload WaterPayload params,
|
||||||
out vertices WaterVertex vertices[TILE_VERTS],
|
out vertices WaterVertex vertices[TILE_VERTS],
|
||||||
out indices uint3 indices[TILE_PRIMS],
|
out indices uint3 indices[TILE_PRIMS],
|
||||||
@@ -44,8 +44,8 @@ void meshMain(
|
|||||||
for(uint i = threadID; i < TILE_VERTS; i += MESH_GROUP_SIZE)
|
for(uint i = threadID; i < TILE_VERTS; i += MESH_GROUP_SIZE)
|
||||||
{
|
{
|
||||||
float2 base = VERT[i];
|
float2 base = VERT[i];
|
||||||
float2 worldTransformed = params.offset + (params.extent * base);
|
float3 objectPos = float3(base.x, 0, base.y);
|
||||||
float3 worldPos = float3(worldTransformed.x, params.height, worldTransformed.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 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 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;
|
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;
|
float3 displacement = displacement1 + displacement2 + displacement3 + displacement4;
|
||||||
|
|
||||||
float4 clipPos = mul(vp, float4(worldPos, 1));
|
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;
|
worldPos += displacement;
|
||||||
|
|
||||||
@@ -61,7 +65,7 @@ void meshMain(
|
|||||||
v.position_WS = worldPos;
|
v.position_WS = worldPos;
|
||||||
v.position_CS = mul(vp, float4(worldPos, 1));
|
v.position_CS = mul(vp, float4(worldPos, 1));
|
||||||
v.texCoord = worldPos.xz;
|
v.texCoord = worldPos.xz;
|
||||||
v.depth = clipPos.z / clipPos.w;
|
v.depth = depth;
|
||||||
vertices[i] = v;
|
vertices[i] = v;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -30,20 +30,20 @@ float4 main(WaterVertex vert) : SV_TARGET {
|
|||||||
float VdotH = clamp(dot(viewDir, halfwayDir), 0, 1);
|
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;
|
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;
|
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;
|
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;
|
displacementFoam4.a += pWaterMaterial.foamSubtract3;
|
||||||
float4 displacementFoam = displacementFoam1 + displacementFoam2 + displacementFoam3 + displacementFoam4;
|
float4 displacementFoam = displacementFoam1 + displacementFoam2 + displacementFoam3 + displacementFoam4;
|
||||||
|
|
||||||
float2 slopes1 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile1, 0));
|
float2 slopes1 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile1, 0));
|
||||||
float2 slopes2 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile2, 1));
|
float2 slopes2 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile2, 1));
|
||||||
float2 slopes3 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile3, 2));
|
float2 slopes3 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile3, 2));
|
||||||
float2 slopes4 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.texCoord * pWaterMaterial.tile4, 3));
|
float2 slopes4 = pWaterMaterial.slopeTextures.Sample(pWaterMaterial.sampler, float3(vert.position_WS.xz * pWaterMaterial.tile4, 3));
|
||||||
float2 slopes = slopes1 + slopes2 + slopes3 + slopes4;
|
float2 slopes = slopes1 + slopes2 + slopes3 + slopes4;
|
||||||
|
|
||||||
slopes *= pWaterMaterial.normalStrength;
|
slopes *= pWaterMaterial.normalStrength;
|
||||||
@@ -51,7 +51,7 @@ float4 main(WaterVertex vert) : SV_TARGET {
|
|||||||
|
|
||||||
float3 macroNormal = float3(0, 1, 0);
|
float3 macroNormal = float3(0, 1, 0);
|
||||||
float3 mesoNormal = normalize(float3(-slopes.x, 1.0f, -slopes.y));
|
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);
|
mesoNormal = normalize(mesoNormal);
|
||||||
|
|
||||||
float NdotL = clamp(dot(mesoNormal, lightDir), 0, 1);
|
float NdotL = clamp(dot(mesoNormal, lightDir), 0, 1);
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
|
import Bounding;
|
||||||
import Common;
|
import Common;
|
||||||
import Scene;
|
import Scene;
|
||||||
import WaterCommon;
|
import WaterCommon;
|
||||||
|
|
||||||
groupshared WaterPayload p;
|
|
||||||
|
|
||||||
[numthreads(1, 1, 1)]
|
[numthreads(1, 1, 1)]
|
||||||
[shader("amplification")]
|
[shader("amplification")]
|
||||||
@@ -10,6 +10,16 @@ void taskMain(
|
|||||||
uint threadID: SV_GroupThreadID,
|
uint threadID: SV_GroupThreadID,
|
||||||
uint groupID: SV_GroupID, )
|
uint groupID: SV_GroupID, )
|
||||||
{
|
{
|
||||||
p = pWaterMaterial.tiles[groupID];
|
WaterTile tile = pWaterMaterial.tiles[groupID];
|
||||||
DispatchMesh(1, 1, 1, p);
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-8
@@ -11,9 +11,9 @@
|
|||||||
#include "Graphics/Vulkan/Graphics.h"
|
#include "Graphics/Vulkan/Graphics.h"
|
||||||
#endif
|
#endif
|
||||||
#include "Graphics/StaticMeshVertexData.h"
|
#include "Graphics/StaticMeshVertexData.h"
|
||||||
|
#include "Graphics/Vulkan/Buffer.h"
|
||||||
#include "Graphics/Vulkan/Graphics.h"
|
#include "Graphics/Vulkan/Graphics.h"
|
||||||
#include "Window/PlayView.h"
|
#include "Window/PlayView.h"
|
||||||
#include "Graphics/Vulkan/Buffer.h"
|
|
||||||
#include "Window/WindowManager.h"
|
#include "Window/WindowManager.h"
|
||||||
#include <fmt/core.h>
|
#include <fmt/core.h>
|
||||||
#include <random>
|
#include <random>
|
||||||
@@ -64,14 +64,17 @@ int main() {
|
|||||||
.filePath = sourcePath / "import/textures/skyboxsun5deg_tn.jpg",
|
.filePath = sourcePath / "import/textures/skyboxsun5deg_tn.jpg",
|
||||||
.type = TextureImportType::TEXTURE_CUBEMAP,
|
.type = TextureImportType::TEXTURE_CUBEMAP,
|
||||||
});
|
});
|
||||||
//ssetImporter::importMesh(MeshImportArgs{
|
AssetImporter::importMesh(MeshImportArgs{
|
||||||
// .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
.filePath = sourcePath / "import/models/sheepsbody.fbx",
|
||||||
// .importPath = "Whitechapel",
|
});
|
||||||
//);
|
|
||||||
// AssetImporter::importMesh(MeshImportArgs{
|
// AssetImporter::importMesh(MeshImportArgs{
|
||||||
// .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj",
|
// .filePath = sourcePath / "import/models/after-the-rain-vr-sound/source/Whitechapel.glb",
|
||||||
// .importPath = "suburbs",
|
// .importPath = "Whitechapel",
|
||||||
// });
|
//);
|
||||||
|
// AssetImporter::importMesh(MeshImportArgs{
|
||||||
|
// .filePath = sourcePath / "import/models/city-suburbs/source/city-suburbs.obj",
|
||||||
|
// .importPath = "suburbs",
|
||||||
|
// });
|
||||||
vd->commitMeshes();
|
vd->commitMeshes();
|
||||||
WindowCreateInfo mainWindowInfo = {
|
WindowCreateInfo mainWindowInfo = {
|
||||||
.width = 1920,
|
.width = 1920,
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ void BasePass::beginFrame(const Component::Camera& cam) {
|
|||||||
opaqueCulling = lightCullingLayout->allocateDescriptorSet();
|
opaqueCulling = lightCullingLayout->allocateDescriptorSet();
|
||||||
transparentCulling = lightCullingLayout->allocateDescriptorSet();
|
transparentCulling = lightCullingLayout->allocateDescriptorSet();
|
||||||
|
|
||||||
waterRenderer->beginFrame();
|
//waterRenderer->beginFrame();
|
||||||
|
|
||||||
// Debug vertices
|
// Debug vertices
|
||||||
{
|
{
|
||||||
@@ -248,7 +248,7 @@ void BasePass::render() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
commands.add(waterRenderer->render(viewParamsSet));
|
//commands.add(waterRenderer->render(viewParamsSet));
|
||||||
|
|
||||||
// Skybox
|
// Skybox
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -344,23 +344,23 @@ WaterRenderer::WaterRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescri
|
|||||||
WaterRenderer::~WaterRenderer() {}
|
WaterRenderer::~WaterRenderer() {}
|
||||||
|
|
||||||
void WaterRenderer::beginFrame() {
|
void WaterRenderer::beginFrame() {
|
||||||
struct WaterPayload {
|
struct WaterTile {
|
||||||
Vector2 offset;
|
IVector2 offset;
|
||||||
float extent;
|
float extent;
|
||||||
float height;
|
float height;
|
||||||
};
|
};
|
||||||
Array<WaterPayload> payloads;
|
Array<WaterTile> payloads;
|
||||||
scene->view<Component::WaterTile>([&](Component::WaterTile& tile) {
|
scene->view<Component::WaterTile>([&](Component::WaterTile& tile) {
|
||||||
payloads.add(WaterPayload{
|
payloads.add(WaterTile{
|
||||||
.offset = Vector2(tile.location),
|
.offset = Vector2(tile.location),
|
||||||
.extent = 1,
|
.extent = Component::WaterTile::DIMENSIONS,
|
||||||
.height = tile.height,
|
.height = tile.height,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
waterTiles = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
waterTiles = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
.sourceData =
|
.sourceData =
|
||||||
{
|
{
|
||||||
.size = payloads.size() * sizeof(WaterPayload),
|
.size = payloads.size() * sizeof(WaterTile),
|
||||||
.data = (uint8*)payloads.data(),
|
.data = (uint8*)payloads.data(),
|
||||||
},
|
},
|
||||||
.numElements = payloads.size(),
|
.numElements = payloads.size(),
|
||||||
@@ -413,8 +413,6 @@ void WaterRenderer::beginFrame() {
|
|||||||
assembleCommand->dispatch(threadGroupsX, threadGroupsY, 1);
|
assembleCommand->dispatch(threadGroupsX, threadGroupsY, 1);
|
||||||
graphics->executeCommands(std::move(assembleCommand));
|
graphics->executeCommands(std::move(assembleCommand));
|
||||||
|
|
||||||
graphics->waitDeviceIdle();
|
|
||||||
|
|
||||||
// transition for mipmap gen
|
// transition for mipmap gen
|
||||||
displacementTextures->changeLayout(
|
displacementTextures->changeLayout(
|
||||||
Gfx::SE_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
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 =
|
.rasterizationState =
|
||||||
{
|
{
|
||||||
|
.polygonMode = Gfx::SE_POLYGON_MODE_LINE,
|
||||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||||
},
|
},
|
||||||
.colorBlend =
|
.colorBlend =
|
||||||
|
|||||||
Reference in New Issue
Block a user