Trying to add fluid simulation
This commit is contained in:
@@ -78,5 +78,3 @@ void PlayView::render() {
|
||||
GameView::render();
|
||||
renderTimestamp->write(Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT, "RenderEnd");
|
||||
}
|
||||
|
||||
void PlayView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier) { GameView::keyCallback(code, action, modifier); }
|
||||
|
||||
@@ -12,8 +12,6 @@ class PlayView : public GameView {
|
||||
|
||||
virtual void prepareRender() override;
|
||||
virtual void render() override;
|
||||
|
||||
virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
||||
|
||||
private:
|
||||
std::thread queryThread;
|
||||
|
||||
@@ -93,7 +93,6 @@ EnvironmentLoader::EnvironmentLoader(Gfx::PGraphics graphics) : graphics(graphic
|
||||
{"precomputeBRDF", "EnvironmentMapping"},
|
||||
},
|
||||
.rootSignature = cubePipelineLayout,
|
||||
.dumpIntermediate = true,
|
||||
});
|
||||
cubePipelineLayout->create();
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ void TextureLoader::import(TextureImportArgs args, PTextureAsset textureAsset) {
|
||||
.uastcFlags = KTX_PACK_UASTC_LEVEL_DEFAULT,
|
||||
.uastcRDO = true,
|
||||
};
|
||||
KTX_ASSERT(ktxTexture2_CompressBasisEx(kTexture, &basisParams));
|
||||
// KTX_ASSERT(ktxTexture2_CompressBasis(kTexture, 0));
|
||||
//KTX_ASSERT(ktxTexture2_DeflateZstd(kTexture, 10));
|
||||
|
||||
char writer[100];
|
||||
|
||||
@@ -38,11 +38,11 @@ void InspectorView::render() { renderGraph.render(Component::Camera(), Component
|
||||
|
||||
void InspectorView::applyArea(URect ) {}
|
||||
|
||||
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifier) {}
|
||||
void InspectorView::keyCallback(KeyCode, InputAction, KeyModifierFlags) {}
|
||||
|
||||
void InspectorView::mouseMoveCallback(double, double) {}
|
||||
|
||||
void InspectorView::mouseButtonCallback(MouseButton, InputAction, KeyModifier) {}
|
||||
void InspectorView::mouseButtonCallback(MouseButton, InputAction, KeyModifierFlags) {}
|
||||
|
||||
void InspectorView::scrollCallback(double, double) {}
|
||||
|
||||
|
||||
@@ -26,9 +26,9 @@ class InspectorView : public View {
|
||||
RenderGraph renderGraph;
|
||||
Component::Camera cam;
|
||||
|
||||
virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) override;
|
||||
virtual void keyCallback(KeyCode code, InputAction action, KeyModifierFlags modifier) override;
|
||||
virtual void mouseMoveCallback(double xPos, double yPos) override;
|
||||
virtual void mouseButtonCallback(MouseButton button, InputAction action, KeyModifier modifier) override;
|
||||
virtual void mouseButtonCallback(MouseButton button, InputAction action, KeyModifierFlags modifier) override;
|
||||
virtual void scrollCallback(double xOffset, double yOffset) override;
|
||||
virtual void fileCallback(int count, const char** paths) override;
|
||||
};
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Graphics/Enums.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "Window/Window.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Editor;
|
||||
@@ -21,7 +22,7 @@ void PlayView::prepareRender() { GameView::prepareRender(); }
|
||||
|
||||
void PlayView::render() { GameView::render(); }
|
||||
|
||||
void PlayView::keyCallback(KeyCode code, InputAction action, KeyModifier modifier) {
|
||||
void PlayView::keyCallback(KeyCode code, InputAction action, KeyModifierFlags modifier) {
|
||||
GameView::keyCallback(code, action, modifier);
|
||||
if (code == KeyCode::KEY_P && action == InputAction::RELEASE) {
|
||||
getGlobals().usePositionOnly = !getGlobals().usePositionOnly;
|
||||
|
||||
@@ -14,7 +14,7 @@ class PlayView : public GameView {
|
||||
virtual void prepareRender() override;
|
||||
virtual void render() override;
|
||||
|
||||
virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
||||
virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifierFlags modifier) override;
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
@@ -42,11 +42,11 @@ void SceneView::prepareRender() {}
|
||||
|
||||
void SceneView::render() { renderGraph.render(viewportCamera, Component::Transform()); }
|
||||
|
||||
void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifier) { cameraSystem.keyCallback(code, action); }
|
||||
void SceneView::keyCallback(KeyCode code, InputAction action, KeyModifierFlags) { cameraSystem.keyCallback(code, action); }
|
||||
|
||||
void SceneView::mouseMoveCallback(double xPos, double yPos) { cameraSystem.mouseMoveCallback(xPos, yPos); }
|
||||
|
||||
void SceneView::mouseButtonCallback(MouseButton button, InputAction action, KeyModifier) {
|
||||
void SceneView::mouseButtonCallback(MouseButton button, InputAction action, KeyModifierFlags) {
|
||||
cameraSystem.mouseButtonCallback(button, action);
|
||||
}
|
||||
|
||||
|
||||
@@ -29,9 +29,9 @@ class SceneView : public View {
|
||||
|
||||
ViewportControl cameraSystem;
|
||||
|
||||
virtual void keyCallback(KeyCode code, InputAction action, KeyModifier modifier) override;
|
||||
virtual void keyCallback(KeyCode code, InputAction action, KeyModifierFlags modifier) override;
|
||||
virtual void mouseMoveCallback(double xPos, double yPos) override;
|
||||
virtual void mouseButtonCallback(MouseButton button, InputAction action, KeyModifier modifier) override;
|
||||
virtual void mouseButtonCallback(MouseButton button, InputAction action, KeyModifierFlags modifier) override;
|
||||
virtual void scrollCallback(double xOffset, double yOffset) override;
|
||||
virtual void fileCallback(int count, const char** paths) override;
|
||||
};
|
||||
|
||||
+12
-12
@@ -21,9 +21,9 @@ using namespace Seele::Editor;
|
||||
static Gfx::OGraphics graphics;
|
||||
|
||||
int main() {
|
||||
std::string gameName = "MeshShadingDemo";
|
||||
std::filesystem::path outputPath = fmt::format("/Users/dynamitos/{0}Game/", gameName);
|
||||
std::filesystem::path sourcePath = fmt::format("/Users/dynamitos/{0}/", gameName);
|
||||
std::string gameName = "FluidSimulation";
|
||||
std::filesystem::path outputPath = fmt::format("/home/dynamitos/{0}Game/", gameName);
|
||||
std::filesystem::path sourcePath = fmt::format("/home/dynamitos/{0}/", gameName);
|
||||
#ifdef WIN32
|
||||
std::string libraryEnding = "dll";
|
||||
#elif __APPLE__
|
||||
@@ -31,7 +31,7 @@ int main() {
|
||||
#else
|
||||
std::string libraryEnding = "so";
|
||||
#endif
|
||||
std::filesystem::path binaryPath = sourcePath / "build/Debug" / fmt::format("{}.{}", gameName, libraryEnding);
|
||||
std::filesystem::path binaryPath = sourcePath / "build" / fmt::format("{}.{}", gameName, libraryEnding);
|
||||
std::filesystem::path cmakePath = outputPath / "cmake";
|
||||
if (true) {
|
||||
graphics = new Vulkan::Graphics();
|
||||
@@ -46,9 +46,9 @@ int main() {
|
||||
AssetImporter::importFont(FontImportArgs{
|
||||
.filePath = "./fonts/arial.ttf",
|
||||
});
|
||||
// AssetImporter::importEnvironmentMap(EnvironmentImportArgs{
|
||||
// .filePath = sourcePath / "import" / "textures" / "newport_loft.hdr",
|
||||
// });
|
||||
AssetImporter::importEnvironmentMap(EnvironmentImportArgs{
|
||||
.filePath = sourcePath / "import" / "newport_loft.hdr",
|
||||
});
|
||||
// AssetImporter::importTexture(TextureImportArgs{
|
||||
// .filePath = sourcePath / "import" / "textures" / "grass_block_side.png",
|
||||
// .importPath = "",
|
||||
@@ -62,12 +62,12 @@ int main() {
|
||||
// .importPath = "rttest",
|
||||
// });
|
||||
|
||||
// AssetImporter::importMesh(MeshImportArgs{
|
||||
// .filePath = sourcePath / "import" / "models" / "cube.fbx",
|
||||
// .importPath = "",
|
||||
// });
|
||||
AssetImporter::importMesh(MeshImportArgs{
|
||||
.filePath = sourcePath / "import" / "models" / "cube.fbx",
|
||||
.importPath = "",
|
||||
});
|
||||
AssetImporter::importMesh(MeshImportArgs{
|
||||
.filePath = sourcePath / "import" / "models" / "rttest.gltf",
|
||||
.filePath = sourcePath / "import" / "rttest.gltf",
|
||||
.importPath = "rttest",
|
||||
});
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ target_sources(Engine
|
||||
Collider.cpp
|
||||
Component.h
|
||||
DirectionalLight.h
|
||||
FluidGrid.h
|
||||
KeyboardInput.h
|
||||
Mesh.h
|
||||
MeshCollider.h
|
||||
@@ -29,6 +30,7 @@ target_sources(Engine
|
||||
Collider.h
|
||||
Component.h
|
||||
DirectionalLight.h
|
||||
FluidGrid.h
|
||||
KeyboardInput.h
|
||||
MeshCollider.h
|
||||
Mesh.h
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
#include "Math/Vector.h"
|
||||
|
||||
namespace Seele {
|
||||
namespace Component {
|
||||
struct FluidGrid {
|
||||
float cellSize = 1.0f;
|
||||
float viscosity = 0.1f;
|
||||
float diffusion = 0.01f;
|
||||
UVector gridSize = {128, 128, 128};
|
||||
};
|
||||
} // namespace Component
|
||||
} // namespace Seele
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "BasePass.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Asset/EnvironmentMapAsset.h"
|
||||
#include "Component/Camera.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
@@ -12,10 +13,9 @@
|
||||
#include "Math/Matrix.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "ShadowPass.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "Asset/EnvironmentMapAsset.h"
|
||||
#include "Scene/LightEnvironment.h"
|
||||
#include "Scene/Scene.h"
|
||||
#include "ShadowPass.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -59,10 +59,8 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
||||
.name = SHADOWSAMPLER_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
shadowMappingLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = CASCADE_SPLIT_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER
|
||||
});
|
||||
shadowMappingLayout->addDescriptorBinding(
|
||||
Gfx::DescriptorBinding{.name = CASCADE_SPLIT_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_UNIFORM_BUFFER});
|
||||
shadowMappingLayout->create();
|
||||
|
||||
basePassLayout->addDescriptorLayout(lightCullingLayout);
|
||||
@@ -116,6 +114,58 @@ BasePass::BasePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics)
|
||||
.minLod = 0.0f,
|
||||
.borderColor = Gfx::SE_BORDER_COLOR_FLOAT_OPAQUE_WHITE,
|
||||
});
|
||||
debugPipelineLayout = graphics->createPipelineLayout("DebugPassLayout");
|
||||
debugPipelineLayout->addDescriptorLayout(viewParamsLayout);
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "DebugVertex",
|
||||
.modules = {"Debug"},
|
||||
.entryPoints =
|
||||
{
|
||||
{"vertexMain", "Debug"},
|
||||
{"fragmentMain", "Debug"},
|
||||
},
|
||||
.rootSignature = debugPipelineLayout,
|
||||
});
|
||||
debugVertexShader = graphics->createVertexShader({0});
|
||||
debugFragmentShader = graphics->createFragmentShader({1});
|
||||
debugPipelineLayout->create();
|
||||
|
||||
skyboxDataLayout = graphics->createDescriptorLayout("pSkyboxData");
|
||||
skyboxDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.name = "transformMatrix", .uniformLength = sizeof(Matrix4)});
|
||||
skyboxDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.name = "fogBlend", .uniformLength = sizeof(Vector4)});
|
||||
skyboxDataLayout->create();
|
||||
textureLayout = graphics->createDescriptorLayout("pSkyboxTextures");
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = SKYBOXDAY_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_SAMPLE_BIT,
|
||||
});
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = SKYBOXNIGHT_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_SAMPLE_BIT,
|
||||
});
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = SKYBOXSAMPLER_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
textureLayout->create();
|
||||
|
||||
pipelineLayout = graphics->createPipelineLayout("SkyboxLayout");
|
||||
pipelineLayout->addDescriptorLayout(viewParamsLayout);
|
||||
pipelineLayout->addDescriptorLayout(skyboxDataLayout);
|
||||
pipelineLayout->addDescriptorLayout(textureLayout);
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "SkyboxVertex",
|
||||
.modules = {"Skybox"},
|
||||
.entryPoints = {{"vertexMain", "Skybox"}, {"fragmentMain", "Skybox"}},
|
||||
.rootSignature = pipelineLayout,
|
||||
});
|
||||
vertexShader = graphics->createVertexShader({0});
|
||||
fragmentShader = graphics->createFragmentShader({1});
|
||||
pipelineLayout->create();
|
||||
}
|
||||
|
||||
BasePass::~BasePass() {}
|
||||
@@ -176,7 +226,7 @@ void BasePass::render() {
|
||||
transparentCulling->updateTexture(LIGHTGRID_NAME, 0, tLightGrid->getDefaultView());
|
||||
opaqueCulling->writeChanges();
|
||||
transparentCulling->writeChanges();
|
||||
|
||||
|
||||
shadowMappingLayout->reset();
|
||||
shadowMapping = shadowMappingLayout->allocateDescriptorSet();
|
||||
for (uint32 i = 0; i < NUM_CASCADES; ++i) {
|
||||
@@ -268,7 +318,8 @@ void BasePass::render() {
|
||||
command->bindPipeline(graphics->createGraphicsPipeline(std::move(pipelineInfo)));
|
||||
}
|
||||
command->bindDescriptor({viewParamsSet, vertexData->getVertexDataSet(), vertexData->getInstanceDataSet(),
|
||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), shadowMapping, opaqueCulling});
|
||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), shadowMapping,
|
||||
opaqueCulling});
|
||||
for (const auto& drawCall : materialData.instances) {
|
||||
command->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||
@@ -382,8 +433,8 @@ void BasePass::render() {
|
||||
transparentCommand->bindPipeline(pipeline);
|
||||
}
|
||||
transparentCommand->bindDescriptor({viewParamsSet, t.vertexData->getVertexDataSet(), t.vertexData->getInstanceDataSet(),
|
||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(), shadowMapping,
|
||||
transparentCulling});
|
||||
scene->getLightEnvironment()->getDescriptorSet(), Material::getDescriptorSet(),
|
||||
shadowMapping, transparentCulling});
|
||||
transparentCommand->pushConstants(Gfx::SE_SHADER_STAGE_TASK_BIT_EXT | Gfx::SE_SHADER_STAGE_VERTEX_BIT |
|
||||
Gfx::SE_SHADER_STAGE_FRAGMENT_BIT,
|
||||
0, sizeof(VertexData::DrawCallOffsets), &t.offsets);
|
||||
@@ -536,24 +587,6 @@ void BasePass::createRenderPass() {
|
||||
|
||||
// Debug rendering
|
||||
{
|
||||
debugPipelineLayout = graphics->createPipelineLayout("DebugPassLayout");
|
||||
debugPipelineLayout->addDescriptorLayout(viewParamsLayout);
|
||||
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "DebugVertex",
|
||||
.modules = {"Debug"},
|
||||
.entryPoints =
|
||||
{
|
||||
{"vertexMain", "Debug"},
|
||||
{"fragmentMain", "Debug"},
|
||||
},
|
||||
.rootSignature = debugPipelineLayout,
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
debugVertexShader = graphics->createVertexShader({0});
|
||||
debugFragmentShader = graphics->createFragmentShader({1});
|
||||
debugPipelineLayout->create();
|
||||
|
||||
VertexInputStateCreateInfo inputCreate = {
|
||||
.bindings =
|
||||
{
|
||||
@@ -605,27 +638,6 @@ void BasePass::createRenderPass() {
|
||||
}
|
||||
// Skybox
|
||||
{
|
||||
skyboxDataLayout = graphics->createDescriptorLayout("pSkyboxData");
|
||||
skyboxDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.name = "transformMatrix", .uniformLength = sizeof(Matrix4)});
|
||||
skyboxDataLayout->addDescriptorBinding(Gfx::DescriptorBinding{.name = "fogBlend", .uniformLength = sizeof(Vector4)});
|
||||
skyboxDataLayout->create();
|
||||
textureLayout = graphics->createDescriptorLayout("pSkyboxTextures");
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = SKYBOXDAY_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_SAMPLE_BIT,
|
||||
});
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = SKYBOXNIGHT_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_SAMPLE_BIT,
|
||||
});
|
||||
textureLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = SKYBOXSAMPLER_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLER,
|
||||
});
|
||||
textureLayout->create();
|
||||
|
||||
skyboxSampler = graphics->createSampler({
|
||||
.magFilter = Gfx::SE_FILTER_LINEAR,
|
||||
.minFilter = Gfx::SE_FILTER_LINEAR,
|
||||
@@ -642,23 +654,6 @@ void BasePass::createRenderPass() {
|
||||
skyboxData.fogColor = skybox.fogColor;
|
||||
skyboxData.blendFactor = skybox.blendFactor;
|
||||
|
||||
pipelineLayout = graphics->createPipelineLayout("SkyboxLayout");
|
||||
pipelineLayout->addDescriptorLayout(viewParamsLayout);
|
||||
pipelineLayout->addDescriptorLayout(skyboxDataLayout);
|
||||
pipelineLayout->addDescriptorLayout(textureLayout);
|
||||
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "SkyboxVertex",
|
||||
.modules = {"Skybox"},
|
||||
.entryPoints = {{"vertexMain", "Skybox"}, {"fragmentMain", "Skybox"}},
|
||||
.rootSignature = pipelineLayout,
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
vertexShader = graphics->createVertexShader({0});
|
||||
fragmentShader = graphics->createFragmentShader({1});
|
||||
|
||||
pipelineLayout->create();
|
||||
|
||||
Gfx::LegacyPipelineCreateInfo gfxInfo = {
|
||||
.topology = Gfx::SE_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST,
|
||||
.vertexShader = vertexShader,
|
||||
@@ -673,10 +668,11 @@ void BasePass::createRenderPass() {
|
||||
{
|
||||
.polygonMode = Gfx::SE_POLYGON_MODE_FILL,
|
||||
},
|
||||
.depthStencilState = {
|
||||
.depthTestEnable = true,
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.depthStencilState =
|
||||
{
|
||||
.depthTestEnable = true,
|
||||
.depthCompareOp = Gfx::SE_COMPARE_OP_GREATER,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/RenderPass/ShadowPass.h"
|
||||
#include "Component/Skybox.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "RenderPass.h"
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@ target_sources(Engine
|
||||
CachedDepthPass.cpp
|
||||
DepthCullingPass.h
|
||||
DepthCullingPass.cpp
|
||||
FluidRenderPass.h
|
||||
FluidRenderPass.cpp
|
||||
LightCullingPass.h
|
||||
LightCullingPass.cpp
|
||||
RayTracingPass.h
|
||||
@@ -17,6 +19,10 @@ target_sources(Engine
|
||||
RenderPass.cpp
|
||||
ShadowPass.h
|
||||
ShadowPass.cpp
|
||||
SimulationComputePass.h
|
||||
SimulationComputePass.cpp
|
||||
SurfaceExtractPass.h
|
||||
SurfaceExtractPass.cpp
|
||||
#TerrainRenderer.h
|
||||
#TerrainRenderer.cpp
|
||||
ToneMappingPass.h
|
||||
@@ -34,6 +40,7 @@ target_sources(Engine
|
||||
BasePass.h
|
||||
CachedDepthPass.h
|
||||
DepthCullingPass.h
|
||||
FluidRenderPass.h
|
||||
LightCullingPass.h
|
||||
ToneMappingPass.h
|
||||
RayTracingPass.h
|
||||
@@ -41,6 +48,8 @@ target_sources(Engine
|
||||
RenderGraphResources.h
|
||||
RenderPass.h
|
||||
ShadowPass.h
|
||||
SimulationComputePass.h
|
||||
SurfaceExtractPass.h
|
||||
#TerrainRenderer.h
|
||||
UIPass.h
|
||||
VisibilityPass.h)
|
||||
@@ -37,6 +37,24 @@ DepthCullingPass::DepthCullingPass(Gfx::PGraphics graphics, PScene scene) : Rend
|
||||
.size = sizeof(MipParam),
|
||||
.name = "pMipParam"
|
||||
});
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "DepthMipCompute",
|
||||
.modules = {"DepthMipGen"},
|
||||
.entryPoints = {{"sourceCopy", "DepthMipGen"}, {"reduceLevel", "DepthMipGen"}},
|
||||
.rootSignature = depthComputeLayout,
|
||||
});
|
||||
depthSourceCopyShader = graphics->createComputeShader({0});
|
||||
depthComputeLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineCreateInfo = {
|
||||
.computeShader = depthSourceCopyShader,
|
||||
.pipelineLayout = depthComputeLayout,
|
||||
};
|
||||
depthSourceCopy = graphics->createComputePipeline(pipelineCreateInfo);
|
||||
|
||||
depthReduceLevelShader = graphics->createComputeShader({1});
|
||||
pipelineCreateInfo.computeShader = depthReduceLevelShader;
|
||||
depthReduceLevel = graphics->createComputePipeline(pipelineCreateInfo);
|
||||
|
||||
if (graphics->supportMeshShading()) {
|
||||
graphics->getShaderCompiler()->registerRenderPass("DepthPass", Gfx::PassConfig{
|
||||
@@ -255,24 +273,6 @@ void DepthCullingPass::publishOutputs() {
|
||||
.name = "DepthMipBuffer",
|
||||
});
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "DepthMipCompute",
|
||||
.modules = {"DepthMipGen"},
|
||||
.entryPoints = {{"sourceCopy", "DepthMipGen"}, {"reduceLevel", "DepthMipGen"}},
|
||||
.rootSignature = depthComputeLayout,
|
||||
});
|
||||
depthSourceCopyShader = graphics->createComputeShader({0});
|
||||
depthComputeLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineCreateInfo = {
|
||||
.computeShader = depthSourceCopyShader,
|
||||
.pipelineLayout = depthComputeLayout,
|
||||
};
|
||||
depthSourceCopy = graphics->createComputePipeline(pipelineCreateInfo);
|
||||
|
||||
depthReduceLevelShader = graphics->createComputeShader({1});
|
||||
pipelineCreateInfo.computeShader = depthReduceLevelShader;
|
||||
depthReduceLevel = graphics->createComputePipeline(pipelineCreateInfo);
|
||||
|
||||
query = graphics->createPipelineStatisticsQuery("DepthPipelineStatistics");
|
||||
resources->registerQueryOutput("DEPTH_QUERY", query);
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
#include "FluidRenderPass.h"
|
||||
#include "Component/Transform.h"
|
||||
#include "Graphics/Command.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/RenderTarget.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Scene/LightEnvironment.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
FluidRenderPass::FluidRenderPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {
|
||||
pipelineLayout = graphics->createPipelineLayout("FluidPipelineLayout");
|
||||
descriptorLayout = graphics->createDescriptorLayout("params");
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "vertexBuffer",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "normalBuffer",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "indexBuffer",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->create();
|
||||
pipelineLayout->addDescriptorLayout(viewParamsLayout);
|
||||
pipelineLayout->addDescriptorLayout(descriptorLayout);
|
||||
pipelineLayout->addDescriptorLayout(scene->getLightEnvironment()->getDescriptorLayout());
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "Fluid",
|
||||
.modules = {"Render"},
|
||||
.entryPoints = {{"vertexMain", "Render"}, {"fragmentMain", "Render"}},
|
||||
.rootSignature = pipelineLayout,
|
||||
});
|
||||
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);
|
||||
}
|
||||
|
||||
void FluidRenderPass::render() {
|
||||
viewParamsSet = createViewParamsSet();
|
||||
graphics->beginRenderPass(renderPass);
|
||||
descriptorLayout->reset();
|
||||
for (const auto& [id, data] : scene->getFluidScene()->getFluidDataMap()) {
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer("vertexBuffer", 0, data.vertexBuffer);
|
||||
descriptorSet->updateBuffer("normalBuffer", 0, data.normalBuffer);
|
||||
descriptorSet->updateBuffer("indexBuffer", 0, data.indexBuffer);
|
||||
descriptorSet->writeChanges();
|
||||
Gfx::ORenderCommand renderCommand = graphics->createRenderCommand();
|
||||
renderCommand->setViewport(viewport);
|
||||
renderCommand->bindPipeline(pipeline);
|
||||
renderCommand->bindDescriptor(viewParamsSet);
|
||||
renderCommand->bindDescriptor(descriptorSet);
|
||||
renderCommand->bindDescriptor(scene->getLightEnvironment()->getDescriptorSet());
|
||||
renderCommand->drawIndirect(data.surfaceCountBuffer, 0, 1, 0);
|
||||
graphics->executeCommands(std::move(renderCommand));
|
||||
}
|
||||
graphics->endRenderPass();
|
||||
}
|
||||
|
||||
void FluidRenderPass::endFrame() {}
|
||||
|
||||
void FluidRenderPass::publishOutputs() {
|
||||
depthTexture = graphics->createTexture2D(TextureCreateInfo{
|
||||
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||
.width = viewport->getWidth(),
|
||||
.height = viewport->getHeight(),
|
||||
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||
.name = "FluidDepth",
|
||||
});
|
||||
}
|
||||
|
||||
void FluidRenderPass::createRenderPass() {
|
||||
colorAttachment = Gfx::RenderTargetAttachment(viewport, 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_FRONT_BIT,
|
||||
},
|
||||
.colorBlend =
|
||||
{
|
||||
.attachmentCount = 1,
|
||||
.blendAttachments =
|
||||
{
|
||||
Gfx::ColorBlendState::BlendAttachment{
|
||||
.blendEnable = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#include "Component/Transform.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/RenderPass/RenderPass.h"
|
||||
#include "MinimalEngine.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
namespace Seele {
|
||||
class FluidRenderPass : public RenderPass {
|
||||
public:
|
||||
FluidRenderPass(Gfx::PGraphics graphics, PScene scene);
|
||||
virtual ~FluidRenderPass() override;
|
||||
|
||||
virtual void beginFrame(const Component::Camera& camera, const Component::Transform& transform) override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
|
||||
private:
|
||||
Gfx::RenderTargetAttachment colorAttachment;
|
||||
Gfx::RenderTargetAttachment depthAttachment;
|
||||
Gfx::OTexture2D depthTexture;
|
||||
|
||||
Gfx::ODescriptorSet viewParamsSet;
|
||||
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::ODescriptorSet descriptorSet;
|
||||
Gfx::OVertexShader vertexShader;
|
||||
Gfx::OFragmentShader fragmentShader;
|
||||
Gfx::PGraphicsPipeline pipeline;
|
||||
|
||||
PScene scene;
|
||||
};
|
||||
DEFINE_REF(FluidRenderPass)
|
||||
} // namespace Seele
|
||||
@@ -11,7 +11,137 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {}
|
||||
LightCullingPass::LightCullingPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {
|
||||
dispatchParamsLayout = graphics->createDescriptorLayout("pDispatchParams");
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "numThreadGroups",
|
||||
.uniformLength = sizeof(UVector4),
|
||||
});
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "numThreads",
|
||||
.uniformLength = sizeof(UVector4),
|
||||
});
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = FRUSTUMBUFFER_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
dispatchParamsLayout->create();
|
||||
frustumLayout = graphics->createPipelineLayout("FrustumLayout");
|
||||
frustumLayout->addDescriptorLayout(viewParamsLayout);
|
||||
frustumLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "Frustum",
|
||||
.modules = {"ComputeFrustums"},
|
||||
.entryPoints = {{"computeFrustums", "ComputeFrustums"}},
|
||||
.rootSignature = frustumLayout,
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
frustumShader = graphics->createComputeShader({0});
|
||||
// Have to compile shader before finalizing layout as parameters get mapped later
|
||||
frustumLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = frustumShader;
|
||||
pipelineInfo.pipelineLayout = frustumLayout;
|
||||
frustumPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
|
||||
cullingDescriptorLayout = graphics->createDescriptorLayout("pCullingParams");
|
||||
|
||||
// DepthTexture
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = DEPTHATTACHMENT_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_SAMPLE_BIT,
|
||||
});
|
||||
// o_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = OLIGHTINDEXCOUNTER_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
// t_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = TLIGHTINDEXCOUNTER_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
// o_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = OLIGHTINDEXLIST_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
// t_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = TLIGHTINDEXLIST_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
// o_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = OLIGHTGRID_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
// t_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = TLIGHTGRID_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
|
||||
cullingDescriptorLayout->create();
|
||||
|
||||
lightEnv = scene->getLightEnvironment();
|
||||
|
||||
{
|
||||
cullingLayout = graphics->createPipelineLayout("CullingLayout");
|
||||
cullingLayout->addDescriptorLayout(viewParamsLayout);
|
||||
cullingLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||
cullingLayout->addDescriptorLayout(cullingDescriptorLayout);
|
||||
cullingLayout->addDescriptorLayout(lightEnv->getDescriptorLayout());
|
||||
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "Culling",
|
||||
.modules = {"LightCulling"},
|
||||
.entryPoints = {{"cullLights", "LightCulling"}},
|
||||
.rootSignature = cullingLayout,
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
cullingShader = graphics->createComputeShader({0});
|
||||
cullingLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = cullingShader;
|
||||
pipelineInfo.pipelineLayout = cullingLayout;
|
||||
cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||
}
|
||||
|
||||
{
|
||||
cullingEnableLayout = graphics->createPipelineLayout("CullingEnabledLayout");
|
||||
cullingEnableLayout->addDescriptorLayout(viewParamsLayout);
|
||||
cullingEnableLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||
cullingEnableLayout->addDescriptorLayout(cullingDescriptorLayout);
|
||||
cullingEnableLayout->addDescriptorLayout(lightEnv->getDescriptorLayout());
|
||||
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "Culling",
|
||||
.modules = {"LightCulling"},
|
||||
.entryPoints = {{"cullLights", "LightCulling"}},
|
||||
.rootSignature = cullingEnableLayout,
|
||||
};
|
||||
createInfo.defines["LIGHT_CULLING"] = "1";
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
cullingEnabledShader = graphics->createComputeShader({0});
|
||||
cullingEnableLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = cullingShader;
|
||||
pipelineInfo.pipelineLayout = cullingEnableLayout;
|
||||
cullingEnabledPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||
}
|
||||
}
|
||||
|
||||
LightCullingPass::~LightCullingPass() {}
|
||||
|
||||
@@ -91,86 +221,9 @@ void LightCullingPass::publishOutputs() {
|
||||
dispatchParamsSet = dispatchParamsLayout->allocateDescriptorSet();
|
||||
dispatchParamsSet->updateConstants("numThreadGroups", 0, &numThreadGroups);
|
||||
dispatchParamsSet->updateConstants("numThreads", 0, &numThreads);
|
||||
dispatchParamsSet->updateBuffer(FRUSTUMBUFFER_NAME, 0, frustumBuffer);
|
||||
dispatchParamsSet->writeChanges();
|
||||
|
||||
cullingDescriptorLayout = graphics->createDescriptorLayout("pCullingParams");
|
||||
|
||||
// DepthTexture
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = DEPTHATTACHMENT_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_SAMPLE_BIT,
|
||||
});
|
||||
// o_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = OLIGHTINDEXCOUNTER_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,});
|
||||
// t_lightIndexCounter
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = TLIGHTINDEXCOUNTER_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,});
|
||||
// o_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = OLIGHTINDEXLIST_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,});
|
||||
// t_lightIndexList
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = TLIGHTINDEXLIST_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,});
|
||||
// o_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = OLIGHTGRID_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,});
|
||||
// t_lightGrid
|
||||
cullingDescriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = TLIGHTGRID_NAME, .descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_IMAGE, .access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,});
|
||||
|
||||
cullingDescriptorLayout->create();
|
||||
|
||||
lightEnv = scene->getLightEnvironment();
|
||||
|
||||
{
|
||||
cullingLayout = graphics->createPipelineLayout("CullingLayout");
|
||||
cullingLayout->addDescriptorLayout(viewParamsLayout);
|
||||
cullingLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||
cullingLayout->addDescriptorLayout(cullingDescriptorLayout);
|
||||
cullingLayout->addDescriptorLayout(lightEnv->getDescriptorLayout());
|
||||
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "Culling",
|
||||
.modules = {"LightCulling"},
|
||||
.entryPoints = {{"cullLights", "LightCulling"}},
|
||||
.rootSignature = cullingLayout,
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
cullingShader = graphics->createComputeShader({0});
|
||||
cullingLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = cullingShader;
|
||||
pipelineInfo.pipelineLayout = cullingLayout;
|
||||
cullingPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||
}
|
||||
|
||||
{
|
||||
cullingEnableLayout = graphics->createPipelineLayout("CullingEnabledLayout");
|
||||
cullingEnableLayout->addDescriptorLayout(viewParamsLayout);
|
||||
cullingEnableLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||
cullingEnableLayout->addDescriptorLayout(cullingDescriptorLayout);
|
||||
cullingEnableLayout->addDescriptorLayout(lightEnv->getDescriptorLayout());
|
||||
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "Culling",
|
||||
.modules = {"LightCulling"},
|
||||
.entryPoints = {{"cullLights", "LightCulling"}},
|
||||
.rootSignature = cullingEnableLayout,
|
||||
};
|
||||
createInfo.defines["LIGHT_CULLING"] = "1";
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
cullingEnabledShader = graphics->createComputeShader({0});
|
||||
cullingEnableLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = cullingShader;
|
||||
pipelineInfo.pipelineLayout = cullingEnableLayout;
|
||||
cullingEnabledPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||
}
|
||||
|
||||
uint32 counterReset = 0;
|
||||
ShaderBufferCreateInfo structInfo = {
|
||||
.sourceData =
|
||||
@@ -188,8 +241,7 @@ void LightCullingPass::publishOutputs() {
|
||||
structInfo = {
|
||||
.sourceData =
|
||||
{
|
||||
.size = (uint32)sizeof(uint32) * numThreadGroups.x * numThreadGroups.y *
|
||||
numThreadGroups.z * 8192,
|
||||
.size = (uint32)sizeof(uint32) * numThreadGroups.x * numThreadGroups.y * numThreadGroups.z * 8192,
|
||||
.data = nullptr,
|
||||
.owner = Gfx::QueueType::COMPUTE,
|
||||
},
|
||||
@@ -237,41 +289,6 @@ void LightCullingPass::setupFrustums() {
|
||||
updateViewParameters(Component::Camera(), Component::Transform());
|
||||
viewParamsSet = createViewParamsSet();
|
||||
|
||||
dispatchParamsLayout = graphics->createDescriptorLayout("pDispatchParams");
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "numThreadGroups",
|
||||
.uniformLength = sizeof(UVector4),
|
||||
});
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "numThreads",
|
||||
.uniformLength = sizeof(UVector4),
|
||||
});
|
||||
dispatchParamsLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = FRUSTUMBUFFER_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
dispatchParamsLayout->create();
|
||||
frustumLayout = graphics->createPipelineLayout("FrustumLayout");
|
||||
frustumLayout->addDescriptorLayout(viewParamsLayout);
|
||||
frustumLayout->addDescriptorLayout(dispatchParamsLayout);
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "Frustum",
|
||||
.modules = {"ComputeFrustums"},
|
||||
.entryPoints = {{"computeFrustums", "ComputeFrustums"}},
|
||||
.rootSignature = frustumLayout,
|
||||
.dumpIntermediate = true,
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
frustumShader = graphics->createComputeShader({0});
|
||||
// Have to compile shader before finalizing layout as parameters get mapped later
|
||||
frustumLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = frustumShader;
|
||||
pipelineInfo.pipelineLayout = frustumLayout;
|
||||
frustumPipeline = graphics->createComputePipeline(pipelineInfo);
|
||||
|
||||
frustumBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
@@ -299,6 +316,6 @@ void LightCullingPass::setupFrustums() {
|
||||
commands.add(std::move(command));
|
||||
graphics->executeCommands(std::move(commands));
|
||||
frustumBuffer->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);
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
#include "Graphics/RayTracing.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Graphics/StaticMeshVertexData.h"
|
||||
#include "RenderPass.h"
|
||||
#include "Material/Material.h"
|
||||
#include "Material/MaterialInstance.h"
|
||||
#include "RenderPass.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
@@ -55,11 +56,24 @@ RayTracingPass::RayTracingPass(Gfx::PGraphics graphics, PScene scene) : RenderPa
|
||||
.size = sizeof(SampleParams),
|
||||
.name = "pSamps",
|
||||
});
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "RayGenMiss",
|
||||
.modules = {"RayGen", "AnyHit", "Miss"},
|
||||
.entryPoints = {{"raygen", "RayGen"}, {"anyhit", "AnyHit"}, {"miss", "Miss"}},
|
||||
.defines = {{"RAY_TRACING", "1"}},
|
||||
.rootSignature = pipelineLayout,
|
||||
});
|
||||
rayGen = graphics->createRayGenShader({0});
|
||||
anyhit = graphics->createAnyHitShader({1});
|
||||
miss = graphics->createMissShader({2});
|
||||
pipelineLayout->create();
|
||||
graphics->getShaderCompiler()->registerRenderPass("RayTracing", Gfx::PassConfig{
|
||||
.baseLayout = pipelineLayout,
|
||||
.mainFile = "ClosestHit",
|
||||
.useMaterial = true,
|
||||
.rayTracing = true,
|
||||
.dumpIntermediates = true,
|
||||
});
|
||||
skyBox = AssetRegistry::findEnvironmentMap("", "newport_loft")->getSkybox();
|
||||
skyBoxSampler = graphics->createSampler({});
|
||||
@@ -212,20 +226,9 @@ void RayTracingPass::publishOutputs() {
|
||||
texture->changeLayout(Gfx::SE_IMAGE_LAYOUT_GENERAL, Gfx::SE_ACCESS_NONE, Gfx::SE_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT | Gfx::SE_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR);
|
||||
resources->registerRenderPassOutput("BASEPASS_COLOR", Gfx::RenderTargetAttachment(texture->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
|
||||
ShaderCompilationInfo compileInfo = {
|
||||
.name = "RayGenMiss",
|
||||
.modules = {"RayGen", "AnyHit", "Miss"},
|
||||
.entryPoints = {{"raygen", "RayGen"}, {"anyhit", "AnyHit"}, {"miss", "Miss"}},
|
||||
.defines = {{"RAY_TRACING", "1"}},
|
||||
.rootSignature = pipelineLayout,
|
||||
};
|
||||
graphics->beginShaderCompilation(compileInfo);
|
||||
rayGen = graphics->createRayGenShader({0});
|
||||
anyhit = graphics->createAnyHitShader({1});
|
||||
miss = graphics->createMissShader({2});
|
||||
pipelineLayout->create();
|
||||
resources->registerRenderPassOutput("BASEPASS_COLOR",
|
||||
Gfx::RenderTargetAttachment(texture->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||
Gfx::SE_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL));
|
||||
}
|
||||
|
||||
void RayTracingPass::createRenderPass() {}
|
||||
|
||||
@@ -0,0 +1,519 @@
|
||||
#include "SimulationComputePass.h"
|
||||
#include "Graphics/Buffer.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"
|
||||
#include "Math/Vector.h"
|
||||
#include <iostream>
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
constexpr static int reinitInterval = 5;
|
||||
constexpr static int reinitIterations = 5;
|
||||
constexpr static float reinitDtau = 0.5f;
|
||||
|
||||
#define SWAP(a, b) \
|
||||
{ \
|
||||
auto temp = std::move(a); \
|
||||
a = std::move(b); \
|
||||
b = std::move(temp); \
|
||||
}
|
||||
|
||||
SimulationComputePass::SimulationComputePass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {
|
||||
{
|
||||
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,
|
||||
});
|
||||
}
|
||||
{
|
||||
reinitialize.pipelineLayout = graphics->createPipelineLayout("ReinitializePipelineLayout");
|
||||
reinitialize.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||
reinitialize.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "dtau",
|
||||
.uniformLength = sizeof(float),
|
||||
});
|
||||
reinitialize.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "phi",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
reinitialize.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "phi0",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
reinitialize.descriptorLayout->create();
|
||||
reinitialize.pipelineLayout->addDescriptorLayout(reinitialize.descriptorLayout);
|
||||
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "SignedDistance",
|
||||
.modules = {"SignedDistance"},
|
||||
.entryPoints = {{"reinitialize", "SignedDistance"}},
|
||||
.rootSignature = reinitialize.pipelineLayout,
|
||||
});
|
||||
reinitialize.pipelineLayout->create();
|
||||
reinitialize.shader = graphics->createComputeShader({0});
|
||||
reinitialize.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = reinitialize.shader,
|
||||
.pipelineLayout = reinitialize.pipelineLayout,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
SimulationComputePass::~SimulationComputePass() {}
|
||||
|
||||
void SimulationComputePass::beginFrame(const Seele::Component::Camera&, const Seele::Component::Transform&) {
|
||||
setBounds.descriptorLayout->reset();
|
||||
linearSolve.descriptorLayout->reset();
|
||||
computeDivergence.descriptorLayout->reset();
|
||||
project.descriptorLayout->reset();
|
||||
advect.descriptorLayout->reset();
|
||||
reinitialize.descriptorLayout->reset();
|
||||
}
|
||||
|
||||
void SimulationComputePass::render() {
|
||||
for (auto& [entityID, data] : scene->getFluidScene()->getFluidDataMap()) {
|
||||
graphics->beginDebugRegion("Diffuse");
|
||||
for (uint iteration = 0; iteration < 4; ++iteration) {
|
||||
float a = dt * data.viscosity * (data.gridSize.x - 2) * (data.gridSize.y - 2) * (data.gridSize.z - 2);
|
||||
float c = 1 + 6 * a;
|
||||
linearSolvePass(data.velocityXNextBuffer, data.velocityXBuffer, data.velocityX0Buffer, a, c, data.gridSize);
|
||||
linearSolvePass(data.velocityYNextBuffer, data.velocityYBuffer, data.velocityY0Buffer, a, c, data.gridSize);
|
||||
linearSolvePass(data.velocityZNextBuffer, data.velocityZBuffer, data.velocityZ0Buffer, a, c, data.gridSize);
|
||||
|
||||
setBoundsPass(data.velocityXNextBuffer, 1, data.gridSize);
|
||||
setBoundsPass(data.velocityYNextBuffer, 2, data.gridSize);
|
||||
setBoundsPass(data.velocityZNextBuffer, 3, data.gridSize);
|
||||
|
||||
SWAP(data.velocityXBuffer, data.velocityXNextBuffer);
|
||||
SWAP(data.velocityYBuffer, data.velocityYNextBuffer);
|
||||
SWAP(data.velocityZBuffer, data.velocityZNextBuffer);
|
||||
}
|
||||
|
||||
SWAP(data.velocityX0Buffer, data.velocityXBuffer);
|
||||
SWAP(data.velocityY0Buffer, data.velocityYBuffer);
|
||||
SWAP(data.velocityZ0Buffer, data.velocityZBuffer);
|
||||
graphics->endDebugRegion();
|
||||
|
||||
graphics->beginDebugRegion("Project");
|
||||
Gfx::PShaderBuffer divergence = data.velocityXBuffer;
|
||||
Gfx::PShaderBuffer pressureCurrent = data.velocityYBuffer;
|
||||
Gfx::PShaderBuffer pressureNext = data.velocityZBuffer;
|
||||
divergencePass(divergence, pressureCurrent, data.velocityX0Buffer, data.velocityY0Buffer, data.velocityZ0Buffer, data.gridSize);
|
||||
|
||||
for (int iteration = 0; iteration < 4; ++iteration) {
|
||||
linearSolvePass(pressureNext, pressureCurrent, divergence, 1, 6, data.gridSize);
|
||||
|
||||
setBoundsPass(pressureNext, 0, data.gridSize);
|
||||
|
||||
// swap pressure buffers
|
||||
SWAP(pressureCurrent, pressureNext);
|
||||
}
|
||||
|
||||
projectPass(data.velocityX0Buffer, data.velocityY0Buffer, data.velocityZ0Buffer, pressureCurrent, data.gridSize);
|
||||
|
||||
setBoundsPass(data.velocityX0Buffer, 1, data.gridSize);
|
||||
setBoundsPass(data.velocityY0Buffer, 2, data.gridSize);
|
||||
setBoundsPass(data.velocityZ0Buffer, 3, data.gridSize);
|
||||
graphics->endDebugRegion();
|
||||
|
||||
graphics->beginDebugRegion("Advect");
|
||||
advectPass(data.velocityXBuffer, data.velocityX0Buffer, data.velocityX0Buffer, data.velocityY0Buffer, data.velocityZ0Buffer, dt, data.gridSize);
|
||||
advectPass(data.velocityYBuffer, data.velocityY0Buffer, data.velocityX0Buffer, data.velocityY0Buffer, data.velocityZ0Buffer, dt, data.gridSize);
|
||||
advectPass(data.velocityZBuffer, data.velocityZ0Buffer, data.velocityX0Buffer, data.velocityY0Buffer, data.velocityZ0Buffer, dt, data.gridSize);
|
||||
|
||||
setBoundsPass(data.velocityXBuffer, 1, data.gridSize);
|
||||
setBoundsPass(data.velocityYBuffer, 2, data.gridSize);
|
||||
setBoundsPass(data.velocityZBuffer, 3, data.gridSize);
|
||||
graphics->endDebugRegion();
|
||||
|
||||
// swap velocity buffers
|
||||
SWAP(data.velocityX0Buffer, data.velocityXBuffer);
|
||||
SWAP(data.velocityY0Buffer, data.velocityYBuffer);
|
||||
SWAP(data.velocityZ0Buffer, data.velocityZBuffer);
|
||||
|
||||
// diffuse density
|
||||
graphics->beginDebugRegion("DiffuseDensity");
|
||||
Gfx::PShaderBuffer densityCurrent = data.densityBuffer;
|
||||
Gfx::PShaderBuffer densityNext = data.scratchBuffer;
|
||||
Gfx::PShaderBuffer density0 = data.density0Buffer;
|
||||
graphics->copyBuffer(density0, densityCurrent);
|
||||
densityCurrent->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
for (int iteration = 0; iteration < 4; ++iteration) {
|
||||
float a = dt * data.diffusion * (data.gridSize.x - 2) * (data.gridSize.y - 2) * (data.gridSize.z - 2);
|
||||
float c = 1 + 6 * a;
|
||||
linearSolvePass(densityNext, densityCurrent, density0, a, c, data.gridSize);
|
||||
setBoundsPass(densityNext, 0, data.gridSize);
|
||||
SWAP(densityCurrent, densityNext);
|
||||
}
|
||||
graphics->endDebugRegion();
|
||||
graphics->beginDebugRegion("AdvectDensity");
|
||||
advectPass(data.density0Buffer, densityCurrent, data.velocityX0Buffer, data.velocityY0Buffer, data.velocityZ0Buffer, dt, data.gridSize);
|
||||
setBoundsPass(data.density0Buffer, 0, data.gridSize);
|
||||
graphics->endDebugRegion();
|
||||
|
||||
graphics->beginDebugRegion("AdvectLevelSet");
|
||||
advectPass(data.phiBuffer, data.phi0Buffer, data.velocityX0Buffer, data.velocityY0Buffer, data.velocityZ0Buffer, dt, data.gridSize);
|
||||
setBoundsPass(data.phiBuffer, 0, data.gridSize);
|
||||
|
||||
// Reinitialize level set every N frames to restore |grad phi| = 1
|
||||
if (data.frameCounter % reinitInterval == 0) {
|
||||
reinitializeLevelSetPass(data.phiBuffer, data.phi0Buffer, data.gridSize);
|
||||
}
|
||||
++data.frameCounter;
|
||||
|
||||
data.phiBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_TRANSFER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
graphics->copyBuffer(data.phiBuffer, data.phi0Buffer);
|
||||
data.phi0Buffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_TRANSFER_READ_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
}
|
||||
|
||||
void SimulationComputePass::endFrame() {}
|
||||
|
||||
void SimulationComputePass::publishOutputs() {}
|
||||
|
||||
void SimulationComputePass::createRenderPass() {}
|
||||
|
||||
UVector SimulationComputePass::getDispatchSize(const UVector& gridSize, const UVector& threadGroupSize) {
|
||||
return {
|
||||
(gridSize.x + threadGroupSize.x - 1) / threadGroupSize.x,
|
||||
(gridSize.y + threadGroupSize.y - 1) / threadGroupSize.y,
|
||||
(gridSize.z + threadGroupSize.z - 1) / threadGroupSize.z,
|
||||
};
|
||||
}
|
||||
|
||||
void SimulationComputePass::setBoundsPass(Gfx::PShaderBuffer grid, int b, UVector gridSize) {
|
||||
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(getDispatchSize(gridSize, setBounds.threadGroupSize));
|
||||
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(getDispatchSize(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 next, Gfx::PShaderBuffer current, Gfx::PShaderBuffer grid0, float a, float c, UVector gridSize) {
|
||||
Gfx::ODescriptorSet solve = linearSolve.descriptorLayout->allocateDescriptorSet();
|
||||
solve->updateBuffer("next", 0, next);
|
||||
solve->updateBuffer("current", 0, current);
|
||||
solve->updateBuffer("grid0", 0, grid0);
|
||||
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(getDispatchSize(gridSize, linearSolve.threadGroupSize));
|
||||
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, UVector gridSize) {
|
||||
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(getDispatchSize(gridSize, computeDivergence.threadGroupSize));
|
||||
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, UVector gridSize) {
|
||||
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(getDispatchSize(gridSize, project.threadGroupSize));
|
||||
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, UVector gridSize) {
|
||||
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(getDispatchSize(gridSize, advect.threadGroupSize));
|
||||
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);
|
||||
}
|
||||
|
||||
void SimulationComputePass::reinitializeLevelSetPass(Seele::Gfx::PShaderBuffer phi, Seele::Gfx::PShaderBuffer phi0, UVector gridSize) {
|
||||
graphics->beginDebugRegion("ReinitializeLevelSet");
|
||||
// Snapshot current phi into phi0 for the sign function
|
||||
phi->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_TRANSFER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT);
|
||||
graphics->copyBuffer(phi, phi0);
|
||||
phi0->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
phi->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_READ_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);
|
||||
|
||||
float dtau = reinitDtau;
|
||||
for (int i = 0; i < reinitIterations; ++i) {
|
||||
Gfx::ODescriptorSet reinitSet = reinitialize.descriptorLayout->allocateDescriptorSet();
|
||||
reinitSet->updateConstants("dtau", 0, &dtau);
|
||||
reinitSet->updateBuffer("phi", 0, phi);
|
||||
reinitSet->updateBuffer("phi0", 0, phi0);
|
||||
reinitSet->writeChanges();
|
||||
Gfx::OComputeCommand reinitCommand = graphics->createComputeCommand();
|
||||
reinitCommand->bindPipeline(reinitialize.pipeline);
|
||||
reinitCommand->bindDescriptor(reinitSet);
|
||||
reinitCommand->dispatch(getDispatchSize(gridSize, reinitialize.threadGroupSize));
|
||||
graphics->executeCommands(std::move(reinitCommand));
|
||||
|
||||
phi->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);
|
||||
setBoundsPass(phi, 0, gridSize);
|
||||
SWAP(phi, phi0);
|
||||
}
|
||||
graphics->endDebugRegion();
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
#pragma once
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Graphics/Initializer.h"
|
||||
#include "Graphics/RenderPass/RenderPass.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
namespace Seele {
|
||||
class SimulationComputePass : public RenderPass {
|
||||
public:
|
||||
SimulationComputePass(Gfx::PGraphics graphics, PScene scene);
|
||||
virtual ~SimulationComputePass() override;
|
||||
virtual void beginFrame(const 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:
|
||||
UVector getDispatchSize(const UVector& gridSize, const UVector& threadGroupSize);
|
||||
void setBoundsPass(Gfx::PShaderBuffer buffer, int b, UVector gridSize);
|
||||
void linearSolvePass(Gfx::PShaderBuffer next, Seele::Gfx::PShaderBuffer current, Seele::Gfx::PShaderBuffer grid0, float a, float c, UVector gridSize);
|
||||
void divergencePass(Gfx::PShaderBuffer divergence, Seele::Gfx::PShaderBuffer pressure, Seele::Gfx::PShaderBuffer velocityX,
|
||||
Seele::Gfx::PShaderBuffer velocityY, Seele::Gfx::PShaderBuffer velocityZ, UVector gridSize);
|
||||
void projectPass(Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY, Seele::Gfx::PShaderBuffer velocityZ,
|
||||
Seele::Gfx::PShaderBuffer pressure, UVector gridSize);
|
||||
void advectPass(Gfx::PShaderBuffer quantity, Seele::Gfx::PShaderBuffer quantity0, Seele::Gfx::PShaderBuffer velocityX,
|
||||
Seele::Gfx::PShaderBuffer velocityY, Seele::Gfx::PShaderBuffer velocityZ, float dt, UVector gridSize);
|
||||
void reinitializeLevelSetPass(Gfx::PShaderBuffer phi, Seele::Gfx::PShaderBuffer phi0, UVector gridSize);
|
||||
struct SetBounds {
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::OComputeShader shader;
|
||||
Gfx::PComputePipeline pipeline;
|
||||
Gfx::OComputeShader shaderEdges;
|
||||
Gfx::PComputePipeline pipelineEdges;
|
||||
Gfx::OComputeShader shaderCorners;
|
||||
Gfx::PComputePipeline pipelineCorners;
|
||||
constexpr static UVector threadGroupSize = {32, 8, 1};
|
||||
} setBounds;
|
||||
struct LinearSolve {
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::OComputeShader shader;
|
||||
Gfx::PComputePipeline pipeline;
|
||||
constexpr static UVector threadGroupSize = {32, 8, 1};
|
||||
} linearSolve;
|
||||
struct ComputeDivergence {
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::OComputeShader shader;
|
||||
Gfx::PComputePipeline pipeline;
|
||||
constexpr static UVector threadGroupSize = {32, 8, 1};
|
||||
} computeDivergence;
|
||||
struct Project {
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::OComputeShader shader;
|
||||
Gfx::PComputePipeline pipeline;
|
||||
constexpr static UVector threadGroupSize = {32, 8, 1};
|
||||
} project;
|
||||
struct Advect {
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::OComputeShader shader;
|
||||
Gfx::PComputePipeline pipeline;
|
||||
constexpr static UVector threadGroupSize = {32, 8, 1};
|
||||
} advect;
|
||||
struct Reinitialize {
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::OComputeShader shader;
|
||||
Gfx::PComputePipeline pipeline;
|
||||
constexpr static UVector threadGroupSize = {32, 8, 1};
|
||||
} reinitialize;
|
||||
PScene scene;
|
||||
constexpr static float dt = 0.1f;
|
||||
};
|
||||
DEFINE_REF(SimulationComputePass)
|
||||
} // namespace Seele
|
||||
@@ -0,0 +1,103 @@
|
||||
#include "SurfaceExtractPass.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"
|
||||
#include "Math/Vector.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
// Linearly interpolate the position where the isosurface crosses the edge
|
||||
// between two grid points.
|
||||
static Vector vertexInterp(float isolevel, const Vector& p1, const Vector& p2, float v1, float v2) {
|
||||
if (std::abs(v1 - v2) < 1e-10f)
|
||||
return p1;
|
||||
float t = (isolevel - v1) / (v2 - v1);
|
||||
return Vector(p1.x + t * (p2.x - p1.x), p1.y + t * (p2.y - p1.y), p1.z + t * (p2.z - p1.z));
|
||||
}
|
||||
|
||||
SurfaceExtractPass::SurfaceExtractPass(Gfx::PGraphics graphics, PScene scene) : RenderPass(graphics), scene(scene) {
|
||||
pipelineLayout = graphics->createPipelineLayout("SurfaceExtractPipelineLayout");
|
||||
descriptorLayout = graphics->createDescriptorLayout("params");
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "vertexBuffer",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "normalBuffer",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "indexBuffer",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "surfaceCounts",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = "levelSet",
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
});
|
||||
descriptorLayout->create();
|
||||
pipelineLayout->addDescriptorLayout(descriptorLayout);
|
||||
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||
.name = "MarchingCubes",
|
||||
.modules = {"MarchingCubes"},
|
||||
.entryPoints = {{"marchingCubes", "MarchingCubes"}},
|
||||
.rootSignature = pipelineLayout,
|
||||
});
|
||||
pipelineLayout->create();
|
||||
computeShader = graphics->createComputeShader({0});
|
||||
pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||
.computeShader = computeShader,
|
||||
.pipelineLayout = pipelineLayout,
|
||||
});
|
||||
}
|
||||
|
||||
SurfaceExtractPass::~SurfaceExtractPass() {}
|
||||
|
||||
void SurfaceExtractPass::beginFrame(const Seele::Component::Camera&, const Seele::Component::Transform&) {}
|
||||
|
||||
void SurfaceExtractPass::render() {
|
||||
for (auto& [entityID, data] : scene->getFluidScene()->getFluidDataMap()) {
|
||||
data.vertexBuffer->rotateBuffer(data.getVertexBufferSize() * sizeof(float));
|
||||
data.normalBuffer->rotateBuffer(data.getVertexBufferSize() * sizeof(float));
|
||||
data.indexBuffer->rotateBuffer(data.getIndexBufferSize() * sizeof(uint32));
|
||||
uint32 surfaceCountData[4] = {0, 1, 0, 0};
|
||||
data.surfaceCountBuffer->updateContents(0, sizeof(surfaceCountData), surfaceCountData);
|
||||
data.surfaceCountBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||
|
||||
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||
descriptorSet->updateBuffer("vertexBuffer", 0, data.vertexBuffer);
|
||||
descriptorSet->updateBuffer("normalBuffer", 0, data.normalBuffer);
|
||||
descriptorSet->updateBuffer("indexBuffer", 0, data.indexBuffer);
|
||||
descriptorSet->updateBuffer("surfaceCounts", 0, data.surfaceCountBuffer);
|
||||
descriptorSet->updateBuffer("levelSet", 0, data.phiBuffer);
|
||||
descriptorSet->writeChanges();
|
||||
|
||||
Gfx::OComputeCommand cmd = graphics->createComputeCommand();
|
||||
cmd->bindPipeline(pipeline);
|
||||
cmd->bindDescriptor(descriptorSet);
|
||||
cmd->dispatch((data.gridSize + threadGroupSize - 1u) / threadGroupSize);
|
||||
graphics->executeCommands(std::move(cmd));
|
||||
|
||||
data.vertexBuffer->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);
|
||||
data.normalBuffer->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);
|
||||
data.indexBuffer->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);
|
||||
data.surfaceCountBuffer->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
|
||||
Gfx::SE_ACCESS_INDIRECT_COMMAND_READ_BIT, Gfx::SE_PIPELINE_STAGE_DRAW_INDIRECT_BIT);
|
||||
}
|
||||
}
|
||||
|
||||
void SurfaceExtractPass::endFrame() {}
|
||||
|
||||
void SurfaceExtractPass::publishOutputs() {}
|
||||
|
||||
void SurfaceExtractPass::createRenderPass() { }
|
||||
@@ -0,0 +1,29 @@
|
||||
#pragma once
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/RenderPass/RenderPass.h"
|
||||
#include "Graphics/Resources.h"
|
||||
#include "Scene/Scene.h"
|
||||
|
||||
namespace Seele {
|
||||
class SurfaceExtractPass : public RenderPass {
|
||||
public:
|
||||
SurfaceExtractPass(Gfx::PGraphics graphics, PScene scene);
|
||||
virtual ~SurfaceExtractPass() override;
|
||||
virtual void beginFrame(const Component::Camera &camera, const Component::Transform &transform) override;
|
||||
virtual void render() override;
|
||||
virtual void endFrame() override;
|
||||
virtual void publishOutputs() override;
|
||||
virtual void createRenderPass() override;
|
||||
|
||||
private:
|
||||
PScene scene;
|
||||
|
||||
Gfx::OPipelineLayout pipelineLayout;
|
||||
Gfx::ODescriptorLayout descriptorLayout;
|
||||
Gfx::ODescriptorSet descriptorSet;
|
||||
Gfx::OComputeShader computeShader;
|
||||
Gfx::PComputePipeline pipeline;
|
||||
constexpr static UVector threadGroupSize = {16, 8, 1};
|
||||
};
|
||||
DEFINE_REF(SurfaceExtractPass)
|
||||
} // namespace Seele
|
||||
@@ -4,7 +4,39 @@
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
VisibilityPass::VisibilityPass(Gfx::PGraphics graphics) : RenderPass(graphics) {}
|
||||
VisibilityPass::VisibilityPass(Gfx::PGraphics graphics) : RenderPass(graphics) {
|
||||
visibilityDescriptor = graphics->createDescriptorLayout("pVisibilityParams");
|
||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = VISIBILITY_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_SAMPLE_BIT,
|
||||
});
|
||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = CULLINGBUFFER_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
visibilityDescriptor->create();
|
||||
|
||||
visibilityLayout = graphics->createPipelineLayout("VisibilityLayout");
|
||||
visibilityLayout->addDescriptorLayout(visibilityDescriptor);
|
||||
visibilityLayout->addDescriptorLayout(viewParamsLayout);
|
||||
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "Visibility",
|
||||
.modules = {"VisibilityCompute"},
|
||||
.entryPoints = {{"computeMain", "VisibilityCompute"}},
|
||||
.rootSignature = visibilityLayout,
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
visibilityShader = graphics->createComputeShader({0});
|
||||
visibilityLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = visibilityShader;
|
||||
pipelineInfo.pipelineLayout = visibilityLayout;
|
||||
visibilityPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||
}
|
||||
|
||||
VisibilityPass::~VisibilityPass() {}
|
||||
|
||||
@@ -52,37 +84,6 @@ void VisibilityPass::publishOutputs() {
|
||||
uint32_t viewportWidth = viewport->getWidth();
|
||||
uint32_t viewportHeight = viewport->getHeight();
|
||||
threadGroupSize = glm::ceil(glm::vec3(viewportWidth / (float)BLOCK_SIZE, viewportHeight / (float)BLOCK_SIZE, 1));
|
||||
visibilityDescriptor = graphics->createDescriptorLayout("pVisibilityParams");
|
||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = VISIBILITY_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_SAMPLED_IMAGE,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_SAMPLE_BIT,
|
||||
});
|
||||
visibilityDescriptor->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||
.name = CULLINGBUFFER_NAME,
|
||||
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||
.access = Gfx::SE_DESCRIPTOR_ACCESS_READ_BIT | Gfx::SE_DESCRIPTOR_ACCESS_WRITE_BIT,
|
||||
});
|
||||
visibilityDescriptor->create();
|
||||
|
||||
visibilityLayout = graphics->createPipelineLayout("VisibilityLayout");
|
||||
visibilityLayout->addDescriptorLayout(visibilityDescriptor);
|
||||
visibilityLayout->addDescriptorLayout(viewParamsLayout);
|
||||
|
||||
ShaderCompilationInfo createInfo = {
|
||||
.name = "Visibility",
|
||||
.modules = {"VisibilityCompute"},
|
||||
.entryPoints = {{"computeMain", "VisibilityCompute"}},
|
||||
.rootSignature = visibilityLayout,
|
||||
};
|
||||
graphics->beginShaderCompilation(createInfo);
|
||||
visibilityShader = graphics->createComputeShader({0});
|
||||
visibilityLayout->create();
|
||||
|
||||
Gfx::ComputePipelineCreateInfo pipelineInfo;
|
||||
pipelineInfo.computeShader = visibilityShader;
|
||||
pipelineInfo.pipelineLayout = visibilityLayout;
|
||||
visibilityPipeline = graphics->createComputePipeline(std::move(pipelineInfo));
|
||||
|
||||
cullingBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.clearValue = 0xffffffff,
|
||||
|
||||
@@ -134,7 +134,6 @@ void ShaderCompiler::createShaders(ShaderPermutation permutation, Gfx::OPipeline
|
||||
}
|
||||
// createInfo.typeParameter.add({Pair<const char*, const char*>("IVertexData", permutation.vertexDataName)});
|
||||
createInfo.modules.add(permutation.vertexDataName);
|
||||
createInfo.dumpIntermediate = true;
|
||||
|
||||
if (permutation.useMeshShading) {
|
||||
if (permutation.hasTaskShader) {
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Graphics/Enums.h"
|
||||
#include <fmt/format.h>
|
||||
#include <vk_mem_alloc.h>
|
||||
#include <vulkan/vulkan_core.h>
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::Vulkan;
|
||||
@@ -192,7 +193,8 @@ void BufferAllocation::unmap() {
|
||||
Buffer::Buffer(PGraphics graphics, uint64 size, VkBufferUsageFlags usage, Gfx::QueueType queueType, bool dynamic, std::string name,
|
||||
bool createCleared, uint32 clearValue)
|
||||
: graphics(graphics), currentBuffer(0), initialOwner(queueType),
|
||||
usage(usage | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT),
|
||||
usage(usage | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_SRC_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||
(graphics->supportRayTracing() ? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR : 0)),
|
||||
dynamic(dynamic), createCleared(createCleared), name(name), clearValue(clearValue) {
|
||||
if (size > 0) {
|
||||
buffers.add(nullptr);
|
||||
@@ -483,9 +485,8 @@ IndexBuffer::IndexBuffer(PGraphics graphics, const IndexBufferCreateInfo& create
|
||||
: Gfx::IndexBuffer(graphics->getFamilyMapping(), createInfo),
|
||||
Vulkan::Buffer(graphics, createInfo.sourceData.size,
|
||||
VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT |
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT | (graphics->supportRayTracing()
|
||||
? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR
|
||||
: 0),
|
||||
VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
|
||||
(graphics->supportRayTracing() ? VK_BUFFER_USAGE_ACCELERATION_STRUCTURE_BUILD_INPUT_READ_ONLY_BIT_KHR : 0),
|
||||
createInfo.sourceData.owner, false, createInfo.name) {
|
||||
getAlloc()->updateContents(createInfo.sourceData.offset, createInfo.sourceData.size, createInfo.sourceData.data);
|
||||
// getAlloc()->pipelineBarrier(VK_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT, Gfx::SE_ACCESS_INDEX_READ_BIT,
|
||||
|
||||
@@ -455,7 +455,7 @@ void ComputeCommand::bindDescriptor(Gfx::PDescriptorSet descriptor) {
|
||||
}
|
||||
}
|
||||
if (descriptorSet->setHandle->constantsBuffer != nullptr) {
|
||||
descriptorSet->setHandle->bind();
|
||||
descriptorSet->setHandle->constantsBuffer->bind();
|
||||
boundResources.add(PBufferAllocation(descriptorSet->setHandle->constantsBuffer));
|
||||
}
|
||||
|
||||
@@ -482,7 +482,7 @@ void ComputeCommand::bindDescriptor(const Array<Gfx::PDescriptorSet>& descriptor
|
||||
}
|
||||
}
|
||||
if (descriptorSet->setHandle->constantsBuffer != nullptr) {
|
||||
descriptorSet->setHandle->bind();
|
||||
descriptorSet->setHandle->constantsBuffer->bind();
|
||||
boundResources.add(PBufferAllocation(descriptorSet->setHandle->constantsBuffer));
|
||||
}
|
||||
sets[pipeline->getPipelineLayout()->findParameter(descriptorSet->getName())] = descriptorSet->getHandle();
|
||||
|
||||
@@ -175,7 +175,6 @@ Gfx::ODescriptorSet DescriptorPool::allocateDescriptorSet() {
|
||||
};
|
||||
vkSetDebugUtilsObjectNameEXT(graphics->getDevice(), &nameInfo);
|
||||
}
|
||||
cachedHandles[setIndex]->isUsed = true;
|
||||
// Found set, stop searching
|
||||
return new DescriptorSet(graphics, this, cachedHandles[setIndex]);
|
||||
}
|
||||
@@ -191,13 +190,11 @@ void DescriptorPool::reset() {}
|
||||
|
||||
DescriptorSetHandle::DescriptorSetHandle(PGraphics graphics, const std::string& name) : CommandBoundResource(graphics, name) {}
|
||||
|
||||
DescriptorSetHandle::~DescriptorSetHandle() {
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(constantsBuffer));
|
||||
}
|
||||
DescriptorSetHandle::~DescriptorSetHandle() { graphics->getDestructionManager()->queueResourceForDestruction(std::move(constantsBuffer)); }
|
||||
|
||||
DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescriptorSetHandle setHandle)
|
||||
: Gfx::DescriptorSet(owner->getLayout()), setHandle(setHandle),
|
||||
graphics(graphics), owner(owner) {
|
||||
: Gfx::DescriptorSet(owner->getLayout()), setHandle(setHandle), graphics(graphics), owner(owner) {
|
||||
setHandle->isUsed = true;
|
||||
boundResources.resize(owner->getLayout()->bindings.size());
|
||||
for (uint32 i = 0; i < boundResources.size(); ++i) {
|
||||
boundResources[i].resize(owner->getLayout()->bindings[i].descriptorCount);
|
||||
@@ -208,8 +205,10 @@ DescriptorSet::DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescrip
|
||||
constantData.resize(owner->getLayout()->constantsSize);
|
||||
}
|
||||
|
||||
DescriptorSet::~DescriptorSet() {
|
||||
setHandle->isUsed = false;
|
||||
DescriptorSet::~DescriptorSet() {
|
||||
if (setHandle != nullptr) {
|
||||
setHandle->isUsed = false;
|
||||
}
|
||||
}
|
||||
|
||||
void DescriptorSet::updateConstants(const std::string& mappingName, uint32 offset, const void* data) {
|
||||
@@ -406,20 +405,21 @@ void DescriptorSet::writeChanges() {
|
||||
if (setHandle->constantsBuffer != nullptr) {
|
||||
graphics->getDestructionManager()->queueResourceForDestruction(std::move(setHandle->constantsBuffer));
|
||||
}
|
||||
setHandle->constantsBuffer = new BufferAllocation(graphics, owner->getLayout()->getName(),
|
||||
VkBufferCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.size = constantData.size(),
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
},
|
||||
VmaAllocationCreateInfo{
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
},
|
||||
Gfx::QueueType::GRAPHICS);
|
||||
setHandle->constantsBuffer =
|
||||
new BufferAllocation(graphics, owner->getLayout()->getName(),
|
||||
VkBufferCreateInfo{
|
||||
.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO,
|
||||
.pNext = nullptr,
|
||||
.size = constantData.size(),
|
||||
.usage = VK_BUFFER_USAGE_TRANSFER_DST_BIT | VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT,
|
||||
},
|
||||
VmaAllocationCreateInfo{
|
||||
.usage = VMA_MEMORY_USAGE_AUTO,
|
||||
},
|
||||
Gfx::QueueType::GRAPHICS);
|
||||
setHandle->constantsBuffer->updateContents(0, constantData.size(), constantData.data());
|
||||
setHandle->constantsBuffer->pipelineBarrier(Gfx::SE_ACCESS_TRANSFER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_TRANSFER_BIT,
|
||||
Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT);
|
||||
Gfx::SE_ACCESS_UNIFORM_READ_BIT, Gfx::SE_PIPELINE_STAGE_ALL_COMMANDS_BIT);
|
||||
bufferInfos.add(VkDescriptorBufferInfo{
|
||||
.buffer = setHandle->constantsBuffer->buffer,
|
||||
.offset = 0,
|
||||
|
||||
@@ -68,6 +68,10 @@ class DescriptorSet : public Gfx::DescriptorSet {
|
||||
public:
|
||||
DescriptorSet(PGraphics graphics, PDescriptorPool owner, PDescriptorSetHandle setHandle);
|
||||
virtual ~DescriptorSet();
|
||||
DescriptorSet(const DescriptorSet&) = delete;
|
||||
DescriptorSet(DescriptorSet&&) noexcept;
|
||||
DescriptorSet& operator=(const DescriptorSet&) = delete;
|
||||
DescriptorSet& operator=(DescriptorSet&&) noexcept;
|
||||
virtual void writeChanges() override;
|
||||
virtual void updateConstants(const std::string& name, uint32 offset, const void* data) override;
|
||||
virtual void updateBuffer(const std::string& name, uint32 index, Gfx::PShaderBuffer shaderBuffer) override;
|
||||
@@ -91,7 +95,7 @@ class DescriptorSet : public Gfx::DescriptorSet {
|
||||
// would not work anyways, so casts should be safe
|
||||
// Array<void*> cachedData;
|
||||
Array<Array<PCommandBoundResource>> boundResources;
|
||||
PDescriptorSetHandle setHandle;
|
||||
PDescriptorSetHandle setHandle = nullptr;
|
||||
PGraphics graphics;
|
||||
PDescriptorPool owner;
|
||||
friend class DescriptorPool;
|
||||
|
||||
@@ -812,8 +812,7 @@ void Graphics::setupDebugCallback() {
|
||||
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_SEVERITY_INFO_BIT_EXT,
|
||||
.messageSeverity = VK_DEBUG_UTILS_MESSAGE_SEVERITY_ERROR_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_SEVERITY_WARNING_BIT_EXT,
|
||||
.messageType = VK_DEBUG_UTILS_MESSAGE_TYPE_GENERAL_BIT_EXT | VK_DEBUG_UTILS_MESSAGE_TYPE_VALIDATION_BIT_EXT |
|
||||
VK_DEBUG_UTILS_MESSAGE_TYPE_PERFORMANCE_BIT_EXT,
|
||||
.pfnUserCallback = &debugCallback,
|
||||
@@ -849,11 +848,11 @@ void Graphics::pickPhysicalDevice() {
|
||||
|
||||
vkGetPhysicalDeviceProperties2(physicalDevice, &props.get());
|
||||
features.get<VkPhysicalDeviceFeatures2>().features = {
|
||||
.geometryShader = false,
|
||||
.geometryShader = true,
|
||||
.sampleRateShading = true,
|
||||
.fillModeNonSolid = true,
|
||||
.wideLines = false,
|
||||
.pipelineStatisticsQuery = false,
|
||||
.wideLines = true,
|
||||
.pipelineStatisticsQuery = true,
|
||||
.fragmentStoresAndAtomics = true,
|
||||
.shaderInt64 = true,
|
||||
.shaderInt16 = true,
|
||||
@@ -862,12 +861,14 @@ void Graphics::pickPhysicalDevice() {
|
||||
features.get<VkPhysicalDeviceVulkan11Features>().multiview = true;
|
||||
features.get<VkPhysicalDeviceVulkan11Features>().storageBuffer16BitAccess = true;
|
||||
features.get<VkPhysicalDeviceVulkan11Features>().shaderDrawParameters = true;
|
||||
features.get<VkPhysicalDeviceVulkan11Features>().uniformAndStorageBuffer16BitAccess = true;
|
||||
|
||||
features.get<VkPhysicalDeviceVulkan12Features>().descriptorIndexing = true;
|
||||
features.get<VkPhysicalDeviceVulkan12Features>().descriptorBindingPartiallyBound = true;
|
||||
features.get<VkPhysicalDeviceVulkan12Features>().bufferDeviceAddress = true;
|
||||
features.get<VkPhysicalDeviceVulkan12Features>().storageBuffer8BitAccess = true;
|
||||
features.get<VkPhysicalDeviceVulkan12Features>().shaderInt8 = true;
|
||||
features.get<VkPhysicalDeviceVulkan12Features>().uniformAndStorageBuffer8BitAccess = true;
|
||||
|
||||
rayTracingFeatures.get<VkPhysicalDeviceAccelerationStructureFeaturesKHR>().accelerationStructure = true;
|
||||
|
||||
@@ -915,7 +916,7 @@ void Graphics::pickPhysicalDevice() {
|
||||
shaderFloatControls = true;
|
||||
}
|
||||
}
|
||||
rayTracingEnabled = rayTracingPipelineSupport && accelerationStructureSupport && hostOperationsSupport && deviceAddressSupport &&
|
||||
rayTracingEnabled = false &&rayTracingPipelineSupport && accelerationStructureSupport && hostOperationsSupport && deviceAddressSupport &&
|
||||
descriptorIndexingSupport && spirv14Support && shaderFloatControls;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,21 +48,79 @@ std::filesystem::path findExistingDirectory(std::initializer_list<std::filesyste
|
||||
return {};
|
||||
}
|
||||
|
||||
bool containsDownstreamCompilerArtifacts(const std::filesystem::path& directory) {
|
||||
std::error_code error;
|
||||
if (!std::filesystem::exists(directory, error) || !std::filesystem::is_directory(directory, error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directory, error)) {
|
||||
if (error || !entry.is_regular_file(error)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto fileName = entry.path().filename().string();
|
||||
if (fileName.rfind("slang-glslang", 0) == 0 || fileName.rfind("spirv-opt", 0) == 0 || fileName.rfind("spirv-dis", 0) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hasArtifactWithPrefix(const std::filesystem::path& directory, const char* prefix) {
|
||||
std::error_code error;
|
||||
if (!std::filesystem::exists(directory, error) || !std::filesystem::is_directory(directory, error)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (const auto& entry : std::filesystem::directory_iterator(directory, error)) {
|
||||
if (error || !entry.is_regular_file(error)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entry.path().filename().string().rfind(prefix, 0) == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
std::filesystem::path findDownstreamCompilerDirectory(std::initializer_list<std::filesystem::path> candidates) {
|
||||
for (const auto& candidate : candidates) {
|
||||
if (containsDownstreamCompilerArtifacts(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
}
|
||||
|
||||
return findExistingDirectory(candidates);
|
||||
}
|
||||
|
||||
void configureDownstreamCompilers(slang::IGlobalSession* session) {
|
||||
const auto executableDirectory = getExecutableDirectory();
|
||||
const auto currentDirectory = std::filesystem::current_path();
|
||||
const auto glslangDirectory = findExistingDirectory({
|
||||
const auto glslangDirectory = findDownstreamCompilerDirectory({
|
||||
executableDirectory,
|
||||
executableDirectory / "Seele",
|
||||
executableDirectory / "vcpkg_installed" / "x64-linux" / "lib",
|
||||
currentDirectory / "build",
|
||||
currentDirectory / "build" / "Seele",
|
||||
currentDirectory / "Seele",
|
||||
currentDirectory / "vcpkg_installed" / "x64-linux" / "lib",
|
||||
});
|
||||
|
||||
if (!glslangDirectory.empty()) {
|
||||
const std::string path = glslangDirectory.string();
|
||||
session->setDownstreamCompilerPath(SLANG_PASS_THROUGH_GLSLANG, path.c_str());
|
||||
session->setDownstreamCompilerPath(SLANG_PASS_THROUGH_SPIRV_OPT, path.c_str());
|
||||
session->setDownstreamCompilerPath(SLANG_PASS_THROUGH_SPIRV_DIS, path.c_str());
|
||||
if (hasArtifactWithPrefix(glslangDirectory, "slang-glslang") || hasArtifactWithPrefix(glslangDirectory, "libslang-glslang")) {
|
||||
session->setDownstreamCompilerPath(SLANG_PASS_THROUGH_GLSLANG, path.c_str());
|
||||
}
|
||||
if (hasArtifactWithPrefix(glslangDirectory, "spirv-opt")) {
|
||||
session->setDownstreamCompilerPath(SLANG_PASS_THROUGH_SPIRV_OPT, path.c_str());
|
||||
}
|
||||
if (hasArtifactWithPrefix(glslangDirectory, "spirv-dis")) {
|
||||
session->setDownstreamCompilerPath(SLANG_PASS_THROUGH_SPIRV_DIS, path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Avoid optional SPIR-V downstream tools that are often unavailable in RenderDoc launch environments.
|
||||
@@ -130,10 +188,9 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg
|
||||
sessionDesc.preprocessorMacros = macros.data();
|
||||
slang::TargetDesc targetDesc = {};
|
||||
targetDesc.format = target;
|
||||
targetDesc.flags = SLANG_TARGET_FLAG_GENERATE_SPIRV_DIRECTLY;
|
||||
sessionDesc.targetCount = 1;
|
||||
sessionDesc.targets = &targetDesc;
|
||||
StaticArray<const char*, 7> searchPaths = {"shaders/", "shaders/lib/", "shaders/raytracing/", "shaders/terrain", "shaders/game", "shaders/generated/", "Seele/shaders/lib/"};
|
||||
StaticArray<const char*, 7> searchPaths = {"shaders/", "shaders/lib/", "shaders/raytracing/", "shaders/terrain", "shaders/game", "shaders/generated/", "shaders/fluid"};
|
||||
sessionDesc.searchPaths = searchPaths.data();
|
||||
sessionDesc.searchPathCount = searchPaths.size();
|
||||
|
||||
@@ -184,16 +241,6 @@ void Seele::beginCompilation(const ShaderCompilationInfo& info, SlangCompileTarg
|
||||
layout->addMapping(param->getName(), param->getBindingIndex());
|
||||
}
|
||||
|
||||
// workaround
|
||||
if (info.name == "RayGenMiss")
|
||||
{
|
||||
layout->addMapping("pScene", 2);
|
||||
layout->addMapping("pLightEnv", 3);
|
||||
layout->addMapping("pResources", 4);
|
||||
layout->addMapping("pRayTracingParams", 5);
|
||||
}
|
||||
//layout->addMapping("pVertexData", 1);
|
||||
// layout->addMapping("pWaterMaterial", 1);
|
||||
}
|
||||
|
||||
Pair<Slang::ComPtr<slang::IBlob>, std::string> Seele::generateShader(const ShaderCreateInfo& createInfo) {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
target_sources(Engine
|
||||
PRIVATE
|
||||
EventManager.h
|
||||
FluidScene.h
|
||||
FluidScene.cpp
|
||||
LightEnvironment.h
|
||||
LightEnvironment.cpp
|
||||
Util.h
|
||||
@@ -11,6 +13,7 @@ target_sources(Engine
|
||||
PUBLIC FILE_SET HEADERS
|
||||
FILES
|
||||
EventManager.h
|
||||
FluidScene.h
|
||||
LightEnvironment.h
|
||||
Util.h
|
||||
Scene.h)
|
||||
@@ -0,0 +1,173 @@
|
||||
#include "FluidScene.h"
|
||||
#include "Graphics/Enums.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
FluidScene::FluidScene(Gfx::PGraphics graphics) : graphics(graphics) {}
|
||||
|
||||
FluidScene::~FluidScene() {}
|
||||
|
||||
void FluidScene::updateFluidData(uint32 entityID, const Component::Transform& transform, const Component::FluidGrid& grid) {
|
||||
if (!fluidDataMap.contains(entityID)) {
|
||||
auto& data = fluidDataMap[entityID];
|
||||
uint64 totalCells = (uint64)grid.gridSize.x * grid.gridSize.y * grid.gridSize.z;
|
||||
uint64 bufferSize = totalCells * sizeof(float);
|
||||
Array<float> initialDensity(bufferSize / sizeof(float));
|
||||
Array<float> initialVelocityX(bufferSize / sizeof(float));
|
||||
Array<float> initialVelocityY(bufferSize / sizeof(float));
|
||||
Array<float> initialVelocityZ(bufferSize / sizeof(float));
|
||||
Array<float> initialPhi(bufferSize / sizeof(float));
|
||||
|
||||
// Initialize level set to positive (outside) everywhere
|
||||
float halfGridX = static_cast<float>(grid.gridSize.x) * 0.5f;
|
||||
float halfGridY = static_cast<float>(grid.gridSize.y) * 0.5f;
|
||||
float radius = static_cast<float>(grid.gridSize.x) * 0.2f;
|
||||
// Place sphere center in the lower portion of the grid
|
||||
float cx = halfGridX;
|
||||
float cy = halfGridY;
|
||||
float cz = static_cast<float>(grid.gridSize.z) * 0.3f;
|
||||
for (uint32 z = 1; z < grid.gridSize.z - 1; ++z) {
|
||||
for (uint32 y = 1; y < grid.gridSize.y - 1; ++y) {
|
||||
for (uint32 x = 1; x < grid.gridSize.x - 1; ++x) {
|
||||
uint32 idx = x + grid.gridSize.x * y + grid.gridSize.x * grid.gridSize.y * z;
|
||||
float dx = static_cast<float>(x) - cx;
|
||||
float dy = static_cast<float>(y) - cy;
|
||||
float dz = static_cast<float>(z) - cz;
|
||||
float dist = std::sqrt(dx * dx + dy * dy + dz * dz);
|
||||
initialPhi[idx] = dist - radius;
|
||||
if (dist < radius) {
|
||||
initialDensity[idx] = 1.0f;
|
||||
// Give an initial upward velocity to kick the simulation
|
||||
initialVelocityZ[idx] = 5.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.phiBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "PhiBuffer",
|
||||
});
|
||||
data.phi0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
.data = (uint8*)initialPhi.data(),
|
||||
},
|
||||
.name = "Phi0Buffer",
|
||||
});
|
||||
data.densityBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "DensityBuffer",
|
||||
});
|
||||
data.density0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
.data = (uint8*)initialDensity.data(),
|
||||
},
|
||||
.name = "Density0Buffer",
|
||||
});
|
||||
data.scratchBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "ScratchBuffer",
|
||||
});
|
||||
data.velocityXNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityXNextBuffer",
|
||||
});
|
||||
data.velocityYNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityYNextBuffer",
|
||||
});
|
||||
data.velocityZNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityZNextBuffer",
|
||||
});
|
||||
data.velocityXBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityXBuffer",
|
||||
});
|
||||
data.velocityYBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityYBuffer",
|
||||
});
|
||||
data.velocityZBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
},
|
||||
.name = "VelocityZBuffer",
|
||||
});
|
||||
data.velocityX0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
.data = (uint8*)initialVelocityX.data(),
|
||||
},
|
||||
.name = "VelocityX0Buffer",
|
||||
});
|
||||
data.velocityY0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
.data = (uint8*)initialVelocityY.data(),
|
||||
},
|
||||
.name = "VelocityY0Buffer",
|
||||
});
|
||||
data.velocityZ0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData =
|
||||
{
|
||||
.size = bufferSize,
|
||||
.data = (uint8*)initialVelocityZ.data(),
|
||||
},
|
||||
.name = "VelocityZ0Buffer",
|
||||
});
|
||||
data.vertexBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.name = "VertexBuffer",
|
||||
});
|
||||
data.normalBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.name = "NormalBuffer",
|
||||
});
|
||||
data.indexBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.name = "IndexBuffer",
|
||||
});
|
||||
data.surfaceCountBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||
.sourceData = {
|
||||
.size = 4 * sizeof(uint32),
|
||||
},
|
||||
.usage = Gfx::SE_BUFFER_USAGE_INDIRECT_BUFFER_BIT,
|
||||
.name = "SurfaceCountBuffer",
|
||||
});
|
||||
}
|
||||
auto& data = fluidDataMap[entityID];
|
||||
data.transform = transform.transform;
|
||||
data.cellSize = grid.cellSize;
|
||||
data.viscosity = grid.viscosity;
|
||||
data.diffusion = grid.diffusion;
|
||||
data.gridSize = grid.gridSize;
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
#pragma once
|
||||
#include "Component/FluidGrid.h"
|
||||
#include "Component/Transform.h"
|
||||
#include "Containers/Array.h"
|
||||
#include "Containers/Map.h"
|
||||
#include "Graphics/Buffer.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Shader.h"
|
||||
#include "Math/Transform.h"
|
||||
#include "Math/Vector.h"
|
||||
#include "MinimalEngine.h"
|
||||
|
||||
namespace Seele {
|
||||
class FluidScene {
|
||||
public:
|
||||
FluidScene(Gfx::PGraphics graphics);
|
||||
virtual ~FluidScene();
|
||||
struct FluidData {
|
||||
Math::Transform transform;
|
||||
float cellSize;
|
||||
float viscosity;
|
||||
float diffusion;
|
||||
UVector gridSize;
|
||||
Gfx::OShaderBuffer phiBuffer;
|
||||
Gfx::OShaderBuffer phi0Buffer;
|
||||
Gfx::OShaderBuffer densityBuffer;
|
||||
Gfx::OShaderBuffer density0Buffer;
|
||||
Gfx::OShaderBuffer scratchBuffer;
|
||||
Gfx::OShaderBuffer velocityXNextBuffer;
|
||||
Gfx::OShaderBuffer velocityYNextBuffer;
|
||||
Gfx::OShaderBuffer velocityZNextBuffer;
|
||||
Gfx::OShaderBuffer velocityXBuffer;
|
||||
Gfx::OShaderBuffer velocityYBuffer;
|
||||
Gfx::OShaderBuffer velocityZBuffer;
|
||||
Gfx::OShaderBuffer velocityX0Buffer;
|
||||
Gfx::OShaderBuffer velocityY0Buffer;
|
||||
Gfx::OShaderBuffer velocityZ0Buffer;
|
||||
Gfx::OShaderBuffer vertexBuffer;
|
||||
Gfx::OShaderBuffer normalBuffer;
|
||||
Gfx::OShaderBuffer indexBuffer;
|
||||
Gfx::OShaderBuffer surfaceCountBuffer;
|
||||
uint32 frameCounter = 0;
|
||||
constexpr uint getVertexBufferSize() {
|
||||
// Max 5 triangles per cell, 3 vertices per triangle
|
||||
return gridSize.x * gridSize.y * gridSize.z * 15;
|
||||
}
|
||||
constexpr uint getIndexBufferSize() { return gridSize.x * gridSize.y * gridSize.z * 15; }
|
||||
};
|
||||
void updateFluidData(uint32 entityID, const Component::Transform& transform, const Component::FluidGrid& grid);
|
||||
const Map<uint32, FluidData>& getFluidDataMap() const { return fluidDataMap; }
|
||||
|
||||
private:
|
||||
Gfx::PGraphics graphics;
|
||||
Map<uint32, FluidData> fluidDataMap;
|
||||
};
|
||||
DEFINE_REF(FluidScene)
|
||||
} // namespace Seele
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "LightEnvironment.h"
|
||||
#include "Asset/AssetRegistry.h"
|
||||
#include "Asset/EnvironmentMapAsset.h"
|
||||
#include "Graphics/Descriptor.h"
|
||||
#include "Asset/EnvironmentMapAsset.h"
|
||||
#include "Graphics/Enums.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
|
||||
|
||||
@@ -1,22 +1,14 @@
|
||||
#include "Scene.h"
|
||||
#include "Actor/PointLightActor.h"
|
||||
#include "Asset/MaterialAsset.h"
|
||||
#include "Asset/TextureAsset.h"
|
||||
#include "Component/DirectionalLight.h"
|
||||
#include "Component/Mesh.h"
|
||||
#include "Component/PointLight.h"
|
||||
#include "Component/Transform.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "Graphics/Mesh.h"
|
||||
#include "Graphics/StaticMeshVertexData.h"
|
||||
|
||||
using namespace Seele;
|
||||
|
||||
Scene::Scene(Gfx::PGraphics graphics)
|
||||
: graphics(graphics), lightEnv(new LightEnvironment(graphics)), physics(registry) {}
|
||||
: graphics(graphics), lightEnv(new LightEnvironment(graphics)), fluidScene(new FluidScene(graphics)), physics(registry) {}
|
||||
|
||||
Scene::~Scene() {}
|
||||
|
||||
void Scene::bakeLighting() {}
|
||||
|
||||
void Scene::update(float deltaTime) { physics.update(deltaTime); }
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
#pragma once
|
||||
#include "MinimalEngine.h"
|
||||
#include "Component/Skybox.h"
|
||||
#include "Graphics/Graphics.h"
|
||||
#include "LightEnvironment.h"
|
||||
#include "Physics/PhysicsSystem.h"
|
||||
#include "FluidScene.h"
|
||||
#include <entt/entt.hpp>
|
||||
#include <iostream>
|
||||
|
||||
|
||||
namespace Seele {
|
||||
DECLARE_REF(Material)
|
||||
@@ -33,12 +31,14 @@ class Scene {
|
||||
template <typename Component> auto constructCallback() { return registry.on_construct<Component>(); }
|
||||
template <typename Component> auto destroyCallback() { return registry.on_destroy<Component>(); }
|
||||
PLightEnvironment getLightEnvironment() { return lightEnv; }
|
||||
PFluidScene getFluidScene() { return fluidScene; }
|
||||
Gfx::PGraphics getGraphics() const { return graphics; }
|
||||
entt::registry registry;
|
||||
|
||||
private:
|
||||
Gfx::PGraphics graphics;
|
||||
OLightEnvironment lightEnv;
|
||||
OFluidScene fluidScene;
|
||||
PhysicsSystem physics;
|
||||
Array<Gfx::OTexture2D> lightMaps;
|
||||
};
|
||||
|
||||
@@ -5,6 +5,8 @@ target_sources(Engine
|
||||
ComponentSystem.h
|
||||
Executor.h
|
||||
Executor.cpp
|
||||
FluidUpdater.h
|
||||
FluidUpdater.cpp
|
||||
KeyboardInput.h
|
||||
KeyboardInput.cpp
|
||||
LightGather.h
|
||||
@@ -21,6 +23,7 @@ target_sources(Engine
|
||||
CameraUpdater.h
|
||||
ComponentSystem.h
|
||||
Executor.h
|
||||
FluidUpdater.h
|
||||
KeyboardInput.h
|
||||
LightGather.h
|
||||
MeshUpdater.h
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#include "FluidUpdater.h"
|
||||
|
||||
using namespace Seele;
|
||||
using namespace Seele::System;
|
||||
|
||||
FluidUpdater::FluidUpdater(PScene scene) : ComponentSystem(scene) {}
|
||||
|
||||
FluidUpdater::~FluidUpdater() {}
|
||||
|
||||
void FluidUpdater::update(entt::entity id, Component::FluidGrid &grid, Component::Transform &transform) {
|
||||
auto fluidScene = scene->getFluidScene();
|
||||
fluidScene->updateFluidData((uint32)id, transform, grid);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
#include "Component/FluidGrid.h"
|
||||
#include "Component/Transform.h"
|
||||
#include "ComponentSystem.h"
|
||||
|
||||
namespace Seele {
|
||||
namespace System {
|
||||
class FluidUpdater : public ComponentSystem<Component::FluidGrid, Component::Transform> {
|
||||
public:
|
||||
FluidUpdater(PScene scene);
|
||||
virtual ~FluidUpdater();
|
||||
|
||||
virtual void update(entt::entity id, Component::FluidGrid& grid, Component::Transform& transform);
|
||||
|
||||
private:
|
||||
};
|
||||
} // namespace System
|
||||
} // namespace Seele
|
||||
@@ -4,12 +4,16 @@
|
||||
#include "Graphics/RenderPass/BasePass.h"
|
||||
#include "Graphics/RenderPass/CachedDepthPass.h"
|
||||
#include "Graphics/RenderPass/DepthCullingPass.h"
|
||||
#include "Graphics/RenderPass/FluidRenderPass.h"
|
||||
#include "Graphics/RenderPass/LightCullingPass.h"
|
||||
#include "Graphics/RenderPass/RayTracingPass.h"
|
||||
#include "Graphics/RenderPass/ShadowPass.h"
|
||||
#include "Graphics/RenderPass/SimulationComputePass.h"
|
||||
#include "Graphics/RenderPass/SurfaceExtractPass.h"
|
||||
#include "Graphics/RenderPass/ToneMappingPass.h"
|
||||
#include "Graphics/RenderPass/VisibilityPass.h"
|
||||
#include "Graphics/RenderPass/ShadowPass.h"
|
||||
#include "System/CameraUpdater.h"
|
||||
#include "System/FluidUpdater.h"
|
||||
#include "System/LightGather.h"
|
||||
#include "System/MeshUpdater.h"
|
||||
#include "Window/Window.h"
|
||||
@@ -25,11 +29,17 @@ GameView::GameView(Gfx::PGraphics graphics, PWindow window, const ViewportCreate
|
||||
renderGraph.addPass(new LightCullingPass(graphics, scene));
|
||||
renderGraph.addPass(new ShadowPass(graphics, scene));
|
||||
renderGraph.addPass(new BasePass(graphics, scene));
|
||||
// renderGraph.addPass(new SimulationComputePass(graphics, scene));
|
||||
// renderGraph.addPass(new SurfaceExtractPass(graphics, scene));
|
||||
// renderGraph.addPass(new FluidRenderPass(graphics, scene));
|
||||
renderGraph.addPass(new ToneMappingPass(graphics));
|
||||
renderGraph.setViewport(viewport);
|
||||
renderGraph.createRenderPass();
|
||||
if (graphics->supportRayTracing()) {
|
||||
rayTracingGraph.addPass(new RayTracingPass(graphics, scene));
|
||||
rayTracingGraph.addPass(new SimulationComputePass(graphics, scene));
|
||||
rayTracingGraph.addPass(new SurfaceExtractPass(graphics, scene));
|
||||
rayTracingGraph.addPass(new FluidRenderPass(graphics, scene));
|
||||
rayTracingGraph.addPass(new ToneMappingPass(graphics));
|
||||
rayTracingGraph.setViewport(viewport);
|
||||
rayTracingGraph.createRenderPass();
|
||||
@@ -90,12 +100,15 @@ void GameView::reloadGame() {
|
||||
System::OKeyboardInput keyInput = new System::KeyboardInput(scene);
|
||||
keyboardSystem = keyInput;
|
||||
systemGraph->addSystem(std::move(keyInput));
|
||||
systemGraph->addSystem(new System::FluidUpdater(scene));
|
||||
systemGraph->addSystem(new System::LightGather(scene));
|
||||
systemGraph->addSystem(new System::MeshUpdater(scene));
|
||||
systemGraph->addSystem(new System::CameraUpdater(scene));
|
||||
}
|
||||
|
||||
void GameView::keyCallback(KeyCode code, InputAction action, KeyModifierFlags modifier) { keyboardSystem->keyCallback(code, action, modifier); }
|
||||
void GameView::keyCallback(KeyCode code, InputAction action, KeyModifierFlags modifier) {
|
||||
keyboardSystem->keyCallback(code, action, modifier);
|
||||
}
|
||||
|
||||
void GameView::mouseMoveCallback(double xPos, double yPos) { keyboardSystem->mouseCallback(xPos, yPos); }
|
||||
|
||||
|
||||
Reference in New Issue
Block a user