Adding basic CBT Terrain implementation
This commit is contained in:
@@ -27,7 +27,6 @@ void Seele::addDebugVertices(Array<DebugVertex> verts) { gDebugVertices.addAll(v
|
||||
|
||||
BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics, scene) {
|
||||
//waterRenderer = new WaterRenderer(graphics, scene, viewParamsLayout);
|
||||
//terrainRenderer = new TerrainRenderer(graphics, scene, viewParamsLayout);
|
||||
basePassLayout = graphics->createPipelineLayout("BasePassLayout");
|
||||
|
||||
basePassLayout->addDescriptorLayout(viewParamsLayout);
|
||||
@@ -100,7 +99,7 @@ void BasePass::beginFrame(const Component::Camera& cam) {
|
||||
transparentCulling = lightCullingLayout->allocateDescriptorSet();
|
||||
|
||||
//waterRenderer->beginFrame();
|
||||
//terrainRenderer->beginFrame();
|
||||
terrainRenderer->beginFrame(viewParamsSet);
|
||||
|
||||
// Debug vertices
|
||||
{
|
||||
@@ -249,8 +248,8 @@ void BasePass::render() {
|
||||
}
|
||||
}
|
||||
|
||||
// commands.add(waterRenderer->render(viewParamsSet));
|
||||
// commands.add(terrainRenderer->render(viewParamsSet));
|
||||
//commands.add(waterRenderer->render(viewParamsSet));
|
||||
commands.add(terrainRenderer->render(viewParamsSet));
|
||||
|
||||
// Skybox
|
||||
{
|
||||
@@ -432,6 +431,8 @@ void BasePass::publishOutputs() {
|
||||
}
|
||||
|
||||
void BasePass::createRenderPass() {
|
||||
RenderPass::beginFrame(Component::Camera());
|
||||
terrainRenderer = new TerrainRenderer(graphics, scene, viewParamsLayout, viewParamsSet);
|
||||
cullingBuffer = resources->requestBuffer("CULLINGBUFFER");
|
||||
timestamps = resources->requestTimestampQuery("TIMESTAMPS");
|
||||
|
||||
@@ -474,7 +475,7 @@ void BasePass::createRenderPass() {
|
||||
tLightGrid = resources->requestTexture("LIGHTCULLING_TLIGHTGRID");
|
||||
|
||||
//waterRenderer->setViewport(viewport, renderPass);
|
||||
//terrainRenderer->setViewport(viewport, renderPass);
|
||||
terrainRenderer->setViewport(viewport, renderPass);
|
||||
|
||||
// Debug rendering
|
||||
{
|
||||
|
||||
@@ -51,7 +51,7 @@ class BasePass : public RenderPass {
|
||||
Gfx::PShaderBuffer cullingBuffer;
|
||||
|
||||
//OWaterRenderer waterRenderer;
|
||||
//OTerrainRenderer terrainRenderer;
|
||||
OTerrainRenderer terrainRenderer;
|
||||
|
||||
// Debug rendering
|
||||
Gfx::OVertexInput debugVertexInput;
|
||||
|
||||
@@ -31,13 +31,6 @@ class LightCullingPass : public RenderPass {
|
||||
glm::uvec3 numThreads;
|
||||
uint32_t pad1;
|
||||
} dispatchParams;
|
||||
struct Plane {
|
||||
Vector n;
|
||||
float d;
|
||||
};
|
||||
struct Frustum {
|
||||
Plane planes[4];
|
||||
};
|
||||
|
||||
Gfx::OShaderBuffer frustumBuffer;
|
||||
Gfx::OUniformBuffer dispatchParamsBuffer;
|
||||
|
||||
@@ -23,13 +23,18 @@ RenderPass::RenderPass(Gfx::PGraphics graphics, PScene scene) : graphics(graphic
|
||||
RenderPass::~RenderPass() {}
|
||||
|
||||
void RenderPass::beginFrame(const Component::Camera& cam) {
|
||||
auto screenDim = Vector2(static_cast<float>(viewport->getWidth()), static_cast<float>(viewport->getHeight()));
|
||||
viewParams = {
|
||||
.viewMatrix = cam.getViewMatrix(),
|
||||
.inverseViewMatrix = glm::inverse(cam.getViewMatrix()),
|
||||
.projectionMatrix = viewport->getProjectionMatrix(),
|
||||
.inverseProjection = glm::inverse(viewport->getProjectionMatrix()),
|
||||
.cameraPosition = Vector4(cam.getCameraPosition(), 1),
|
||||
.screenDimensions = Vector2(static_cast<float>(viewport->getWidth()), static_cast<float>(viewport->getHeight())),
|
||||
.cameraPosition_WS = Vector4(cam.getCameraPosition(), 1),
|
||||
.cameraForward_WS = Vector4(cam.getCameraForward(), 1),
|
||||
.screenDimensions = screenDim,
|
||||
.invScreenDimensions = 1.0f / screenDim,
|
||||
.frameIndex = Gfx::getCurrentFrameIndex(),
|
||||
.time = static_cast<float>(Gfx::getCurrentFrameTime()),
|
||||
};
|
||||
viewParamsBuffer->rotateBuffer(sizeof(ViewParameter));
|
||||
viewParamsBuffer->updateContents(0, sizeof(ViewParameter), &viewParams);
|
||||
|
||||
@@ -27,13 +27,25 @@ class RenderPass {
|
||||
void setViewport(Gfx::PViewport _viewport);
|
||||
|
||||
protected:
|
||||
struct Plane {
|
||||
Vector n;
|
||||
float d;
|
||||
};
|
||||
struct Frustum {
|
||||
Plane planes[4];
|
||||
};
|
||||
struct ViewParameter {
|
||||
Frustum viewFrustum;
|
||||
Matrix4 viewMatrix;
|
||||
Matrix4 inverseViewMatrix;
|
||||
Matrix4 projectionMatrix;
|
||||
Matrix4 inverseProjection;
|
||||
Vector4 cameraPosition;
|
||||
Vector4 cameraPosition_WS;
|
||||
Vector4 cameraForward_WS;
|
||||
Vector2 screenDimensions;
|
||||
Vector2 invScreenDimensions;
|
||||
uint32 frameIndex;
|
||||
float time;
|
||||
} viewParams;
|
||||
PRenderGraphResources resources;
|
||||
Gfx::ODescriptorLayout viewParamsLayout;
|
||||
|
||||
@@ -2,111 +2,298 @@
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Component/TerrainTile.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Pipeline.h"
|
||||
#include "Graphics/Shader.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescriptorLayout viewParamsLayout)
|
||||
TerrainRenderer::TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescriptorLayout viewParamsLayout,
|
||||
Gfx::PDescriptorSet viewParamsSet)
|
||||
: graphics(graphics), scene(scene) {
|
||||
struct TerrainTile {
|
||||
IVector2 offset;
|
||||
float extent;
|
||||
float height;
|
||||
};
|
||||
Array<TerrainTile> payloads;
|
||||
for (int32 y = -100; y < 100; ++y) {
|
||||
for (int32 x = -100; x < 100; ++x) {
|
||||
payloads.add(TerrainTile{
|
||||
.offset = IVector2(x, y),
|
||||
.extent = Component::TerrainTile::DIMENSIONS,
|
||||
.height = 0,
|
||||
});
|
||||
}
|
||||
meshUpdater.init(graphics, viewParamsLayout);
|
||||
lebCache.init(graphics, 5);
|
||||
CBT<21> cbt;
|
||||
CPUMesh cpuMesh = generateCPUMesh(cbt.numElements());
|
||||
plainMesh.gpuCBT.lastLevelSize = cbt.lastLevelSize();
|
||||
for (uint32 i = 0; i < 2; ++i) {
|
||||
uint32 bufferSize = cbt.bufferSize(i);
|
||||
uint32 elementSize = cbt.elementSize(i);
|
||||
plainMesh.gpuCBT.bufferArray[i] = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
.data = (uint8*)cbt.rawBuffer(i),
|
||||
},
|
||||
.name = "GPUCBT",
|
||||
});
|
||||
plainMesh.gpuCBT.bufferArray[i]->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
tilesBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
plainMesh.totalNumElements = cpuMesh.totalNumElements;
|
||||
plainMesh.numBaseVertices = (uint32)cpuMesh.basePoints.size();
|
||||
plainMesh.baseDepth = cpuMesh.minimalDepth;
|
||||
|
||||
plainMesh.heapIDBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(TerrainTile) * payloads.size(),
|
||||
.data = (uint8*)payloads.data(),
|
||||
.size = sizeof(uint64) * cpuMesh.totalNumElements,
|
||||
.data = (uint8*)cpuMesh.heapIDArray.data(),
|
||||
},
|
||||
.numElements = payloads.size(),
|
||||
.name = "TilesBuffer",
|
||||
.name = "HeapID",
|
||||
});
|
||||
tilesBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TASK_SHADER_BIT_EXT);
|
||||
colorMap = AssetRegistry::findTexture("", "azeroth")->getTexture();
|
||||
displacementMap = AssetRegistry::findTexture("", "azeroth_height")->getTexture();
|
||||
plainMesh.heapIDBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
sampler = graphics->createSampler(SamplerCreateInfo{});
|
||||
layout = graphics->createDescriptorLayout("pTerrainData");
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 0,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
plainMesh.currentNeighborsBufferIdx = 0;
|
||||
plainMesh.neighborsBuffers[0] = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(UVector4) * cpuMesh.totalNumElements,
|
||||
.data = (uint8*)cpuMesh.neighborsArray.data(),
|
||||
},
|
||||
.name = "Neighbours0",
|
||||
});
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 1,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
plainMesh.neighborsBuffers[0]->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
plainMesh.neighborsBuffers[1] = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(UVector4) * cpuMesh.totalNumElements,
|
||||
},
|
||||
.name = "Neighbours1",
|
||||
});
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 2,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
plainMesh.neighborsBuffers[1]->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
plainMesh.updateBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(BisectorData) * cpuMesh.totalNumElements,
|
||||
},
|
||||
.usage = Gfx::SE_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
|
||||
.name = "UpdateBuffer",
|
||||
});
|
||||
layout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.binding = 3,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
plainMesh.classificationBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * (2 + cpuMesh.totalNumElements * 2),
|
||||
},
|
||||
.name = "Classification",
|
||||
});
|
||||
layout->create();
|
||||
pipelineLayout = graphics->createPipelineLayout("TerrainLayout");
|
||||
pipelineLayout->addDescriptorLayout(viewParamsLayout);
|
||||
pipelineLayout->addDescriptorLayout(layout);
|
||||
ShaderCompilationInfo s{
|
||||
.name = "TerrainShaders",
|
||||
plainMesh.simplificationBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * (1 + cpuMesh.totalNumElements),
|
||||
},
|
||||
.name = "Simplification",
|
||||
});
|
||||
plainMesh.allocateBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * (1 + cpuMesh.totalNumElements),
|
||||
},
|
||||
.name = "Allocation",
|
||||
});
|
||||
plainMesh.propagateBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * (2 + cpuMesh.totalNumElements),
|
||||
},
|
||||
.name = "Propagate",
|
||||
});
|
||||
|
||||
plainMesh.indirectDrawBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * (4 * 2 + 2),
|
||||
},
|
||||
.usage = Gfx::SE_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
|
||||
.name = "IndirectDraw",
|
||||
});
|
||||
plainMesh.indirectDispatchBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * 3 * 3,
|
||||
},
|
||||
.usage = Gfx::SE_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
|
||||
.name = "IndirectDispatch",
|
||||
});
|
||||
plainMesh.indexedBisectorBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * cpuMesh.totalNumElements,
|
||||
},
|
||||
.name = "IndexedBisector",
|
||||
});
|
||||
plainMesh.visibleIndexedBisectorBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * cpuMesh.totalNumElements,
|
||||
},
|
||||
.name = "VisibleIndexedBisector",
|
||||
});
|
||||
plainMesh.modifiedIndexedBisectorBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * cpuMesh.totalNumElements,
|
||||
},
|
||||
.name = "ModifiedIndexedBisector",
|
||||
});
|
||||
|
||||
plainMesh.lebVertexBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(Vector4) * plainMesh.totalNumElements * 4,
|
||||
},
|
||||
.name = "LebVertexBuffer",
|
||||
});
|
||||
plainMesh.currentVertexBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(Vector4) * plainMesh.totalNumElements * 4,
|
||||
},
|
||||
.usage = Gfx::SE_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
|
||||
.name = "CurrentVertexBuffer",
|
||||
});
|
||||
plainMesh.currentDisplacementBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(Vector4) * plainMesh.totalNumElements * 3,
|
||||
},
|
||||
.name = "CurrentDisplacementBuffer",
|
||||
});
|
||||
uint32 numBaseVertex = (uint32)cpuMesh.basePoints.size();
|
||||
baseMesh.numVertices = numBaseVertex;
|
||||
baseMesh.numElements = numBaseVertex / 3;
|
||||
uint32 baseVertexBufferSize = sizeof(Vector4) * numBaseVertex;
|
||||
baseMesh.vertexBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = baseVertexBufferSize,
|
||||
.data = (uint8*)cpuMesh.basePoints.data(),
|
||||
},
|
||||
.name = "VertexBuffer",
|
||||
});
|
||||
baseMesh.vertexBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
uint32 indexBufferSize = cpuMesh.totalNumElements * sizeof(UVector);
|
||||
Array<uint32> indices;
|
||||
for (uint32 i = 0; i < cpuMesh.totalNumElements * 3; ++i)
|
||||
indices.add(i);
|
||||
baseMesh.indexBuffer = graphics->createIndexBuffer(IndexBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(uint32) * indices.size(),
|
||||
.data = (uint8*)indices.data(),
|
||||
},
|
||||
.indexType = Gfx::SE_INDEX_TYPE_UINT32,
|
||||
.name = "IndexBuffer",
|
||||
});
|
||||
baseMesh.indexBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT | Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
GeometryCB geometryCB = {
|
||||
.totalNumElements = plainMesh.totalNumElements,
|
||||
.baseDepth = plainMesh.baseDepth,
|
||||
.totalNumVertices = plainMesh.totalNumElements * 3,
|
||||
};
|
||||
geometryBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(GeometryCB),
|
||||
.data = (uint8*)&geometryCB,
|
||||
},
|
||||
.name = "GeometryCB",
|
||||
});
|
||||
geometryBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_UNIFORM_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
UpdateCB updateCB = {
|
||||
.triangleSize = 10.0f,
|
||||
.maxSubdivisionDepth = 63,
|
||||
.fov = 70.0f,
|
||||
.farPlaneDistance = 1000.0f,
|
||||
};
|
||||
updateBuffer = graphics->createUniformBuffer(UniformBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = sizeof(UpdateCB),
|
||||
.data = (uint8*)&updateCB,
|
||||
},
|
||||
.name = "UpdateCB",
|
||||
});
|
||||
updateBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_UNIFORM_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
meshUpdater.resetBuffers(plainMesh);
|
||||
meshUpdater.prepareIndirection(plainMesh, geometryBuffer);
|
||||
meshUpdater.evaluateLeb(baseMesh, plainMesh, viewParamsSet, geometryBuffer, updateBuffer, lebCache.getLebMatrixBuffer(), true, true);
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.modules = {"TerrainPass"},
|
||||
.entryPoints =
|
||||
{
|
||||
{"taskMain", "TerrainPass"},
|
||||
{"meshMain", "TerrainPass"},
|
||||
{"fragmentMain", "TerrainPass"},
|
||||
{"vert", "TerrainPass"},
|
||||
{"frag", "TerrainPass"},
|
||||
{"deform", "TerrainPass"},
|
||||
},
|
||||
.rootSignature = pipelineLayout,
|
||||
.dumpIntermediate = false,
|
||||
};
|
||||
graphics->beginShaderCompilation(s);
|
||||
task = graphics->createTaskShader({0});
|
||||
mesh = graphics->createMeshShader({1});
|
||||
frag = graphics->createFragmentShader({2});
|
||||
pipelineLayout->create();
|
||||
.rootSignature = meshUpdater.pipelineLayout,
|
||||
});
|
||||
vert = graphics->createVertexShader({0});
|
||||
frag = graphics->createFragmentShader({1});
|
||||
deformCS = graphics->createComputeShader({2});
|
||||
deform = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = deformCS,
|
||||
.pipelineLayout = meshUpdater.pipelineLayout,
|
||||
});
|
||||
}
|
||||
|
||||
TerrainRenderer::~TerrainRenderer() {}
|
||||
|
||||
void TerrainRenderer::beginFrame() {
|
||||
set = layout->allocateDescriptorSet();
|
||||
set->updateBuffer(0, 0, tilesBuffer);
|
||||
set->updateTexture(1, 0, displacementMap);
|
||||
set->updateTexture(2, 0, colorMap);
|
||||
set->updateSampler(3, 0, sampler);
|
||||
void TerrainRenderer::beginFrame(Gfx::PDescriptorSet viewParamsSet) {
|
||||
meshUpdater.update(plainMesh, viewParamsSet, geometryBuffer, updateBuffer);
|
||||
meshUpdater.evaluateLeb(baseMesh, plainMesh, viewParamsSet, geometryBuffer, updateBuffer, lebCache.getLebMatrixBuffer(), false, false);
|
||||
Gfx::PDescriptorSet set = meshUpdater.layout->allocateDescriptorSet();
|
||||
set->updateBuffer(GEOMETRY_CB, 0, geometryBuffer);
|
||||
set->updateBuffer(INDIRECT_DRAW_BUFFER, 0, plainMesh.indirectDrawBuffer);
|
||||
set->updateBuffer(INDEXED_BISECTOR_BUFFER, 0, plainMesh.indexedBisectorBuffer);
|
||||
set->updateBuffer(LEB_POSITION_BUFFER, 0, plainMesh.lebVertexBuffer);
|
||||
set->updateBuffer(CURRENT_VERTEX_BUFFER, 0, plainMesh.currentVertexBuffer);
|
||||
set->writeChanges();
|
||||
Gfx::OComputeCommand command = graphics->createComputeCommand("Deform");
|
||||
command->bindPipeline(deform);
|
||||
command->bindDescriptor({viewParamsSet, set});
|
||||
command->dispatchIndirect(plainMesh.indirectDispatchBuffer, 3 * sizeof(uint32));
|
||||
graphics->executeCommands(std::move(command));
|
||||
plainMesh.currentVertexBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_VERTEX_SHADER_BIT);
|
||||
}
|
||||
|
||||
Gfx::ORenderCommand TerrainRenderer::render(Gfx::PDescriptorSet viewParamsSet) {
|
||||
Gfx::PDescriptorSet set = meshUpdater.layout->allocateDescriptorSet();
|
||||
set->updateBuffer(CURRENT_VERTEX_BUFFER, 0, plainMesh.currentVertexBuffer);
|
||||
set->updateBuffer(INDEXED_BISECTOR_BUFFER, 0, plainMesh.indexedBisectorBuffer);
|
||||
set->writeChanges();
|
||||
Gfx::ORenderCommand command = graphics->createRenderCommand("TerrainRender");
|
||||
command->setViewport(viewport);
|
||||
command->bindPipeline(pipeline);
|
||||
command->bindDescriptor({viewParamsSet, set});
|
||||
command->drawMesh(tilesBuffer->getNumElements(), 4, 1);
|
||||
command->drawIndirect(plainMesh.indirectDrawBuffer, 0, 1, 0);
|
||||
return command;
|
||||
}
|
||||
|
||||
void TerrainRenderer::setViewport(Gfx::PViewport _viewport, Gfx::PRenderPass renderPass) {
|
||||
viewport = _viewport;
|
||||
|
||||
Gfx::MeshPipelineCreateInfo pipelineInfo = {
|
||||
.taskShader = task,
|
||||
.meshShader = mesh,
|
||||
inp = graphics->createVertexInput({});
|
||||
Gfx::LegacyPipelineCreateInfo pipelineInfo = {
|
||||
.vertexInput = inp,
|
||||
.vertexShader = vert,
|
||||
.fragmentShader = frag,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = pipelineLayout,
|
||||
.pipelineLayout = meshUpdater.pipelineLayout,
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = viewport->getSamples(),
|
||||
@@ -128,4 +315,4 @@ void TerrainRenderer::setViewport(Gfx::PViewport _viewport, Gfx::PRenderPass ren
|
||||
},
|
||||
};
|
||||
pipeline = graphics->createGraphicsPipeline(std::move(pipelineInfo));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
#pragma once
|
||||
#include "RenderPass.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/CBT/CBT.h"
|
||||
|
||||
namespace Seele {
|
||||
class TerrainRenderer {
|
||||
public:
|
||||
TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescriptorLayout viewParamsLayout);
|
||||
TerrainRenderer(Gfx::PGraphics graphics, PScene scene, Gfx::PDescriptorLayout viewParamsLayout, Gfx::PDescriptorSet viewParamsSet);
|
||||
~TerrainRenderer();
|
||||
void beginFrame();
|
||||
void beginFrame(Gfx::PDescriptorSet viewParamsSet);
|
||||
Gfx::ORenderCommand render(Gfx::PDescriptorSet viewParamsSet);
|
||||
void setViewport(Gfx::PViewport viewport, Gfx::PRenderPass renderPass);
|
||||
|
||||
@@ -18,13 +20,24 @@ class TerrainRenderer {
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::OTaskShader task;
|
||||
Gfx::OMeshShader mesh;
|
||||
Gfx::OVertexInput inp;
|
||||
Gfx::OVertexShader vert;
|
||||
Gfx::OFragmentShader frag;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
Gfx::OComputeShader deformCS;
|
||||
Gfx::PComputePipeline deform;
|
||||
Gfx::PViewport viewport;
|
||||
Gfx::OShaderBuffer tilesBuffer;
|
||||
Gfx::PTexture2D displacementMap;
|
||||
Gfx::PTexture2D colorMap;
|
||||
Gfx::OSampler sampler;
|
||||
|
||||
Gfx::OUniformBuffer geometryBuffer;
|
||||
Gfx::OUniformBuffer updateBuffer;
|
||||
BaseMesh baseMesh;
|
||||
CBTMesh plainMesh;
|
||||
MeshUpdater meshUpdater;
|
||||
LebMatrixCache lebCache;
|
||||
};
|
||||
DEFINE_REF(TerrainRenderer);
|
||||
}
|
||||
} // namespace Seele
|
||||
Reference in New Issue
Block a user