Initial commit
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
target_sources(FluidSimulation
|
||||
PRIVATE
|
||||
SimulationComputePass.h
|
||||
SimulationComputePass.cpp
|
||||
FluidRenderPass.h
|
||||
FluidRenderPass.cpp
|
||||
FluidSimulationView.h
|
||||
FluidSimulationView.cpp
|
||||
main.cpp)
|
||||
@@ -0,0 +1,122 @@
|
||||
#include "FluidRenderPass.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics/Shader.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
FluidRenderPass::FluidRenderPass(Seele::Gfx::PGraphics graphics) : RenderPass(graphics) {
|
||||
pipelineLayout = graphics->createPipelineLayout("FluidPipelineLayout");
|
||||
descriptorLayout = graphics->createDescriptorLayout("params");
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "density",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->create();
|
||||
pipelineLayout->addDescriptorLayout(descriptorLayout);
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "Fluid",
|
||||
.modules = {"Render"},
|
||||
.entryPoints = {{"vertexMain", "Render"}, {"fragmentMain", "Render"}},
|
||||
.rootSignature = pipelineLayout,
|
||||
.dumpIntermediate = true,
|
||||
});
|
||||
pipelineLayout->create();
|
||||
vertexShader = graphics->createVertexShader({0});
|
||||
fragmentShader = graphics->createFragmentShader({1});
|
||||
}
|
||||
|
||||
FluidRenderPass::~FluidRenderPass() {}
|
||||
|
||||
void FluidRenderPass::beginFrame(const Seele::Component::Camera &camera, const Seele::Component::Transform &transform) {
|
||||
updateViewParameters(camera, transform);
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer("density", 0, densityBuffer);
|
||||
descriptorSet->writeChanges();
|
||||
}
|
||||
|
||||
void FluidRenderPass::render() {
|
||||
graphics->beginRenderPass(renderPass);
|
||||
graphics->endRenderPass();
|
||||
}
|
||||
|
||||
void FluidRenderPass::endFrame() {}
|
||||
|
||||
void FluidRenderPass::publishOutputs() {
|
||||
depthTexture = graphics->createTexture2D(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = viewport->getWidth(),
|
||||
.height = viewport->getHeight(),
|
||||
.name = "FluidDepth",
|
||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
});
|
||||
}
|
||||
|
||||
void FluidRenderPass::createRenderPass() {
|
||||
densityBuffer = resources->requestBuffer("DENSITY");
|
||||
colorAttachment = Gfx::RenderTargetAttachment(viewport->getOwner()->getBackBuffer()->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||
Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||
depthAttachment = Gfx::RenderTargetAttachment(depthTexture->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||
Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||
depthAttachment.clear.depthStencil.depth = 0.0f;
|
||||
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||
.colorAttachments = {colorAttachment},
|
||||
.depthAttachment = depthAttachment,
|
||||
};
|
||||
Array<Gfx::SubPassDependency> dependency = {
|
||||
{
|
||||
.srcSubpass = ~0U,
|
||||
.dstSubpass = 0,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
{
|
||||
.srcSubpass = 0,
|
||||
.dstSubpass = ~0U,
|
||||
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
},
|
||||
};
|
||||
renderPass = graphics->createRenderPass(layout, dependency, viewport->getRenderArea(), "FluidRenderPass");
|
||||
pipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
|
||||
.vertexShader = vertexShader,
|
||||
.fragmentShader = fragmentShader,
|
||||
.renderPass = renderPass,
|
||||
.pipelineLayout = pipelineLayout,
|
||||
.multisampleState =
|
||||
{
|
||||
.samples = Gfx::SE_SAMPLE_COUNT_1_BIT,
|
||||
},
|
||||
.rasterizationState =
|
||||
{
|
||||
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
.blendAttachments =
|
||||
{
|
||||
Gfx::ColorBlendState::BlendAttachment{
|
||||
.blendEnable = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
#include "Component/Transform.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/RenderPass/RenderPass.h"
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
class FluidRenderPass : public Seele::RenderPass {
|
||||
public:
|
||||
FluidRenderPass(Seele::Gfx::PGraphics graphics);
|
||||
virtual ~FluidRenderPass() override;
|
||||
|
||||
virtual void beginFrame(const Seele::Component::Camera &camera, const Seele::Component::Transform &transform) override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
|
||||
private:
|
||||
Seele::Gfx::RenderTargetAttachment colorAttachment;
|
||||
Seele::Gfx::RenderTargetAttachment depthAttachment;
|
||||
Seele::Gfx::OTexture2D depthTexture;
|
||||
|
||||
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||
Seele::Gfx::ODescriptorSet descriptorSet;
|
||||
Seele::Gfx::OVertexShader vertexShader;
|
||||
Seele::Gfx::OFragmentShader fragmentShader;
|
||||
Seele::Gfx::PGraphicsPipeline pipeline;
|
||||
|
||||
Seele::Gfx::PShaderBuffer densityBuffer;
|
||||
};
|
||||
DEFINE_REF(FluidRenderPass)
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "FluidSimulationView.h"
|
||||
#include "FluidRenderPass.h"
|
||||
#include "SimulationComputePass.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
FluidSimulationView::FluidSimulationView(Gfx::PGraphics graphics, Seele::PWindow window, const Seele::ViewportCreateInfo &createInfo)
|
||||
: View(graphics, window, createInfo, "Fluid Simulation View") {
|
||||
camera = Component::Camera{};
|
||||
transform = Component::Transform{
|
||||
.transform = Math::Transform({0.0f, 0.0f, -5.0f}),
|
||||
};
|
||||
renderGraph.addPass(new SimulationComputePass(graphics));
|
||||
renderGraph.addPass(new FluidRenderPass(graphics));
|
||||
renderGraph.setViewport(viewport);
|
||||
renderGraph.createRenderPass();
|
||||
}
|
||||
|
||||
FluidSimulationView::~FluidSimulationView() {}
|
||||
|
||||
void FluidSimulationView::beginUpdate() {}
|
||||
|
||||
void FluidSimulationView::update() {}
|
||||
|
||||
void FluidSimulationView::commitUpdate() {}
|
||||
|
||||
void FluidSimulationView::prepareRender() {}
|
||||
|
||||
void FluidSimulationView::render() { renderGraph.render(camera, transform); }
|
||||
|
||||
void FluidSimulationView::applyArea(Seele::URect area) {}
|
||||
void FluidSimulationView::keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) {}
|
||||
void FluidSimulationView::mouseMoveCallback(double xPos, double yPos) {}
|
||||
void FluidSimulationView::mouseButtonCallback(Seele::MouseButton button, Seele::InputAction action, Seele::KeyModifier modifier) {}
|
||||
void FluidSimulationView::scrollCallback(double xOffset, double yOffset) {}
|
||||
void FluidSimulationView::fileCallback(int count, const char **paths) {}
|
||||
@@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/RenderPass/RenderGraph.h"
|
||||
#include "Window/View.h"
|
||||
|
||||
class FluidSimulationView : public Seele::View {
|
||||
public:
|
||||
FluidSimulationView(Seele::Gfx::PGraphics graphics, Seele::PWindow window, const Seele::ViewportCreateInfo &createInfo);
|
||||
~FluidSimulationView() override;
|
||||
|
||||
virtual void beginUpdate() override;
|
||||
virtual void update() override;
|
||||
virtual void commitUpdate() override;
|
||||
|
||||
virtual void prepareRender() override;
|
||||
virtual void render() override;
|
||||
|
||||
protected:
|
||||
virtual void applyArea(Seele::URect area) override;
|
||||
virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
||||
virtual void mouseMoveCallback(double xPos, double yPos) override;
|
||||
virtual void mouseButtonCallback(Seele::MouseButton button, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
||||
virtual void scrollCallback(double xOffset, double yOffset) override;
|
||||
virtual void fileCallback(int count, const char **paths) override;
|
||||
|
||||
private:
|
||||
Seele::Component::Camera camera;
|
||||
Seele::Component::Transform transform;
|
||||
Seele::RenderGraph renderGraph;
|
||||
};
|
||||
@@ -0,0 +1,487 @@
|
||||
#include "SimulationComputePass.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Shader.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
#define SWAP(a, b) \
|
||||
{ \
|
||||
auto temp = std::move(a); \
|
||||
a = std::move(b); \
|
||||
b = std::move(temp); \
|
||||
}
|
||||
|
||||
SimulationComputePass::SimulationComputePass(Seele::Gfx::PGraphics graphics) : RenderPass(graphics) {
|
||||
{
|
||||
setBounds.pipelineLayout = graphics->createPipelineLayout("SetBoundsPipelineLayout");
|
||||
setBounds.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||
setBounds.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "b",
|
||||
.uniformLength = sizeof(int),
|
||||
});
|
||||
setBounds.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "grid",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
setBounds.descriptorLayout->create();
|
||||
setBounds.pipelineLayout->addDescriptorLayout(setBounds.descriptorLayout);
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "SetBound",
|
||||
.modules = {"SetBound"},
|
||||
.entryPoints = {{"setBound", "SetBound"}, {"setBoundEdges", "SetBound"}, {"setBoundCorners", "SetBound"}},
|
||||
.rootSignature = setBounds.pipelineLayout,
|
||||
});
|
||||
setBounds.pipelineLayout->create();
|
||||
setBounds.shader = graphics->createComputeShader({0});
|
||||
setBounds.shaderEdges = graphics->createComputeShader({1});
|
||||
setBounds.shaderCorners = graphics->createComputeShader({2});
|
||||
setBounds.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = setBounds.shader,
|
||||
.pipelineLayout = setBounds.pipelineLayout,
|
||||
});
|
||||
setBounds.pipelineEdges = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = setBounds.shaderEdges,
|
||||
.pipelineLayout = setBounds.pipelineLayout,
|
||||
});
|
||||
setBounds.pipelineCorners = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = setBounds.shaderCorners,
|
||||
.pipelineLayout = setBounds.pipelineLayout,
|
||||
});
|
||||
}
|
||||
{
|
||||
linearSolve.pipelineLayout = graphics->createPipelineLayout("LinearSolvePipelineLayout");
|
||||
linearSolve.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "a",
|
||||
.uniformLength = sizeof(float),
|
||||
});
|
||||
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "c",
|
||||
.uniformLength = sizeof(float),
|
||||
});
|
||||
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "next",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "current",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "grid0",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
linearSolve.descriptorLayout->create();
|
||||
linearSolve.pipelineLayout->addDescriptorLayout(linearSolve.descriptorLayout);
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "LinearSolve",
|
||||
.modules = {"LinearSolve"},
|
||||
.entryPoints = {{"linearSolve", "LinearSolve"}},
|
||||
.rootSignature = linearSolve.pipelineLayout,
|
||||
});
|
||||
linearSolve.pipelineLayout->create();
|
||||
linearSolve.shader = graphics->createComputeShader({0});
|
||||
linearSolve.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = linearSolve.shader,
|
||||
.pipelineLayout = linearSolve.pipelineLayout,
|
||||
});
|
||||
}
|
||||
{
|
||||
computeDivergence.pipelineLayout = graphics->createPipelineLayout("ComputeDivergencePipelineLayout");
|
||||
computeDivergence.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "velocityX",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "velocityY",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "velocityZ",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "divergence",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "pressure",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
computeDivergence.descriptorLayout->create();
|
||||
computeDivergence.pipelineLayout->addDescriptorLayout(computeDivergence.descriptorLayout);
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "Divergence",
|
||||
.modules = {"Divergence"},
|
||||
.entryPoints = {{"computeDivergence", "Divergence"}},
|
||||
.rootSignature = computeDivergence.pipelineLayout,
|
||||
});
|
||||
computeDivergence.pipelineLayout->create();
|
||||
|
||||
computeDivergence.shader = graphics->createComputeShader({0});
|
||||
computeDivergence.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = computeDivergence.shader,
|
||||
.pipelineLayout = computeDivergence.pipelineLayout,
|
||||
});
|
||||
}
|
||||
{
|
||||
project.pipelineLayout = graphics->createPipelineLayout("ProjectPipelineLayout");
|
||||
project.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||
project.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "velocityX",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
project.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "velocityY",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
project.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "velocityZ",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
project.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "pressure",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
project.descriptorLayout->create();
|
||||
project.pipelineLayout->addDescriptorLayout(project.descriptorLayout);
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "Project",
|
||||
.modules = {"Project"},
|
||||
.entryPoints = {{"project", "Project"}},
|
||||
.rootSignature = project.pipelineLayout,
|
||||
});
|
||||
project.pipelineLayout->create();
|
||||
project.shader = graphics->createComputeShader({0});
|
||||
project.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = project.shader,
|
||||
.pipelineLayout = project.pipelineLayout,
|
||||
});
|
||||
}
|
||||
{
|
||||
advect.pipelineLayout = graphics->createPipelineLayout("AdvectPipelineLayout");
|
||||
advect.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "density",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "density0",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "velocityX",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "velocityY",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "velocityZ",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "dt",
|
||||
.uniformLength = sizeof(float),
|
||||
});
|
||||
advect.descriptorLayout->create();
|
||||
advect.pipelineLayout->addDescriptorLayout(advect.descriptorLayout);
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "Advect",
|
||||
.modules = {"Advect"},
|
||||
.entryPoints = {{"advect", "Advect"}},
|
||||
.rootSignature = advect.pipelineLayout,
|
||||
});
|
||||
advect.pipelineLayout->create();
|
||||
|
||||
advect.shader = graphics->createComputeShader({0});
|
||||
advect.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = advect.shader,
|
||||
.pipelineLayout = advect.pipelineLayout,
|
||||
});
|
||||
}
|
||||
|
||||
uint64_t bufferSize = gridSize * gridSize * gridSize * sizeof(float);
|
||||
densityBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "DensityBuffer",
|
||||
});
|
||||
scratchBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "Density0Buffer",
|
||||
});
|
||||
velocityXNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityXNextBuffer",
|
||||
});
|
||||
velocityYNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityYNextBuffer",
|
||||
});
|
||||
velocityZNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityZNextBuffer",
|
||||
});
|
||||
velocityXBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityXBuffer",
|
||||
});
|
||||
velocityYBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityYBuffer",
|
||||
});
|
||||
velocityZBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityZBuffer",
|
||||
});
|
||||
velocityX0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityX0Buffer",
|
||||
});
|
||||
velocityY0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityY0Buffer",
|
||||
});
|
||||
velocityZ0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityZ0Buffer",
|
||||
});
|
||||
}
|
||||
|
||||
SimulationComputePass::~SimulationComputePass() {}
|
||||
|
||||
void SimulationComputePass::beginFrame(const Seele::Component::Camera &camera, const Seele::Component::Transform &transform) {
|
||||
setBounds.descriptorLayout->reset();
|
||||
linearSolve.descriptorLayout->reset();
|
||||
computeDivergence.descriptorLayout->reset();
|
||||
project.descriptorLayout->reset();
|
||||
advect.descriptorLayout->reset();
|
||||
}
|
||||
|
||||
void SimulationComputePass::render() {
|
||||
for (uint iteration = 0; iteration < 4; ++iteration) {
|
||||
float a = dt * viscosity * (gridSize - 2) * (gridSize - 2) * (gridSize - 2);
|
||||
float c = 1 + 6 * a;
|
||||
linearSolvePass(velocityXNextBuffer, velocityXBuffer, velocityX0Buffer, a, c);
|
||||
linearSolvePass(velocityYNextBuffer, velocityYBuffer, velocityY0Buffer, a, c);
|
||||
linearSolvePass(velocityZNextBuffer, velocityZBuffer, velocityZ0Buffer, a, c);
|
||||
|
||||
setBoundsPass(velocityXNextBuffer, 1);
|
||||
setBoundsPass(velocityYNextBuffer, 2);
|
||||
setBoundsPass(velocityZNextBuffer, 3);
|
||||
|
||||
SWAP(velocityXBuffer, velocityXNextBuffer);
|
||||
SWAP(velocityYBuffer, velocityYNextBuffer);
|
||||
SWAP(velocityZBuffer, velocityZNextBuffer);
|
||||
}
|
||||
|
||||
SWAP(velocityX0Buffer, velocityXBuffer);
|
||||
SWAP(velocityY0Buffer, velocityYBuffer);
|
||||
SWAP(velocityZ0Buffer, velocityZBuffer);
|
||||
|
||||
Gfx::PShaderBuffer divergence = velocityXBuffer;
|
||||
Gfx::PShaderBuffer pressureCurrent = velocityYBuffer;
|
||||
Gfx::PShaderBuffer pressureNext = velocityZBuffer;
|
||||
divergencePass(divergence, pressureCurrent, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer);
|
||||
|
||||
for (int iteration = 0; iteration < 4; ++iteration) {
|
||||
linearSolvePass(pressureNext, pressureCurrent, divergence, 1, 6);
|
||||
|
||||
setBoundsPass(pressureNext, 0);
|
||||
|
||||
// swap pressure buffers
|
||||
SWAP(pressureCurrent, pressureNext);
|
||||
}
|
||||
|
||||
projectPass(velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, pressureCurrent);
|
||||
|
||||
setBoundsPass(velocityX0Buffer, 1);
|
||||
setBoundsPass(velocityY0Buffer, 2);
|
||||
setBoundsPass(velocityZ0Buffer, 3);
|
||||
|
||||
advectPass(velocityXBuffer, velocityX0Buffer, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, dt);
|
||||
advectPass(velocityYBuffer, velocityY0Buffer, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, dt);
|
||||
advectPass(velocityZBuffer, velocityZ0Buffer, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, dt);
|
||||
|
||||
setBoundsPass(velocityXBuffer, 1);
|
||||
setBoundsPass(velocityYBuffer, 2);
|
||||
setBoundsPass(velocityZBuffer, 3);
|
||||
|
||||
// swap velocity buffers
|
||||
SWAP(velocityX0Buffer, velocityXBuffer);
|
||||
SWAP(velocityY0Buffer, velocityYBuffer);
|
||||
SWAP(velocityZ0Buffer, velocityZBuffer);
|
||||
|
||||
// diffuse density
|
||||
for (int iteration = 0; iteration < 4; ++iteration) {
|
||||
float a = dt * diffusion * (gridSize - 2) * (gridSize - 2) * (gridSize - 2);
|
||||
float c = 1 + 6 * a;
|
||||
linearSolvePass(scratchBuffer, densityBuffer, densityBuffer, a, c);
|
||||
setBoundsPass(scratchBuffer, 0);
|
||||
}
|
||||
advectPass(densityBuffer, scratchBuffer, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, dt);
|
||||
setBoundsPass(densityBuffer, 0);
|
||||
}
|
||||
|
||||
void SimulationComputePass::endFrame() {}
|
||||
|
||||
void SimulationComputePass::publishOutputs() { resources->registerBufferOutput("DENSITY", densityBuffer); }
|
||||
|
||||
void SimulationComputePass::createRenderPass() {}
|
||||
|
||||
void SimulationComputePass::setBoundsPass(Gfx::PShaderBuffer grid, int b) {
|
||||
Gfx::ODescriptorSet bounds = setBounds.descriptorLayout->allocateDescriptorSet();
|
||||
bounds->updateConstants("b", 0, &b);
|
||||
bounds->updateBuffer("grid", 0, grid);
|
||||
bounds->writeChanges();
|
||||
Gfx::OComputeCommand boundsCommand = graphics->createComputeCommand();
|
||||
boundsCommand->bindPipeline(setBounds.pipeline);
|
||||
boundsCommand->bindDescriptor(bounds);
|
||||
boundsCommand->dispatch(gridSize / setBounds.threadGroupSize.x, gridSize / setBounds.threadGroupSize.y, 1);
|
||||
graphics->executeCommands(std::move(boundsCommand));
|
||||
|
||||
grid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
Gfx::OComputeCommand edgesCommand = graphics->createComputeCommand();
|
||||
edgesCommand->bindPipeline(setBounds.pipelineEdges);
|
||||
edgesCommand->bindDescriptor(bounds);
|
||||
edgesCommand->dispatch(gridSize / setBounds.threadGroupSize.x, 1, 1);
|
||||
graphics->executeCommands(std::move(edgesCommand));
|
||||
|
||||
grid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
Gfx::OComputeCommand cornersCommand = graphics->createComputeCommand();
|
||||
cornersCommand->bindPipeline(setBounds.pipelineCorners);
|
||||
cornersCommand->bindDescriptor(bounds);
|
||||
cornersCommand->dispatch(1, 1, 1);
|
||||
graphics->executeCommands(std::move(cornersCommand));
|
||||
|
||||
grid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
|
||||
void SimulationComputePass::linearSolvePass(Gfx::PShaderBuffer current, Gfx::PShaderBuffer next, Gfx::PShaderBuffer grid0, float a,
|
||||
float c) {
|
||||
Gfx::ODescriptorSet solve = linearSolve.descriptorLayout->allocateDescriptorSet();
|
||||
solve->updateBuffer("grid0", 0, grid0);
|
||||
solve->updateBuffer("current", 0, current);
|
||||
solve->updateBuffer("next", 0, next);
|
||||
solve->updateConstants("a", 0, &a);
|
||||
solve->updateConstants("c", 0, &c);
|
||||
solve->writeChanges();
|
||||
Gfx::OComputeCommand solveCommand = graphics->createComputeCommand();
|
||||
solveCommand->bindPipeline(linearSolve.pipeline);
|
||||
solveCommand->bindDescriptor(solve);
|
||||
solveCommand->dispatch(gridSize / linearSolve.threadGroupSize.x, gridSize / linearSolve.threadGroupSize.y,
|
||||
gridSize / linearSolve.threadGroupSize.z);
|
||||
graphics->executeCommands(std::move(solveCommand));
|
||||
|
||||
next->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
void SimulationComputePass::divergencePass(Seele::Gfx::PShaderBuffer divergence, Seele::Gfx::PShaderBuffer pressure,
|
||||
Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY,
|
||||
Seele::Gfx::PShaderBuffer velocityZ) {
|
||||
Gfx::ODescriptorSet divergenceSet = computeDivergence.descriptorLayout->allocateDescriptorSet();
|
||||
divergenceSet->updateBuffer("velocityX", 0, velocityX);
|
||||
divergenceSet->updateBuffer("velocityY", 0, velocityY);
|
||||
divergenceSet->updateBuffer("velocityZ", 0, velocityZ);
|
||||
divergenceSet->updateBuffer("divergence", 0, divergence);
|
||||
divergenceSet->updateBuffer("pressure", 0, pressure);
|
||||
divergenceSet->writeChanges();
|
||||
Gfx::OComputeCommand divergenceCommand = graphics->createComputeCommand();
|
||||
divergenceCommand->bindPipeline(computeDivergence.pipeline);
|
||||
divergenceCommand->bindDescriptor(divergenceSet);
|
||||
divergenceCommand->dispatch(gridSize / computeDivergence.threadGroupSize.x, gridSize / computeDivergence.threadGroupSize.y,
|
||||
gridSize / computeDivergence.threadGroupSize.z);
|
||||
graphics->executeCommands(std::move(divergenceCommand));
|
||||
// divergence is now in velocityXBuffer, pressure is in velocityYBuffer
|
||||
divergence->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
pressure->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
|
||||
void SimulationComputePass::projectPass(Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY,
|
||||
Seele::Gfx::PShaderBuffer velocityZ, Seele::Gfx::PShaderBuffer pressure) {
|
||||
Gfx::ODescriptorSet projectSet = project.descriptorLayout->allocateDescriptorSet();
|
||||
projectSet->updateBuffer("velocityX", 0, velocityX);
|
||||
projectSet->updateBuffer("velocityY", 0, velocityY);
|
||||
projectSet->updateBuffer("velocityZ", 0, velocityZ);
|
||||
projectSet->updateBuffer("pressure", 0, pressure);
|
||||
projectSet->writeChanges();
|
||||
Gfx::OComputeCommand projectCommand = graphics->createComputeCommand();
|
||||
projectCommand->bindPipeline(project.pipeline);
|
||||
projectCommand->bindDescriptor(projectSet);
|
||||
projectCommand->dispatch(gridSize / project.threadGroupSize.x, gridSize / project.threadGroupSize.y,
|
||||
gridSize / project.threadGroupSize.z);
|
||||
graphics->executeCommands(std::move(projectCommand));
|
||||
|
||||
velocityX->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
velocityY->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
velocityZ->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
|
||||
void SimulationComputePass::advectPass(Gfx::PShaderBuffer quantity, Gfx::PShaderBuffer quantity0, Gfx::PShaderBuffer velocityX,
|
||||
Gfx::PShaderBuffer velocityY, Gfx::PShaderBuffer velocityZ, float dt) {
|
||||
Gfx::ODescriptorSet advectSet = this->advect.descriptorLayout->allocateDescriptorSet();
|
||||
advectSet->updateBuffer("density", 0, quantity);
|
||||
advectSet->updateBuffer("density0", 0, quantity0);
|
||||
advectSet->updateBuffer("velocityX", 0, velocityX);
|
||||
advectSet->updateBuffer("velocityY", 0, velocityY);
|
||||
advectSet->updateBuffer("velocityZ", 0, velocityZ);
|
||||
advectSet->updateConstants("dt", 0, &dt);
|
||||
advectSet->writeChanges();
|
||||
Gfx::OComputeCommand advectCommand = graphics->createComputeCommand();
|
||||
advectCommand->bindPipeline(advect.pipeline);
|
||||
advectCommand->bindDescriptor(advectSet);
|
||||
advectCommand->dispatch(gridSize / advect.threadGroupSize.x, gridSize / advect.threadGroupSize.y, gridSize / advect.threadGroupSize.z);
|
||||
graphics->executeCommands(std::move(advectCommand));
|
||||
|
||||
quantity->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
#pragma once
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/RenderPass/RenderPass.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include <sys/types.h>
|
||||
|
||||
class SimulationComputePass : public Seele::RenderPass {
|
||||
public:
|
||||
SimulationComputePass(Seele::Gfx::PGraphics graphics);
|
||||
virtual ~SimulationComputePass() override;
|
||||
virtual void beginFrame(const Seele::Component::Camera &camera, const Seele::Component::Transform &transform) override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
|
||||
private:
|
||||
void setBoundsPass(Seele::Gfx::PShaderBuffer buffer, int b);
|
||||
void linearSolvePass(Seele::Gfx::PShaderBuffer next, Seele::Gfx::PShaderBuffer current, Seele::Gfx::PShaderBuffer grid0, float a, float c);
|
||||
void divergencePass(Seele::Gfx::PShaderBuffer divergence, Seele::Gfx::PShaderBuffer pressure, Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY, Seele::Gfx::PShaderBuffer velocityZ);
|
||||
void projectPass(Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY, Seele::Gfx::PShaderBuffer velocityZ, Seele::Gfx::PShaderBuffer pressure);
|
||||
void advectPass(Seele::Gfx::PShaderBuffer quantity, Seele::Gfx::PShaderBuffer quantity0, Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY, Seele::Gfx::PShaderBuffer velocityZ, float dt);
|
||||
float viscosity = 0.001f;
|
||||
float diffusion = 0.0001f;
|
||||
float dt = 0.1f;
|
||||
constexpr static uint gridSize = 128;
|
||||
struct SetBounds
|
||||
{
|
||||
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||
Seele::Gfx::OComputeShader shader;
|
||||
Seele::Gfx::PComputePipeline pipeline;
|
||||
Seele::Gfx::OComputeShader shaderEdges;
|
||||
Seele::Gfx::PComputePipeline pipelineEdges;
|
||||
Seele::Gfx::OComputeShader shaderCorners;
|
||||
Seele::Gfx::PComputePipeline pipelineCorners;
|
||||
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||
} setBounds;
|
||||
struct LinearSolve
|
||||
{
|
||||
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||
Seele::Gfx::OComputeShader shader;
|
||||
Seele::Gfx::PComputePipeline pipeline;
|
||||
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||
} linearSolve;
|
||||
struct ComputeDivergence
|
||||
{
|
||||
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||
Seele::Gfx::OComputeShader shader;
|
||||
Seele::Gfx::PComputePipeline pipeline;
|
||||
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||
} computeDivergence;
|
||||
struct Project
|
||||
{
|
||||
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||
Seele::Gfx::OComputeShader shader;
|
||||
Seele::Gfx::PComputePipeline pipeline;
|
||||
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||
} project;
|
||||
struct Advect
|
||||
{
|
||||
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||
Seele::Gfx::OComputeShader shader;
|
||||
Seele::Gfx::PComputePipeline pipeline;
|
||||
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||
} advect;
|
||||
Seele::Gfx::OShaderBuffer densityBuffer;
|
||||
Seele::Gfx::OShaderBuffer scratchBuffer;
|
||||
Seele::Gfx::OShaderBuffer velocityXNextBuffer;
|
||||
Seele::Gfx::OShaderBuffer velocityYNextBuffer;
|
||||
Seele::Gfx::OShaderBuffer velocityZNextBuffer;
|
||||
Seele::Gfx::OShaderBuffer velocityXBuffer;
|
||||
Seele::Gfx::OShaderBuffer velocityYBuffer;
|
||||
Seele::Gfx::OShaderBuffer velocityZBuffer;
|
||||
Seele::Gfx::OShaderBuffer velocityX0Buffer;
|
||||
Seele::Gfx::OShaderBuffer velocityY0Buffer;
|
||||
Seele::Gfx::OShaderBuffer velocityZ0Buffer;
|
||||
};
|
||||
DEFINE_REF(SimulationComputePass)
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "FluidSimulationView.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/Vulkan/Graphics.h"
|
||||
#include "Window/WindowManager.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
int main() {
|
||||
Gfx::OGraphics graphics = new Vulkan::Graphics();
|
||||
graphics->init(GraphicsInitializer());
|
||||
OWindowManager windowManager = new WindowManager();
|
||||
auto window = windowManager->addWindow(graphics, WindowCreateInfo{
|
||||
.title = "Seele Fluid Simulation",
|
||||
.width = 1280,
|
||||
.height = 720,
|
||||
});
|
||||
auto view = new FluidSimulationView(graphics, window,
|
||||
ViewportCreateInfo{
|
||||
.dimensions =
|
||||
{
|
||||
.size =
|
||||
{
|
||||
1280,
|
||||
720,
|
||||
},
|
||||
},
|
||||
});
|
||||
view->setFocused();
|
||||
window->show();
|
||||
while(!window->shouldClose()) {
|
||||
windowManager->render();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user