Initial commit
This commit is contained in:
+297
@@ -0,0 +1,297 @@
|
|||||||
|
---
|
||||||
|
Language: Cpp
|
||||||
|
AccessModifierOffset: -2
|
||||||
|
AlignAfterOpenBracket: Align
|
||||||
|
AlignArrayOfStructures: None
|
||||||
|
AlignConsecutiveAssignments:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionDeclarations: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: true
|
||||||
|
AlignConsecutiveBitFields:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionDeclarations: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveDeclarations:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionDeclarations: true
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveMacros:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionDeclarations: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveShortCaseStatements:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCaseArrows: false
|
||||||
|
AlignCaseColons: false
|
||||||
|
AlignConsecutiveTableGenBreakingDAGArgColons:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionDeclarations: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveTableGenCondOperatorColons:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionDeclarations: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignConsecutiveTableGenDefinitionColons:
|
||||||
|
Enabled: false
|
||||||
|
AcrossEmptyLines: false
|
||||||
|
AcrossComments: false
|
||||||
|
AlignCompound: false
|
||||||
|
AlignFunctionDeclarations: false
|
||||||
|
AlignFunctionPointers: false
|
||||||
|
PadOperators: false
|
||||||
|
AlignEscapedNewlines: Right
|
||||||
|
AlignOperands: Align
|
||||||
|
AlignTrailingComments:
|
||||||
|
Kind: Always
|
||||||
|
OverEmptyLines: 0
|
||||||
|
AllowAllArgumentsOnNextLine: true
|
||||||
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
|
AllowBreakBeforeNoexceptSpecifier: Never
|
||||||
|
AllowShortBlocksOnASingleLine: Never
|
||||||
|
AllowShortCaseExpressionOnASingleLine: true
|
||||||
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
|
AllowShortCompoundRequirementOnASingleLine: true
|
||||||
|
AllowShortEnumsOnASingleLine: true
|
||||||
|
AllowShortFunctionsOnASingleLine: All
|
||||||
|
AllowShortIfStatementsOnASingleLine: Never
|
||||||
|
AllowShortLambdasOnASingleLine: All
|
||||||
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
AllowShortNamespacesOnASingleLine: false
|
||||||
|
AlwaysBreakAfterDefinitionReturnType: None
|
||||||
|
AlwaysBreakBeforeMultilineStrings: false
|
||||||
|
AttributeMacros:
|
||||||
|
- __capability
|
||||||
|
BinPackArguments: true
|
||||||
|
BinPackLongBracedList: true
|
||||||
|
BinPackParameters: BinPack
|
||||||
|
BitFieldColonSpacing: Both
|
||||||
|
BracedInitializerIndentWidth: -1
|
||||||
|
BraceWrapping:
|
||||||
|
AfterCaseLabel: false
|
||||||
|
AfterClass: false
|
||||||
|
AfterControlStatement: Never
|
||||||
|
AfterEnum: false
|
||||||
|
AfterExternBlock: false
|
||||||
|
AfterFunction: false
|
||||||
|
AfterNamespace: false
|
||||||
|
AfterObjCDeclaration: false
|
||||||
|
AfterStruct: false
|
||||||
|
AfterUnion: false
|
||||||
|
BeforeCatch: false
|
||||||
|
BeforeElse: false
|
||||||
|
BeforeLambdaBody: false
|
||||||
|
BeforeWhile: false
|
||||||
|
IndentBraces: false
|
||||||
|
SplitEmptyFunction: true
|
||||||
|
SplitEmptyRecord: true
|
||||||
|
SplitEmptyNamespace: true
|
||||||
|
BreakAdjacentStringLiterals: true
|
||||||
|
BreakAfterAttributes: Leave
|
||||||
|
BreakAfterJavaFieldAnnotations: false
|
||||||
|
BreakAfterReturnType: None
|
||||||
|
BreakArrays: true
|
||||||
|
BreakBeforeBinaryOperators: None
|
||||||
|
BreakBeforeConceptDeclarations: Always
|
||||||
|
BreakBeforeBraces: Attach
|
||||||
|
BreakBeforeInlineASMColon: OnlyMultiline
|
||||||
|
BreakBeforeTemplateCloser: false
|
||||||
|
BreakBeforeTernaryOperators: true
|
||||||
|
BreakBinaryOperations: Never
|
||||||
|
BreakConstructorInitializers: BeforeColon
|
||||||
|
BreakFunctionDefinitionParameters: false
|
||||||
|
BreakInheritanceList: BeforeColon
|
||||||
|
BreakStringLiterals: true
|
||||||
|
BreakTemplateDeclarations: MultiLine
|
||||||
|
ColumnLimit: 140
|
||||||
|
CommentPragmas: '^ IWYU pragma:'
|
||||||
|
CompactNamespaces: false
|
||||||
|
ConstructorInitializerIndentWidth: 4
|
||||||
|
ContinuationIndentWidth: 4
|
||||||
|
Cpp11BracedListStyle: true
|
||||||
|
DerivePointerAlignment: false
|
||||||
|
DisableFormat: false
|
||||||
|
EmptyLineAfterAccessModifier: Never
|
||||||
|
EmptyLineBeforeAccessModifier: LogicalBlock
|
||||||
|
EnumTrailingComma: Leave
|
||||||
|
ExperimentalAutoDetectBinPacking: false
|
||||||
|
FixNamespaceComments: true
|
||||||
|
ForEachMacros:
|
||||||
|
- foreach
|
||||||
|
- Q_FOREACH
|
||||||
|
- BOOST_FOREACH
|
||||||
|
IfMacros:
|
||||||
|
- KJ_IF_MAYBE
|
||||||
|
IncludeBlocks: Preserve
|
||||||
|
IncludeCategories:
|
||||||
|
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
|
||||||
|
Priority: 2
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||||
|
Priority: 3
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
- Regex: '.*'
|
||||||
|
Priority: 1
|
||||||
|
SortPriority: 0
|
||||||
|
CaseSensitive: false
|
||||||
|
IncludeIsMainRegex: '(Test)?$'
|
||||||
|
IncludeIsMainSourceRegex: ''
|
||||||
|
IndentAccessModifiers: false
|
||||||
|
IndentCaseBlocks: false
|
||||||
|
IndentCaseLabels: false
|
||||||
|
IndentExportBlock: true
|
||||||
|
IndentExternBlock: AfterExternBlock
|
||||||
|
IndentGotoLabels: true
|
||||||
|
IndentPPDirectives: None
|
||||||
|
IndentRequiresClause: true
|
||||||
|
IndentWidth: 2
|
||||||
|
IndentWrappedFunctionNames: false
|
||||||
|
InsertBraces: false
|
||||||
|
InsertNewlineAtEOF: false
|
||||||
|
InsertTrailingCommas: None
|
||||||
|
IntegerLiteralSeparator:
|
||||||
|
Binary: 0
|
||||||
|
BinaryMinDigits: 0
|
||||||
|
Decimal: 0
|
||||||
|
DecimalMinDigits: 0
|
||||||
|
Hex: 0
|
||||||
|
HexMinDigits: 0
|
||||||
|
JavaScriptQuotes: Leave
|
||||||
|
JavaScriptWrapImports: true
|
||||||
|
KeepEmptyLines:
|
||||||
|
AtEndOfFile: false
|
||||||
|
AtStartOfBlock: true
|
||||||
|
AtStartOfFile: true
|
||||||
|
KeepFormFeed: false
|
||||||
|
LambdaBodyIndentation: Signature
|
||||||
|
LineEnding: DeriveLF
|
||||||
|
MacroBlockBegin: ''
|
||||||
|
MacroBlockEnd: ''
|
||||||
|
MainIncludeChar: Quote
|
||||||
|
MaxEmptyLinesToKeep: 1
|
||||||
|
NamespaceIndentation: None
|
||||||
|
ObjCBinPackProtocolList: Auto
|
||||||
|
ObjCBlockIndentWidth: 2
|
||||||
|
ObjCBreakBeforeNestedBlockParam: true
|
||||||
|
ObjCSpaceAfterProperty: false
|
||||||
|
ObjCSpaceBeforeProtocolList: true
|
||||||
|
OneLineFormatOffRegex: ''
|
||||||
|
PackConstructorInitializers: BinPack
|
||||||
|
PenaltyBreakAssignment: 2
|
||||||
|
PenaltyBreakBeforeFirstCallParameter: 19
|
||||||
|
PenaltyBreakBeforeMemberAccess: 150
|
||||||
|
PenaltyBreakComment: 300
|
||||||
|
PenaltyBreakFirstLessLess: 120
|
||||||
|
PenaltyBreakOpenParenthesis: 0
|
||||||
|
PenaltyBreakScopeResolution: 500
|
||||||
|
PenaltyBreakString: 1000
|
||||||
|
PenaltyBreakTemplateDeclaration: 10
|
||||||
|
PenaltyExcessCharacter: 1000000
|
||||||
|
PenaltyIndentedWhitespace: 0
|
||||||
|
PenaltyReturnTypeOnItsOwnLine: 60
|
||||||
|
PointerAlignment: Right
|
||||||
|
PPIndentWidth: -1
|
||||||
|
QualifierAlignment: Leave
|
||||||
|
ReferenceAlignment: Pointer
|
||||||
|
ReflowComments: Always
|
||||||
|
RemoveBracesLLVM: false
|
||||||
|
RemoveEmptyLinesInUnwrappedLines: false
|
||||||
|
RemoveParentheses: Leave
|
||||||
|
RemoveSemicolon: false
|
||||||
|
RequiresClausePosition: OwnLine
|
||||||
|
RequiresExpressionIndentation: OuterScope
|
||||||
|
SeparateDefinitionBlocks: Leave
|
||||||
|
ShortNamespaceLines: 1
|
||||||
|
SkipMacroDefinitionBody: false
|
||||||
|
SortIncludes:
|
||||||
|
Enabled: true
|
||||||
|
IgnoreCase: false
|
||||||
|
SortJavaStaticImport: Before
|
||||||
|
SortUsingDeclarations: LexicographicNumeric
|
||||||
|
SpaceAfterCStyleCast: false
|
||||||
|
SpaceAfterLogicalNot: false
|
||||||
|
SpaceAfterOperatorKeyword: false
|
||||||
|
SpaceAfterTemplateKeyword: true
|
||||||
|
SpaceAroundPointerQualifiers: Default
|
||||||
|
SpaceBeforeAssignmentOperators: true
|
||||||
|
SpaceBeforeCaseColon: false
|
||||||
|
SpaceBeforeCpp11BracedList: false
|
||||||
|
SpaceBeforeCtorInitializerColon: true
|
||||||
|
SpaceBeforeInheritanceColon: true
|
||||||
|
SpaceBeforeJsonColon: false
|
||||||
|
SpaceBeforeParens: ControlStatements
|
||||||
|
SpaceBeforeParensOptions:
|
||||||
|
AfterControlStatements: true
|
||||||
|
AfterForeachMacros: true
|
||||||
|
AfterFunctionDefinitionName: false
|
||||||
|
AfterFunctionDeclarationName: false
|
||||||
|
AfterIfMacros: true
|
||||||
|
AfterNot: false
|
||||||
|
AfterOverloadedOperator: false
|
||||||
|
AfterPlacementOperator: true
|
||||||
|
AfterRequiresInClause: false
|
||||||
|
AfterRequiresInExpression: false
|
||||||
|
BeforeNonEmptyParentheses: false
|
||||||
|
SpaceBeforeRangeBasedForLoopColon: true
|
||||||
|
SpaceBeforeSquareBrackets: false
|
||||||
|
SpaceInEmptyBlock: false
|
||||||
|
SpacesBeforeTrailingComments: 1
|
||||||
|
SpacesInAngles: Never
|
||||||
|
SpacesInContainerLiterals: true
|
||||||
|
SpacesInLineCommentPrefix:
|
||||||
|
Minimum: 1
|
||||||
|
Maximum: -1
|
||||||
|
SpacesInParens: Never
|
||||||
|
SpacesInParensOptions:
|
||||||
|
ExceptDoubleParentheses: false
|
||||||
|
InCStyleCasts: false
|
||||||
|
InConditionalStatements: false
|
||||||
|
InEmptyParentheses: false
|
||||||
|
Other: false
|
||||||
|
SpacesInSquareBrackets: false
|
||||||
|
Standard: Latest
|
||||||
|
StatementAttributeLikeMacros:
|
||||||
|
- Q_EMIT
|
||||||
|
StatementMacros:
|
||||||
|
- Q_UNUSED
|
||||||
|
- QT_REQUIRE_VERSION
|
||||||
|
TableGenBreakInsideDAGArg: DontBreak
|
||||||
|
TabWidth: 8
|
||||||
|
UseTab: Never
|
||||||
|
VerilogBreakBetweenInstancePorts: true
|
||||||
|
WhitespaceSensitiveMacros:
|
||||||
|
- BOOST_PP_STRINGIZE
|
||||||
|
- CF_SWIFT_NAME
|
||||||
|
- NS_SWIFT_NAME
|
||||||
|
- PP_STRINGIZE
|
||||||
|
- STRINGIZE
|
||||||
|
WrapNamespaceBodyWithEmptyLines: Leave
|
||||||
|
...
|
||||||
|
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
build/
|
||||||
|
.cache/
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
[submodule "Seele"]
|
||||||
|
path = Seele
|
||||||
|
url = https://git.hoegler.org/Dynamitos/Seele
|
||||||
Vendored
+16
@@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch",
|
||||||
|
"type": "lldb",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceRoot}/build/FluidSimulation",
|
||||||
|
"args": [],
|
||||||
|
"cwd": "${workspaceRoot}/build"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
cmake_minimum_required(VERSION 3.24)
|
||||||
|
|
||||||
|
set(CMAKE_CXX_STANDARD 23)
|
||||||
|
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
if(APPLE)
|
||||||
|
set(CMAKE_OSX_DEPLOYMENT_TARGET 26.0)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(CMAKE_TOOLCHAIN_FILE
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/Seele/external/vcpkg/scripts/buildsystems/vcpkg.cmake)
|
||||||
|
|
||||||
|
project(FluidSimulation)
|
||||||
|
|
||||||
|
set(CMAKE_DEBUG_POSTFIX "")
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
add_subdirectory(Seele/)
|
||||||
|
|
||||||
|
add_executable(FluidSimulation "")
|
||||||
|
target_link_libraries(FluidSimulation PRIVATE Engine)
|
||||||
|
target_include_directories(FluidSimulation PRIVATE src/)
|
||||||
|
add_subdirectory(src/)
|
||||||
|
|
||||||
|
add_custom_target(FluidSimulationAll ALL
|
||||||
|
COMMAND ${CMAKE_COMMAND} -E copy_directory
|
||||||
|
${CMAKE_SOURCE_DIR}/res $<TARGET_FILE_DIR:FluidSimulation>
|
||||||
|
COMMAND
|
||||||
|
DEPENDS FluidSimulation)
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"cmakeMinimumRequired": {
|
||||||
|
"major": 3,
|
||||||
|
"minor": 19,
|
||||||
|
"patch": 0
|
||||||
|
},
|
||||||
|
"configurePresets": [
|
||||||
|
{
|
||||||
|
"name": "release",
|
||||||
|
"displayName": "Release (no ASan)",
|
||||||
|
"description": "Release build without sanitizers",
|
||||||
|
"binaryDir": "${sourceDir}/build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||||
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "release-asan",
|
||||||
|
"displayName": "Release (ASan)",
|
||||||
|
"description": "Release build with Address Sanitizer",
|
||||||
|
"binaryDir": "${sourceDir}/build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "RelWithDebInfo",
|
||||||
|
"CMAKE_CXX_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
|
"CMAKE_C_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
|
"CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address",
|
||||||
|
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address",
|
||||||
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"displayName": "Debug (no ASan)",
|
||||||
|
"description": "Debug build without sanitizers",
|
||||||
|
"binaryDir": "${sourceDir}/build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug-mac",
|
||||||
|
"displayName": "Debug Mac (no ASan)",
|
||||||
|
"description": "Debug Mac build without sanitizers",
|
||||||
|
"binaryDir": "${sourceDir}/build",
|
||||||
|
"generator": "Xcode",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug-mac-asan",
|
||||||
|
"displayName": "Debug Mac (ASan)",
|
||||||
|
"description": "Debug Mac build with Address Sanitizer",
|
||||||
|
"binaryDir": "${sourceDir}/build",
|
||||||
|
"generator": "Xcode",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_CXX_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
|
"CMAKE_C_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
|
"CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address",
|
||||||
|
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address",
|
||||||
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug-asan",
|
||||||
|
"displayName": "Debug (ASan)",
|
||||||
|
"description": "Debug build with Address Sanitizer",
|
||||||
|
"binaryDir": "${sourceDir}/build",
|
||||||
|
"cacheVariables": {
|
||||||
|
"CMAKE_BUILD_TYPE": "Debug",
|
||||||
|
"CMAKE_CXX_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
|
"CMAKE_C_FLAGS": "-fsanitize=address -fno-omit-frame-pointer",
|
||||||
|
"CMAKE_EXE_LINKER_FLAGS": "-fsanitize=address",
|
||||||
|
"CMAKE_SHARED_LINKER_FLAGS": "-fsanitize=address",
|
||||||
|
"CMAKE_INSTALL_PREFIX": "C:/Program Files/Seele"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"buildPresets": [
|
||||||
|
{
|
||||||
|
"name": "release",
|
||||||
|
"displayName": "Release (no ASan)",
|
||||||
|
"configurePreset": "release",
|
||||||
|
"jobs": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "release-asan",
|
||||||
|
"displayName": "Release (ASan)",
|
||||||
|
"configurePreset": "release-asan",
|
||||||
|
"jobs": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug",
|
||||||
|
"displayName": "Debug (no ASan)",
|
||||||
|
"configurePreset": "debug",
|
||||||
|
"jobs": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug-mac",
|
||||||
|
"displayName": "Debug Mac (no ASan)",
|
||||||
|
"configurePreset": "debug-mac",
|
||||||
|
"jobs": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug-mac-asan",
|
||||||
|
"displayName": "Debug Mac (ASan)",
|
||||||
|
"configurePreset": "debug-mac-asan",
|
||||||
|
"jobs": 0
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "debug-asan",
|
||||||
|
"displayName": "Debug (ASan)",
|
||||||
|
"configurePreset": "debug-asan",
|
||||||
|
"jobs": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Submodule
+1
Submodule Seele added at 7271fe8a0b
@@ -0,0 +1,55 @@
|
|||||||
|
import FluidGridData;
|
||||||
|
|
||||||
|
struct Params
|
||||||
|
{
|
||||||
|
// read-write
|
||||||
|
FluidGridData<float> density;
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> density0;
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> velocityX;
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> velocityY;
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> velocityZ;
|
||||||
|
float dt;
|
||||||
|
};
|
||||||
|
ParameterBlock<Params> params;
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
[numthreads(32, 8, 1)]
|
||||||
|
void advect(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
FluidGridData<float> density = params.density;
|
||||||
|
FluidGridData<float> density0 = params.density0;
|
||||||
|
FluidGridData<float> velocityX = params.velocityX;
|
||||||
|
FluidGridData<float> velocityY = params.velocityY;
|
||||||
|
FluidGridData<float> velocityZ = params.velocityZ;
|
||||||
|
float dt = params.dt;
|
||||||
|
|
||||||
|
int x = dispatchThreadID.x + 1;
|
||||||
|
int y = dispatchThreadID.y + 1;
|
||||||
|
int z = dispatchThreadID.z + 1;
|
||||||
|
if(x >= gridSize.x - 1 || y >= gridSize.y - 1 || z >= gridSize.z - 1) return;
|
||||||
|
|
||||||
|
float dt0x = dt * (gridSize.x - 2);
|
||||||
|
float dt0y = dt * (gridSize.y - 2);
|
||||||
|
float dt0z = dt * (gridSize.z - 2);
|
||||||
|
|
||||||
|
float3 pos = float3(x - dt0x * velocityX[x, y, z], y - dt0y * velocityY[x, y, z], z - dt0z * velocityZ[x, y, z]);
|
||||||
|
pos.x = clamp(pos.x, 0.5f, gridSize.x - 1.5f);
|
||||||
|
pos.y = clamp(pos.y, 0.5f, gridSize.y - 1.5f);
|
||||||
|
pos.z = clamp(pos.z, 0.5f, gridSize.z - 1.5f);
|
||||||
|
|
||||||
|
int3 i0 = int3(pos);
|
||||||
|
int3 i1 = i0 + int3(1, 1, 1);
|
||||||
|
|
||||||
|
float3 s1 = pos - i0;
|
||||||
|
float3 s0 = 1 - s1;
|
||||||
|
|
||||||
|
density[x, y, z] =
|
||||||
|
s0.x * (s0.y * (s0.z * density0[i0.x, i0.y, i0.z] + s1.z * density0[i0.x, i0.y, i1.z]) +
|
||||||
|
s1.y * (s0.z * density0[i0.x, i1.y, i0.z] + s1.z * density0[i0.x, i1.y, i1.z])) +
|
||||||
|
s1.x * (s0.y * (s0.z * density0[i1.x, i0.y, i0.z] + s1.z * density0[i1.x, i0.y, i1.z]) +
|
||||||
|
s1.y * (s0.z * density0[i1.x, i1.y, i0.z] + s1.z * density0[i1.x, i1.y, i1.z]));
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import FluidGridData;
|
||||||
|
|
||||||
|
struct Params
|
||||||
|
{
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> velocityX;
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> velocityY;
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> velocityZ;
|
||||||
|
// read-write
|
||||||
|
FluidGridData<float> divergence;
|
||||||
|
// read-write
|
||||||
|
FluidGridData<float> pressure;
|
||||||
|
};
|
||||||
|
ParameterBlock<Params> params;
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
[numthreads(32, 8, 1)]
|
||||||
|
void computeDivergence(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
FluidGridData<float> velocityX = params.velocityX;
|
||||||
|
FluidGridData<float> velocityY = params.velocityY;
|
||||||
|
FluidGridData<float> velocityZ = params.velocityZ;
|
||||||
|
FluidGridData<float> divergence = params.divergence;
|
||||||
|
FluidGridData<float> pressure = params.pressure;
|
||||||
|
|
||||||
|
int x = dispatchThreadID.x + 1;
|
||||||
|
int y = dispatchThreadID.y + 1;
|
||||||
|
int z = dispatchThreadID.z + 1;
|
||||||
|
if(x >= gridSize.x - 1 || y >= gridSize.y - 1 || z >= gridSize.z - 1) return;
|
||||||
|
|
||||||
|
divergence[x, y, z] = -0.5f * (velocityX[x + 1, y, z] - velocityX[x - 1, y, z] + velocityY[x, y + 1, z] - velocityY[x, y - 1, z] + velocityZ[x, y, z + 1] - velocityZ[x, y, z - 1]) / gridSize.x;
|
||||||
|
pressure[x, y, z] = 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
static const uint3 gridSize = uint3(128, 128, 128);
|
||||||
|
struct FluidGridData<T>
|
||||||
|
{
|
||||||
|
RWStructuredBuffer<T> dataGrid;
|
||||||
|
__subscript(uint3 index) -> T
|
||||||
|
{
|
||||||
|
get { return dataGrid[index.x + index.y * gridSize.x + index.z * gridSize.x * gridSize.y]; }
|
||||||
|
set { dataGrid[index.x + index.y * gridSize.x + index.z * gridSize.x * gridSize.y] = newValue; }
|
||||||
|
}
|
||||||
|
__subscript(uint x, uint y, uint z) -> T
|
||||||
|
{
|
||||||
|
get { return dataGrid[x + y * gridSize.x + z * gridSize.x * gridSize.y]; }
|
||||||
|
set { dataGrid[x + y * gridSize.x + z * gridSize.x * gridSize.y] = newValue; }
|
||||||
|
}
|
||||||
|
};
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import FluidGridData;
|
||||||
|
|
||||||
|
struct Params
|
||||||
|
{
|
||||||
|
// read-write
|
||||||
|
FluidGridData<float> next;
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> current;
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> grid0;
|
||||||
|
float a;
|
||||||
|
float c;
|
||||||
|
};
|
||||||
|
ParameterBlock<Params> params;
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
[numthreads(32, 8, 1)]
|
||||||
|
void linearSolve(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
FluidGridData<float> next = params.next;
|
||||||
|
FluidGridData<float> current = params.current;
|
||||||
|
FluidGridData<float> grid0 = params.grid0;
|
||||||
|
float a = params.a;
|
||||||
|
float cRecip = 1.0f / params.c;
|
||||||
|
|
||||||
|
int x = dispatchThreadID.x + 1;
|
||||||
|
int y = dispatchThreadID.y + 1;
|
||||||
|
int z = dispatchThreadID.z + 1;
|
||||||
|
if(x >= gridSize.x - 1 || y >= gridSize.y - 1 || z >= gridSize.z - 1) return;
|
||||||
|
|
||||||
|
next[x, y, z] = (grid0[x, y, z] + a * (current[x + 1, y, z] + current[x - 1, y, z] + current[x, y + 1, z] + current[x, y - 1, z] + current[x, y, z + 1] + current[x, y, z - 1])) * cRecip;
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import FluidGridData;
|
||||||
|
|
||||||
|
struct Params
|
||||||
|
{
|
||||||
|
// read-write
|
||||||
|
FluidGridData<float> velocityX;
|
||||||
|
// read-write
|
||||||
|
FluidGridData<float> velocityY;
|
||||||
|
// read-write
|
||||||
|
FluidGridData<float> velocityZ;
|
||||||
|
// read-only
|
||||||
|
FluidGridData<float> pressure;
|
||||||
|
};
|
||||||
|
ParameterBlock<Params> params;
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
[numthreads(32, 8, 1)]
|
||||||
|
void project(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
FluidGridData<float> velocityX = params.velocityX;
|
||||||
|
FluidGridData<float> velocityY = params.velocityY;
|
||||||
|
FluidGridData<float> velocityZ = params.velocityZ;
|
||||||
|
FluidGridData<float> pressure = params.pressure;
|
||||||
|
|
||||||
|
int x = dispatchThreadID.x + 1;
|
||||||
|
int y = dispatchThreadID.y + 1;
|
||||||
|
int z = dispatchThreadID.z + 1;
|
||||||
|
if(x >= gridSize.x - 1 || y >= gridSize.y - 1 || z >= gridSize.z - 1) return;
|
||||||
|
|
||||||
|
velocityX[x, y, z] -= 0.5f * (pressure[x + 1, y, z] - pressure[x - 1, y, z]) * gridSize.x;
|
||||||
|
velocityY[x, y, z] -= 0.5f * (pressure[x, y + 1, z] - pressure[x, y - 1, z]) * gridSize.y;
|
||||||
|
velocityZ[x, y, z] -= 0.5f * (pressure[x, y, z + 1] - pressure[x, y, z - 1]) * gridSize.z;
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
import FluidGridData;
|
||||||
|
|
||||||
|
struct Params
|
||||||
|
{
|
||||||
|
FluidGridData<float> density;
|
||||||
|
};
|
||||||
|
ParameterBlock<Params> params;
|
||||||
|
|
||||||
|
struct VertexOut
|
||||||
|
{
|
||||||
|
float4 position : SV_Position;
|
||||||
|
float2 uv : UV;
|
||||||
|
};
|
||||||
|
|
||||||
|
[shader("vertex")]
|
||||||
|
VertexOut vertexMain(uint vertexId : SV_VertexID)
|
||||||
|
{
|
||||||
|
VertexOut output;
|
||||||
|
output.uv = float2((vertexId << 1) & 2, vertexId & 2);
|
||||||
|
output.position = float4(output.uv * 2.0f - 1.0f, 0, 1);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("pixel")]
|
||||||
|
float4 fragmentMain(VertexOut input) : SV_Target
|
||||||
|
{
|
||||||
|
FluidGridData<float> density = params.density;
|
||||||
|
int x = int(input.uv.x * (gridSize.x - 2) + 1);
|
||||||
|
int y = int(input.uv.y * (gridSize.y - 2) + 1);
|
||||||
|
float d = density[x, y, 0];
|
||||||
|
return float4(d, d, d, 1);
|
||||||
|
}
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import FluidGridData;
|
||||||
|
|
||||||
|
struct Params
|
||||||
|
{
|
||||||
|
int b;
|
||||||
|
// read-write
|
||||||
|
FluidGridData<float> grid;
|
||||||
|
};
|
||||||
|
ParameterBlock<Params> params;
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
[numthreads(32, 8, 1)]
|
||||||
|
void setBound(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
int b = params.b;
|
||||||
|
FluidGridData<float> grid = params.grid;
|
||||||
|
int x = dispatchThreadID.x + 1;
|
||||||
|
int y = dispatchThreadID.y + 1;
|
||||||
|
if(x >= gridSize.x - 1 || y >= gridSize.y - 1) return;
|
||||||
|
|
||||||
|
grid[0, x, y] = b == 1 ? grid[1, x, y] : -grid[1, x, y];
|
||||||
|
grid[gridSize.x - 1, x, y] = b == 1 ? grid[gridSize.x - 2, x, y] : -grid[gridSize.x - 2, x, y];
|
||||||
|
|
||||||
|
grid[x, 0, y] = b == 2 ? grid[x, 1, y] : -grid[x, 1, y];
|
||||||
|
grid[x, gridSize.y - 1, y] = b == 2 ? grid[x, gridSize.y - 2, y] : -grid[x, gridSize.y - 2, y];
|
||||||
|
|
||||||
|
grid[x, y, 0] = b == 3 ? grid[x, y, 1] : -grid[x, y, 1];
|
||||||
|
grid[x, y, gridSize.z - 1] = b == 3 ? grid[x, y, gridSize.z - 2] : -grid[x, y, gridSize.z - 2];
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
[numthreads(128, 1, 1)]
|
||||||
|
void setBoundEdges(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
FluidGridData<float> grid = params.grid;
|
||||||
|
int x = dispatchThreadID.x + 1;
|
||||||
|
if(x >= gridSize.x - 1) return;
|
||||||
|
|
||||||
|
grid[x, 0, 0] = 0.5f * (grid[x, 1, 0] + grid[x, 0, 1]);
|
||||||
|
grid[x, gridSize.y - 1, 0] = 0.5f * (grid[x, gridSize.y - 2, 0] + grid[x, gridSize.y - 1, 1]);
|
||||||
|
grid[x, 0, gridSize.z - 1] = 0.5f * (grid[x, 1, gridSize.z - 1] + grid[x, 0, gridSize.z - 2]);
|
||||||
|
grid[x, gridSize.y - 1, gridSize.z - 1] = 0.5f * (grid[x, gridSize.y - 2, gridSize.z - 1] + grid[x, gridSize.y - 1, gridSize.z - 2]);
|
||||||
|
|
||||||
|
grid[0, x, 0] = 0.5f * (grid[1, x, 0] + grid[0, x, 1]);
|
||||||
|
grid[0, x, gridSize.z - 1] = 0.5f * (grid[1, x, gridSize.z - 1] + grid[0, x, gridSize.z - 2]);
|
||||||
|
grid[gridSize.x - 1, x, 0] = 0.5f * (grid[gridSize.x - 2, x, 0] + grid[gridSize.x - 1, x, 1]);
|
||||||
|
grid[gridSize.x - 1, x, gridSize.z - 1] = 0.5f * (grid[gridSize.x - 2, x, gridSize.z - 1] + grid[gridSize.x - 1, x, gridSize.z - 2]);
|
||||||
|
|
||||||
|
grid[0, 0, x] = 0.5f * (grid[1, 0, x] + grid[0, 1, x]);
|
||||||
|
grid[0, gridSize.y - 1, x] = 0.5f * (grid[1, gridSize.y - 1, x] + grid[0, gridSize.y - 2, x]);
|
||||||
|
grid[gridSize.x - 1, 0, x] = 0.5f * (grid[gridSize.x - 2, 0, x] + grid[gridSize.x - 1, 1, x]);
|
||||||
|
grid[gridSize.x - 1, gridSize.y - 1, x] = 0.5f * (grid[gridSize.x - 2, gridSize.y - 1, x] + grid[gridSize.x - 1, gridSize.y - 2, x]);
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
[numthreads(8, 1, 1)]
|
||||||
|
void setBoundCorners(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
FluidGridData<float> grid = params.grid;
|
||||||
|
uint threadIdx = dispatchThreadID.x;
|
||||||
|
|
||||||
|
uint x = ((threadIdx & 1) == 0) ? 0 : (gridSize.x - 1);
|
||||||
|
uint y = ((threadIdx & 2) == 0) ? 0 : (gridSize.y - 1);
|
||||||
|
uint z = ((threadIdx & 4) == 0) ? 0 : (gridSize.z - 1);
|
||||||
|
|
||||||
|
uint nx = (x == 0) ? 1 : (gridSize.x - 2);
|
||||||
|
uint ny = (y == 0) ? 1 : (gridSize.y - 2);
|
||||||
|
uint nz = (z == 0) ? 1 : (gridSize.z - 2);
|
||||||
|
|
||||||
|
grid[x, y, z] = 0.33f * (grid[nx, y, z] + grid[x, ny, z] + grid[x, y, nz]);
|
||||||
|
}
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
import FluidGridData;
|
||||||
|
|
||||||
|
void linearSolve(int b, FluidGridData<float> grid, const FluidGridData<float> grid0, float a, float c, int iterations)
|
||||||
|
{
|
||||||
|
float cRecip = 1.0f / c;
|
||||||
|
for(int k = 0; k < iterations; k++)
|
||||||
|
{
|
||||||
|
for(int z = 1; z < gridSize.z - 1; z++)
|
||||||
|
{
|
||||||
|
for(int y = 1; y < gridSize.y - 1; y++)
|
||||||
|
{
|
||||||
|
for(int x = 1; x < gridSize.x - 1; x++)
|
||||||
|
{
|
||||||
|
grid[x, y, z] = (grid0[x, y, z] + a * (grid[x + 1, y, z] + grid[x - 1, y, z] + grid[x, y + 1, z] + grid[x, y - 1, z] + grid[x, y, z + 1] + grid[x, y, z - 1])) * cRecip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setBound(b, grid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void diffuse(int b, FluidGridData<float> grid, const FluidGridData<float> grid0, float diff, float dt, int iterations)
|
||||||
|
{
|
||||||
|
float a = dt * diff * (gridSize.x - 2) * (gridSize.y - 2) * (gridSize.z - 2);
|
||||||
|
linearSolve(b, grid, grid0, a, 1 + 6 * a, iterations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void advect(int b, FluidGridData<float> density, FluidGridData<float> density0, FluidGridData<float> velocityX, FluidGridData<float> velocityY, FluidGridData<float> velocityZ, float dt)
|
||||||
|
{
|
||||||
|
float dt0x = dt * (gridSize.x - 2);
|
||||||
|
float dt0y = dt * (gridSize.y - 2);
|
||||||
|
float dt0z = dt * (gridSize.z - 2);
|
||||||
|
|
||||||
|
for(int z = 1; z < gridSize.z - 1; z++)
|
||||||
|
{
|
||||||
|
for(int y = 1; y < gridSize.y - 1; y++)
|
||||||
|
{
|
||||||
|
for(int x = 1; x < gridSize.x - 1; x++)
|
||||||
|
{
|
||||||
|
float3 pos = float3(x - dt0x * velocityX[x, y, z], y - dt0y * velocityY[x, y, z], z - dt0z * velocityZ[x, y, z]);
|
||||||
|
pos.x = clamp(pos.x, 0.5f, gridSize.x - 1.5f);
|
||||||
|
pos.y = clamp(pos.y, 0.5f, gridSize.y - 1.5f);
|
||||||
|
pos.z = clamp(pos.z, 0.5f, gridSize.z - 1.5f);
|
||||||
|
|
||||||
|
int3 i0 = int3(pos);
|
||||||
|
int3 i1 = i0 + int3(1, 1, 1);
|
||||||
|
|
||||||
|
float3 s1 = pos - i0;
|
||||||
|
float3 s0 = 1 - s1;
|
||||||
|
|
||||||
|
density[x, y, z] =
|
||||||
|
s0.x * (s0.y * (s0.z * density0[i0.x, i0.y, i0.z] + s1.z * density0[i0.x, i0.y, i1.z]) +
|
||||||
|
s1.y * (s0.z * density0[i0.x, i1.y, i0.z] + s1.z * density0[i0.x, i1.y, i1.z])) +
|
||||||
|
s1.x * (s0.y * (s0.z * density0[i1.x, i0.y, i0.z] + s1.z * density0[i1.x, i0.y, i1.z]) +
|
||||||
|
s1.y * (s0.z * density0[i1.x, i1.y, i0.z] + s1.z * density0[i1.x, i1.y, i1.z]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setBound(b, density);
|
||||||
|
}
|
||||||
|
|
||||||
|
void project(FluidGridData<float> velocityX, FluidGridData<float> velocityY, FluidGridData<float> velocityZ, FluidGridData<float> pressure, FluidGridData<float> divergence, int iter)
|
||||||
|
{
|
||||||
|
for(int z = 1; z < gridSize.z - 1; z++)
|
||||||
|
{
|
||||||
|
for(int y = 1; y < gridSize.y - 1; y++)
|
||||||
|
{
|
||||||
|
for(int x = 1; x < gridSize.x - 1; x++)
|
||||||
|
{
|
||||||
|
divergence[x, y, z] = -0.5f * (velocityX[x + 1, y, z] - velocityX[x - 1, y, z] + velocityY[x, y + 1, z] - velocityY[x, y - 1, z] + velocityZ[x, y, z + 1] - velocityZ[x, y, z - 1]) / gridSize.x;
|
||||||
|
pressure[x, y, z] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setBound(0, divergence);
|
||||||
|
setBound(0, pressure);
|
||||||
|
linearSolve(0, pressure, divergence, 1, 6, iter);
|
||||||
|
for(int z = 1; z < gridSize.z - 1; z++)
|
||||||
|
{
|
||||||
|
for(int y = 1; y < gridSize.y - 1; y++)
|
||||||
|
{
|
||||||
|
for(int x = 1; x < gridSize.x - 1; x++)
|
||||||
|
{
|
||||||
|
velocityX[x, y, z] -= 0.5f * (pressure[x + 1, y, z] - pressure[x - 1, y, z]) * gridSize.x;
|
||||||
|
velocityY[x, y, z] -= 0.5f * (pressure[x, y + 1, z] - pressure[x, y - 1, z]) * gridSize.y;
|
||||||
|
velocityZ[x, y, z] -= 0.5f * (pressure[x, y, z + 1] - pressure[x, y, z - 1]) * gridSize.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
setBound(1, velocityX);
|
||||||
|
setBound(2, velocityY);
|
||||||
|
setBound(3, velocityZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
[shader("compute")]
|
||||||
|
void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID)
|
||||||
|
{
|
||||||
|
diffuse(1, pComputeParams.velocityX0, pComputeParams.velocityX, pComputeParams.viscosity, pComputeParams.dt, 20);
|
||||||
|
diffuse(2, pComputeParams.velocityY0, pComputeParams.velocityY, pComputeParams.viscosity, pComputeParams.dt, 20);
|
||||||
|
diffuse(3, pComputeParams.velocityZ0, pComputeParams.velocityZ, pComputeParams.viscosity, pComputeParams.dt, 20);
|
||||||
|
project(pComputeParams.velocityX0, pComputeParams.velocityY0, pComputeParams.velocityZ0, pComputeParams.scratch, pComputeParams.density, 20);
|
||||||
|
advect(1, pComputeParams.velocityX, pComputeParams.velocityX0, pComputeParams.velocityX0, pComputeParams.velocityY0, pComputeParams.velocityZ0, pComputeParams.dt);
|
||||||
|
advect(2, pComputeParams.velocityY, pComputeParams.velocityY0, pComputeParams.velocityX0, pComputeParams.velocityY0, pComputeParams.velocityZ0, pComputeParams.dt);
|
||||||
|
advect(3, pComputeParams.velocityZ, pComputeParams.velocityZ0, pComputeParams.velocityX0, pComputeParams.velocityY0, pComputeParams.velocityZ0, pComputeParams.dt);
|
||||||
|
|
||||||
|
diffuse(0, pComputeParams.scratch, pComputeParams.density, pComputeParams.diffusion, pComputeParams.dt, 20);
|
||||||
|
advect(0, pComputeParams.density, pComputeParams.scratch, pComputeParams.velocityX0, pComputeParams.velocityY0, pComputeParams.velocityZ0, pComputeParams.dt);
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
target_sources(FluidSimulation
|
||||||
|
PRIVATE
|
||||||
|
SimulationComputePass.h
|
||||||
|
SimulationComputePass.cpp
|
||||||
|
FluidRenderPass.h
|
||||||
|
FluidRenderPass.cpp
|
||||||
|
FluidSimulationView.h
|
||||||
|
FluidSimulationView.cpp
|
||||||
|
main.cpp)
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
#include "FluidRenderPass.h"
|
||||||
|
#include "Graphics/Enums.h"
|
||||||
|
#include "Graphics/Graphics.h"
|
||||||
|
#include "Graphics/Initializer.h"
|
||||||
|
#include "Graphics/RenderTarget.h"
|
||||||
|
#include "Graphics/Shader.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
FluidRenderPass::FluidRenderPass(Seele::Gfx::PGraphics graphics) : RenderPass(graphics) {
|
||||||
|
pipelineLayout = graphics->createPipelineLayout("FluidPipelineLayout");
|
||||||
|
descriptorLayout = graphics->createDescriptorLayout("params");
|
||||||
|
descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "density",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
descriptorLayout->create();
|
||||||
|
pipelineLayout->addDescriptorLayout(descriptorLayout);
|
||||||
|
|
||||||
|
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||||
|
.name = "Fluid",
|
||||||
|
.modules = {"Render"},
|
||||||
|
.entryPoints = {{"vertexMain", "Render"}, {"fragmentMain", "Render"}},
|
||||||
|
.rootSignature = pipelineLayout,
|
||||||
|
.dumpIntermediate = true,
|
||||||
|
});
|
||||||
|
pipelineLayout->create();
|
||||||
|
vertexShader = graphics->createVertexShader({0});
|
||||||
|
fragmentShader = graphics->createFragmentShader({1});
|
||||||
|
}
|
||||||
|
|
||||||
|
FluidRenderPass::~FluidRenderPass() {}
|
||||||
|
|
||||||
|
void FluidRenderPass::beginFrame(const Seele::Component::Camera &camera, const Seele::Component::Transform &transform) {
|
||||||
|
updateViewParameters(camera, transform);
|
||||||
|
descriptorSet = descriptorLayout->allocateDescriptorSet();
|
||||||
|
descriptorSet->updateBuffer("density", 0, densityBuffer);
|
||||||
|
descriptorSet->writeChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidRenderPass::render() {
|
||||||
|
graphics->beginRenderPass(renderPass);
|
||||||
|
graphics->endRenderPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidRenderPass::endFrame() {}
|
||||||
|
|
||||||
|
void FluidRenderPass::publishOutputs() {
|
||||||
|
depthTexture = graphics->createTexture2D(TextureCreateInfo{
|
||||||
|
.format = Gfx::SE_FORMAT_D32_SFLOAT,
|
||||||
|
.width = viewport->getWidth(),
|
||||||
|
.height = viewport->getHeight(),
|
||||||
|
.name = "FluidDepth",
|
||||||
|
.usage = Gfx::SE_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void FluidRenderPass::createRenderPass() {
|
||||||
|
densityBuffer = resources->requestBuffer("DENSITY");
|
||||||
|
colorAttachment = Gfx::RenderTargetAttachment(viewport->getOwner()->getBackBuffer()->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
Gfx::SE_IMAGE_LAYOUT_PRESENT_SRC_KHR, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
|
Gfx::SE_ATTACHMENT_STORE_OP_STORE);
|
||||||
|
depthAttachment = Gfx::RenderTargetAttachment(depthTexture->getDefaultView(), Gfx::SE_IMAGE_LAYOUT_UNDEFINED,
|
||||||
|
Gfx::SE_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, Gfx::SE_ATTACHMENT_LOAD_OP_CLEAR,
|
||||||
|
Gfx::SE_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||||
|
depthAttachment.clear.depthStencil.depth = 0.0f;
|
||||||
|
Gfx::RenderTargetLayout layout = Gfx::RenderTargetLayout{
|
||||||
|
.colorAttachments = {colorAttachment},
|
||||||
|
.depthAttachment = depthAttachment,
|
||||||
|
};
|
||||||
|
Array<Gfx::SubPassDependency> dependency = {
|
||||||
|
{
|
||||||
|
.srcSubpass = ~0U,
|
||||||
|
.dstSubpass = 0,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.srcSubpass = 0,
|
||||||
|
.dstSubpass = ~0U,
|
||||||
|
.srcStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.dstStage = Gfx::SE_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT | Gfx::SE_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT |
|
||||||
|
Gfx::SE_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
|
||||||
|
.srcAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
.dstAccess = Gfx::SE_ACCESS_COLOR_ATTACHMENT_WRITE_BIT | Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT |
|
||||||
|
Gfx::SE_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
renderPass = graphics->createRenderPass(layout, dependency, viewport->getRenderArea(), "FluidRenderPass");
|
||||||
|
pipeline = graphics->createGraphicsPipeline(Gfx::LegacyPipelineCreateInfo{
|
||||||
|
.vertexShader = vertexShader,
|
||||||
|
.fragmentShader = fragmentShader,
|
||||||
|
.renderPass = renderPass,
|
||||||
|
.pipelineLayout = pipelineLayout,
|
||||||
|
.multisampleState =
|
||||||
|
{
|
||||||
|
.samples = Gfx::SE_SAMPLE_COUNT_1_BIT,
|
||||||
|
},
|
||||||
|
.rasterizationState =
|
||||||
|
{
|
||||||
|
.cullMode = Gfx::SE_CULL_MODE_BACK_BIT,
|
||||||
|
},
|
||||||
|
.colorBlend =
|
||||||
|
{
|
||||||
|
.attachmentCount = 1,
|
||||||
|
.blendAttachments =
|
||||||
|
{
|
||||||
|
Gfx::ColorBlendState::BlendAttachment{
|
||||||
|
.blendEnable = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Component/Transform.h"
|
||||||
|
#include "Graphics/Descriptor.h"
|
||||||
|
#include "Graphics/Initializer.h"
|
||||||
|
#include "Graphics/RenderPass/RenderPass.h"
|
||||||
|
#include "MinimalEngine.h"
|
||||||
|
|
||||||
|
class FluidRenderPass : public Seele::RenderPass {
|
||||||
|
public:
|
||||||
|
FluidRenderPass(Seele::Gfx::PGraphics graphics);
|
||||||
|
virtual ~FluidRenderPass() override;
|
||||||
|
|
||||||
|
virtual void beginFrame(const Seele::Component::Camera &camera, const Seele::Component::Transform &transform) override;
|
||||||
|
virtual void render() override;
|
||||||
|
virtual void endFrame() override;
|
||||||
|
|
||||||
|
virtual void publishOutputs() override;
|
||||||
|
virtual void createRenderPass() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Seele::Gfx::RenderTargetAttachment colorAttachment;
|
||||||
|
Seele::Gfx::RenderTargetAttachment depthAttachment;
|
||||||
|
Seele::Gfx::OTexture2D depthTexture;
|
||||||
|
|
||||||
|
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||||
|
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||||
|
Seele::Gfx::ODescriptorSet descriptorSet;
|
||||||
|
Seele::Gfx::OVertexShader vertexShader;
|
||||||
|
Seele::Gfx::OFragmentShader fragmentShader;
|
||||||
|
Seele::Gfx::PGraphicsPipeline pipeline;
|
||||||
|
|
||||||
|
Seele::Gfx::PShaderBuffer densityBuffer;
|
||||||
|
};
|
||||||
|
DEFINE_REF(FluidRenderPass)
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include "FluidSimulationView.h"
|
||||||
|
#include "FluidRenderPass.h"
|
||||||
|
#include "SimulationComputePass.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
FluidSimulationView::FluidSimulationView(Gfx::PGraphics graphics, Seele::PWindow window, const Seele::ViewportCreateInfo &createInfo)
|
||||||
|
: View(graphics, window, createInfo, "Fluid Simulation View") {
|
||||||
|
camera = Component::Camera{};
|
||||||
|
transform = Component::Transform{
|
||||||
|
.transform = Math::Transform({0.0f, 0.0f, -5.0f}),
|
||||||
|
};
|
||||||
|
renderGraph.addPass(new SimulationComputePass(graphics));
|
||||||
|
renderGraph.addPass(new FluidRenderPass(graphics));
|
||||||
|
renderGraph.setViewport(viewport);
|
||||||
|
renderGraph.createRenderPass();
|
||||||
|
}
|
||||||
|
|
||||||
|
FluidSimulationView::~FluidSimulationView() {}
|
||||||
|
|
||||||
|
void FluidSimulationView::beginUpdate() {}
|
||||||
|
|
||||||
|
void FluidSimulationView::update() {}
|
||||||
|
|
||||||
|
void FluidSimulationView::commitUpdate() {}
|
||||||
|
|
||||||
|
void FluidSimulationView::prepareRender() {}
|
||||||
|
|
||||||
|
void FluidSimulationView::render() { renderGraph.render(camera, transform); }
|
||||||
|
|
||||||
|
void FluidSimulationView::applyArea(Seele::URect area) {}
|
||||||
|
void FluidSimulationView::keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) {}
|
||||||
|
void FluidSimulationView::mouseMoveCallback(double xPos, double yPos) {}
|
||||||
|
void FluidSimulationView::mouseButtonCallback(Seele::MouseButton button, Seele::InputAction action, Seele::KeyModifier modifier) {}
|
||||||
|
void FluidSimulationView::scrollCallback(double xOffset, double yOffset) {}
|
||||||
|
void FluidSimulationView::fileCallback(int count, const char **paths) {}
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Graphics/Enums.h"
|
||||||
|
#include "Graphics/Initializer.h"
|
||||||
|
#include "Graphics/RenderPass/RenderGraph.h"
|
||||||
|
#include "Window/View.h"
|
||||||
|
|
||||||
|
class FluidSimulationView : public Seele::View {
|
||||||
|
public:
|
||||||
|
FluidSimulationView(Seele::Gfx::PGraphics graphics, Seele::PWindow window, const Seele::ViewportCreateInfo &createInfo);
|
||||||
|
~FluidSimulationView() override;
|
||||||
|
|
||||||
|
virtual void beginUpdate() override;
|
||||||
|
virtual void update() override;
|
||||||
|
virtual void commitUpdate() override;
|
||||||
|
|
||||||
|
virtual void prepareRender() override;
|
||||||
|
virtual void render() override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void applyArea(Seele::URect area) override;
|
||||||
|
virtual void keyCallback(Seele::KeyCode code, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
||||||
|
virtual void mouseMoveCallback(double xPos, double yPos) override;
|
||||||
|
virtual void mouseButtonCallback(Seele::MouseButton button, Seele::InputAction action, Seele::KeyModifier modifier) override;
|
||||||
|
virtual void scrollCallback(double xOffset, double yOffset) override;
|
||||||
|
virtual void fileCallback(int count, const char **paths) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Seele::Component::Camera camera;
|
||||||
|
Seele::Component::Transform transform;
|
||||||
|
Seele::RenderGraph renderGraph;
|
||||||
|
};
|
||||||
@@ -0,0 +1,487 @@
|
|||||||
|
#include "SimulationComputePass.h"
|
||||||
|
#include "Graphics/Command.h"
|
||||||
|
#include "Graphics/Descriptor.h"
|
||||||
|
#include "Graphics/Enums.h"
|
||||||
|
#include "Graphics/Graphics.h"
|
||||||
|
#include "Graphics/Initializer.h"
|
||||||
|
#include "Graphics/Shader.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
#define SWAP(a, b) \
|
||||||
|
{ \
|
||||||
|
auto temp = std::move(a); \
|
||||||
|
a = std::move(b); \
|
||||||
|
b = std::move(temp); \
|
||||||
|
}
|
||||||
|
|
||||||
|
SimulationComputePass::SimulationComputePass(Seele::Gfx::PGraphics graphics) : RenderPass(graphics) {
|
||||||
|
{
|
||||||
|
setBounds.pipelineLayout = graphics->createPipelineLayout("SetBoundsPipelineLayout");
|
||||||
|
setBounds.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||||
|
setBounds.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "b",
|
||||||
|
.uniformLength = sizeof(int),
|
||||||
|
});
|
||||||
|
setBounds.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "grid",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
setBounds.descriptorLayout->create();
|
||||||
|
setBounds.pipelineLayout->addDescriptorLayout(setBounds.descriptorLayout);
|
||||||
|
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||||
|
.name = "SetBound",
|
||||||
|
.modules = {"SetBound"},
|
||||||
|
.entryPoints = {{"setBound", "SetBound"}, {"setBoundEdges", "SetBound"}, {"setBoundCorners", "SetBound"}},
|
||||||
|
.rootSignature = setBounds.pipelineLayout,
|
||||||
|
});
|
||||||
|
setBounds.pipelineLayout->create();
|
||||||
|
setBounds.shader = graphics->createComputeShader({0});
|
||||||
|
setBounds.shaderEdges = graphics->createComputeShader({1});
|
||||||
|
setBounds.shaderCorners = graphics->createComputeShader({2});
|
||||||
|
setBounds.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||||
|
.computeShader = setBounds.shader,
|
||||||
|
.pipelineLayout = setBounds.pipelineLayout,
|
||||||
|
});
|
||||||
|
setBounds.pipelineEdges = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||||
|
.computeShader = setBounds.shaderEdges,
|
||||||
|
.pipelineLayout = setBounds.pipelineLayout,
|
||||||
|
});
|
||||||
|
setBounds.pipelineCorners = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||||
|
.computeShader = setBounds.shaderCorners,
|
||||||
|
.pipelineLayout = setBounds.pipelineLayout,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{
|
||||||
|
linearSolve.pipelineLayout = graphics->createPipelineLayout("LinearSolvePipelineLayout");
|
||||||
|
linearSolve.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||||
|
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "a",
|
||||||
|
.uniformLength = sizeof(float),
|
||||||
|
});
|
||||||
|
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "c",
|
||||||
|
.uniformLength = sizeof(float),
|
||||||
|
});
|
||||||
|
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "next",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "current",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
linearSolve.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "grid0",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
linearSolve.descriptorLayout->create();
|
||||||
|
linearSolve.pipelineLayout->addDescriptorLayout(linearSolve.descriptorLayout);
|
||||||
|
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||||
|
.name = "LinearSolve",
|
||||||
|
.modules = {"LinearSolve"},
|
||||||
|
.entryPoints = {{"linearSolve", "LinearSolve"}},
|
||||||
|
.rootSignature = linearSolve.pipelineLayout,
|
||||||
|
});
|
||||||
|
linearSolve.pipelineLayout->create();
|
||||||
|
linearSolve.shader = graphics->createComputeShader({0});
|
||||||
|
linearSolve.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||||
|
.computeShader = linearSolve.shader,
|
||||||
|
.pipelineLayout = linearSolve.pipelineLayout,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{
|
||||||
|
computeDivergence.pipelineLayout = graphics->createPipelineLayout("ComputeDivergencePipelineLayout");
|
||||||
|
computeDivergence.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||||
|
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "velocityX",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "velocityY",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "velocityZ",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "divergence",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
computeDivergence.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "pressure",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
computeDivergence.descriptorLayout->create();
|
||||||
|
computeDivergence.pipelineLayout->addDescriptorLayout(computeDivergence.descriptorLayout);
|
||||||
|
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||||
|
.name = "Divergence",
|
||||||
|
.modules = {"Divergence"},
|
||||||
|
.entryPoints = {{"computeDivergence", "Divergence"}},
|
||||||
|
.rootSignature = computeDivergence.pipelineLayout,
|
||||||
|
});
|
||||||
|
computeDivergence.pipelineLayout->create();
|
||||||
|
|
||||||
|
computeDivergence.shader = graphics->createComputeShader({0});
|
||||||
|
computeDivergence.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||||
|
.computeShader = computeDivergence.shader,
|
||||||
|
.pipelineLayout = computeDivergence.pipelineLayout,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{
|
||||||
|
project.pipelineLayout = graphics->createPipelineLayout("ProjectPipelineLayout");
|
||||||
|
project.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||||
|
project.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "velocityX",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
project.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "velocityY",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
project.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "velocityZ",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
project.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "pressure",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
project.descriptorLayout->create();
|
||||||
|
project.pipelineLayout->addDescriptorLayout(project.descriptorLayout);
|
||||||
|
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||||
|
.name = "Project",
|
||||||
|
.modules = {"Project"},
|
||||||
|
.entryPoints = {{"project", "Project"}},
|
||||||
|
.rootSignature = project.pipelineLayout,
|
||||||
|
});
|
||||||
|
project.pipelineLayout->create();
|
||||||
|
project.shader = graphics->createComputeShader({0});
|
||||||
|
project.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||||
|
.computeShader = project.shader,
|
||||||
|
.pipelineLayout = project.pipelineLayout,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
{
|
||||||
|
advect.pipelineLayout = graphics->createPipelineLayout("AdvectPipelineLayout");
|
||||||
|
advect.descriptorLayout = graphics->createDescriptorLayout("params");
|
||||||
|
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "density",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "density0",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "velocityX",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "velocityY",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "velocityZ",
|
||||||
|
.descriptorType = Gfx::SE_DESCRIPTOR_TYPE_STORAGE_BUFFER,
|
||||||
|
});
|
||||||
|
advect.descriptorLayout->addDescriptorBinding(Gfx::DescriptorBinding{
|
||||||
|
.name = "dt",
|
||||||
|
.uniformLength = sizeof(float),
|
||||||
|
});
|
||||||
|
advect.descriptorLayout->create();
|
||||||
|
advect.pipelineLayout->addDescriptorLayout(advect.descriptorLayout);
|
||||||
|
graphics->beginShaderCompilation(ShaderCompilationInfo{
|
||||||
|
.name = "Advect",
|
||||||
|
.modules = {"Advect"},
|
||||||
|
.entryPoints = {{"advect", "Advect"}},
|
||||||
|
.rootSignature = advect.pipelineLayout,
|
||||||
|
});
|
||||||
|
advect.pipelineLayout->create();
|
||||||
|
|
||||||
|
advect.shader = graphics->createComputeShader({0});
|
||||||
|
advect.pipeline = graphics->createComputePipeline(Gfx::ComputePipelineCreateInfo{
|
||||||
|
.computeShader = advect.shader,
|
||||||
|
.pipelineLayout = advect.pipelineLayout,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t bufferSize = gridSize * gridSize * gridSize * sizeof(float);
|
||||||
|
densityBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "DensityBuffer",
|
||||||
|
});
|
||||||
|
scratchBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "Density0Buffer",
|
||||||
|
});
|
||||||
|
velocityXNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "VelocityXNextBuffer",
|
||||||
|
});
|
||||||
|
velocityYNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "VelocityYNextBuffer",
|
||||||
|
});
|
||||||
|
velocityZNextBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "VelocityZNextBuffer",
|
||||||
|
});
|
||||||
|
velocityXBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "VelocityXBuffer",
|
||||||
|
});
|
||||||
|
velocityYBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "VelocityYBuffer",
|
||||||
|
});
|
||||||
|
velocityZBuffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "VelocityZBuffer",
|
||||||
|
});
|
||||||
|
velocityX0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "VelocityX0Buffer",
|
||||||
|
});
|
||||||
|
velocityY0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "VelocityY0Buffer",
|
||||||
|
});
|
||||||
|
velocityZ0Buffer = graphics->createShaderBuffer(ShaderBufferCreateInfo{
|
||||||
|
.sourceData =
|
||||||
|
{
|
||||||
|
.size = bufferSize,
|
||||||
|
},
|
||||||
|
.name = "VelocityZ0Buffer",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
SimulationComputePass::~SimulationComputePass() {}
|
||||||
|
|
||||||
|
void SimulationComputePass::beginFrame(const Seele::Component::Camera &camera, const Seele::Component::Transform &transform) {
|
||||||
|
setBounds.descriptorLayout->reset();
|
||||||
|
linearSolve.descriptorLayout->reset();
|
||||||
|
computeDivergence.descriptorLayout->reset();
|
||||||
|
project.descriptorLayout->reset();
|
||||||
|
advect.descriptorLayout->reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationComputePass::render() {
|
||||||
|
for (uint iteration = 0; iteration < 4; ++iteration) {
|
||||||
|
float a = dt * viscosity * (gridSize - 2) * (gridSize - 2) * (gridSize - 2);
|
||||||
|
float c = 1 + 6 * a;
|
||||||
|
linearSolvePass(velocityXNextBuffer, velocityXBuffer, velocityX0Buffer, a, c);
|
||||||
|
linearSolvePass(velocityYNextBuffer, velocityYBuffer, velocityY0Buffer, a, c);
|
||||||
|
linearSolvePass(velocityZNextBuffer, velocityZBuffer, velocityZ0Buffer, a, c);
|
||||||
|
|
||||||
|
setBoundsPass(velocityXNextBuffer, 1);
|
||||||
|
setBoundsPass(velocityYNextBuffer, 2);
|
||||||
|
setBoundsPass(velocityZNextBuffer, 3);
|
||||||
|
|
||||||
|
SWAP(velocityXBuffer, velocityXNextBuffer);
|
||||||
|
SWAP(velocityYBuffer, velocityYNextBuffer);
|
||||||
|
SWAP(velocityZBuffer, velocityZNextBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
SWAP(velocityX0Buffer, velocityXBuffer);
|
||||||
|
SWAP(velocityY0Buffer, velocityYBuffer);
|
||||||
|
SWAP(velocityZ0Buffer, velocityZBuffer);
|
||||||
|
|
||||||
|
Gfx::PShaderBuffer divergence = velocityXBuffer;
|
||||||
|
Gfx::PShaderBuffer pressureCurrent = velocityYBuffer;
|
||||||
|
Gfx::PShaderBuffer pressureNext = velocityZBuffer;
|
||||||
|
divergencePass(divergence, pressureCurrent, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer);
|
||||||
|
|
||||||
|
for (int iteration = 0; iteration < 4; ++iteration) {
|
||||||
|
linearSolvePass(pressureNext, pressureCurrent, divergence, 1, 6);
|
||||||
|
|
||||||
|
setBoundsPass(pressureNext, 0);
|
||||||
|
|
||||||
|
// swap pressure buffers
|
||||||
|
SWAP(pressureCurrent, pressureNext);
|
||||||
|
}
|
||||||
|
|
||||||
|
projectPass(velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, pressureCurrent);
|
||||||
|
|
||||||
|
setBoundsPass(velocityX0Buffer, 1);
|
||||||
|
setBoundsPass(velocityY0Buffer, 2);
|
||||||
|
setBoundsPass(velocityZ0Buffer, 3);
|
||||||
|
|
||||||
|
advectPass(velocityXBuffer, velocityX0Buffer, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, dt);
|
||||||
|
advectPass(velocityYBuffer, velocityY0Buffer, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, dt);
|
||||||
|
advectPass(velocityZBuffer, velocityZ0Buffer, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, dt);
|
||||||
|
|
||||||
|
setBoundsPass(velocityXBuffer, 1);
|
||||||
|
setBoundsPass(velocityYBuffer, 2);
|
||||||
|
setBoundsPass(velocityZBuffer, 3);
|
||||||
|
|
||||||
|
// swap velocity buffers
|
||||||
|
SWAP(velocityX0Buffer, velocityXBuffer);
|
||||||
|
SWAP(velocityY0Buffer, velocityYBuffer);
|
||||||
|
SWAP(velocityZ0Buffer, velocityZBuffer);
|
||||||
|
|
||||||
|
// diffuse density
|
||||||
|
for (int iteration = 0; iteration < 4; ++iteration) {
|
||||||
|
float a = dt * diffusion * (gridSize - 2) * (gridSize - 2) * (gridSize - 2);
|
||||||
|
float c = 1 + 6 * a;
|
||||||
|
linearSolvePass(scratchBuffer, densityBuffer, densityBuffer, a, c);
|
||||||
|
setBoundsPass(scratchBuffer, 0);
|
||||||
|
}
|
||||||
|
advectPass(densityBuffer, scratchBuffer, velocityX0Buffer, velocityY0Buffer, velocityZ0Buffer, dt);
|
||||||
|
setBoundsPass(densityBuffer, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationComputePass::endFrame() {}
|
||||||
|
|
||||||
|
void SimulationComputePass::publishOutputs() { resources->registerBufferOutput("DENSITY", densityBuffer); }
|
||||||
|
|
||||||
|
void SimulationComputePass::createRenderPass() {}
|
||||||
|
|
||||||
|
void SimulationComputePass::setBoundsPass(Gfx::PShaderBuffer grid, int b) {
|
||||||
|
Gfx::ODescriptorSet bounds = setBounds.descriptorLayout->allocateDescriptorSet();
|
||||||
|
bounds->updateConstants("b", 0, &b);
|
||||||
|
bounds->updateBuffer("grid", 0, grid);
|
||||||
|
bounds->writeChanges();
|
||||||
|
Gfx::OComputeCommand boundsCommand = graphics->createComputeCommand();
|
||||||
|
boundsCommand->bindPipeline(setBounds.pipeline);
|
||||||
|
boundsCommand->bindDescriptor(bounds);
|
||||||
|
boundsCommand->dispatch(gridSize / setBounds.threadGroupSize.x, gridSize / setBounds.threadGroupSize.y, 1);
|
||||||
|
graphics->executeCommands(std::move(boundsCommand));
|
||||||
|
|
||||||
|
grid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
|
||||||
|
Gfx::OComputeCommand edgesCommand = graphics->createComputeCommand();
|
||||||
|
edgesCommand->bindPipeline(setBounds.pipelineEdges);
|
||||||
|
edgesCommand->bindDescriptor(bounds);
|
||||||
|
edgesCommand->dispatch(gridSize / setBounds.threadGroupSize.x, 1, 1);
|
||||||
|
graphics->executeCommands(std::move(edgesCommand));
|
||||||
|
|
||||||
|
grid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_READ_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_WRITE_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
|
||||||
|
Gfx::OComputeCommand cornersCommand = graphics->createComputeCommand();
|
||||||
|
cornersCommand->bindPipeline(setBounds.pipelineCorners);
|
||||||
|
cornersCommand->bindDescriptor(bounds);
|
||||||
|
cornersCommand->dispatch(1, 1, 1);
|
||||||
|
graphics->executeCommands(std::move(cornersCommand));
|
||||||
|
|
||||||
|
grid->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationComputePass::linearSolvePass(Gfx::PShaderBuffer current, Gfx::PShaderBuffer next, Gfx::PShaderBuffer grid0, float a,
|
||||||
|
float c) {
|
||||||
|
Gfx::ODescriptorSet solve = linearSolve.descriptorLayout->allocateDescriptorSet();
|
||||||
|
solve->updateBuffer("grid0", 0, grid0);
|
||||||
|
solve->updateBuffer("current", 0, current);
|
||||||
|
solve->updateBuffer("next", 0, next);
|
||||||
|
solve->updateConstants("a", 0, &a);
|
||||||
|
solve->updateConstants("c", 0, &c);
|
||||||
|
solve->writeChanges();
|
||||||
|
Gfx::OComputeCommand solveCommand = graphics->createComputeCommand();
|
||||||
|
solveCommand->bindPipeline(linearSolve.pipeline);
|
||||||
|
solveCommand->bindDescriptor(solve);
|
||||||
|
solveCommand->dispatch(gridSize / linearSolve.threadGroupSize.x, gridSize / linearSolve.threadGroupSize.y,
|
||||||
|
gridSize / linearSolve.threadGroupSize.z);
|
||||||
|
graphics->executeCommands(std::move(solveCommand));
|
||||||
|
|
||||||
|
next->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
}
|
||||||
|
void SimulationComputePass::divergencePass(Seele::Gfx::PShaderBuffer divergence, Seele::Gfx::PShaderBuffer pressure,
|
||||||
|
Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY,
|
||||||
|
Seele::Gfx::PShaderBuffer velocityZ) {
|
||||||
|
Gfx::ODescriptorSet divergenceSet = computeDivergence.descriptorLayout->allocateDescriptorSet();
|
||||||
|
divergenceSet->updateBuffer("velocityX", 0, velocityX);
|
||||||
|
divergenceSet->updateBuffer("velocityY", 0, velocityY);
|
||||||
|
divergenceSet->updateBuffer("velocityZ", 0, velocityZ);
|
||||||
|
divergenceSet->updateBuffer("divergence", 0, divergence);
|
||||||
|
divergenceSet->updateBuffer("pressure", 0, pressure);
|
||||||
|
divergenceSet->writeChanges();
|
||||||
|
Gfx::OComputeCommand divergenceCommand = graphics->createComputeCommand();
|
||||||
|
divergenceCommand->bindPipeline(computeDivergence.pipeline);
|
||||||
|
divergenceCommand->bindDescriptor(divergenceSet);
|
||||||
|
divergenceCommand->dispatch(gridSize / computeDivergence.threadGroupSize.x, gridSize / computeDivergence.threadGroupSize.y,
|
||||||
|
gridSize / computeDivergence.threadGroupSize.z);
|
||||||
|
graphics->executeCommands(std::move(divergenceCommand));
|
||||||
|
// divergence is now in velocityXBuffer, pressure is in velocityYBuffer
|
||||||
|
divergence->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
pressure->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationComputePass::projectPass(Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY,
|
||||||
|
Seele::Gfx::PShaderBuffer velocityZ, Seele::Gfx::PShaderBuffer pressure) {
|
||||||
|
Gfx::ODescriptorSet projectSet = project.descriptorLayout->allocateDescriptorSet();
|
||||||
|
projectSet->updateBuffer("velocityX", 0, velocityX);
|
||||||
|
projectSet->updateBuffer("velocityY", 0, velocityY);
|
||||||
|
projectSet->updateBuffer("velocityZ", 0, velocityZ);
|
||||||
|
projectSet->updateBuffer("pressure", 0, pressure);
|
||||||
|
projectSet->writeChanges();
|
||||||
|
Gfx::OComputeCommand projectCommand = graphics->createComputeCommand();
|
||||||
|
projectCommand->bindPipeline(project.pipeline);
|
||||||
|
projectCommand->bindDescriptor(projectSet);
|
||||||
|
projectCommand->dispatch(gridSize / project.threadGroupSize.x, gridSize / project.threadGroupSize.y,
|
||||||
|
gridSize / project.threadGroupSize.z);
|
||||||
|
graphics->executeCommands(std::move(projectCommand));
|
||||||
|
|
||||||
|
velocityX->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
velocityY->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
velocityZ->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SimulationComputePass::advectPass(Gfx::PShaderBuffer quantity, Gfx::PShaderBuffer quantity0, Gfx::PShaderBuffer velocityX,
|
||||||
|
Gfx::PShaderBuffer velocityY, Gfx::PShaderBuffer velocityZ, float dt) {
|
||||||
|
Gfx::ODescriptorSet advectSet = this->advect.descriptorLayout->allocateDescriptorSet();
|
||||||
|
advectSet->updateBuffer("density", 0, quantity);
|
||||||
|
advectSet->updateBuffer("density0", 0, quantity0);
|
||||||
|
advectSet->updateBuffer("velocityX", 0, velocityX);
|
||||||
|
advectSet->updateBuffer("velocityY", 0, velocityY);
|
||||||
|
advectSet->updateBuffer("velocityZ", 0, velocityZ);
|
||||||
|
advectSet->updateConstants("dt", 0, &dt);
|
||||||
|
advectSet->writeChanges();
|
||||||
|
Gfx::OComputeCommand advectCommand = graphics->createComputeCommand();
|
||||||
|
advectCommand->bindPipeline(advect.pipeline);
|
||||||
|
advectCommand->bindDescriptor(advectSet);
|
||||||
|
advectCommand->dispatch(gridSize / advect.threadGroupSize.x, gridSize / advect.threadGroupSize.y, gridSize / advect.threadGroupSize.z);
|
||||||
|
graphics->executeCommands(std::move(advectCommand));
|
||||||
|
|
||||||
|
quantity->pipelineBarrier(Gfx::SE_ACCESS_SHADER_WRITE_BIT, Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT, Gfx::SE_ACCESS_SHADER_READ_BIT,
|
||||||
|
Gfx::SE_PIPELINE_STAGE_COMPUTE_SHADER_BIT);
|
||||||
|
}
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Graphics/Buffer.h"
|
||||||
|
#include "Graphics/Descriptor.h"
|
||||||
|
#include "Graphics/Initializer.h"
|
||||||
|
#include "Graphics/RenderPass/RenderPass.h"
|
||||||
|
#include "Graphics/Resources.h"
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
class SimulationComputePass : public Seele::RenderPass {
|
||||||
|
public:
|
||||||
|
SimulationComputePass(Seele::Gfx::PGraphics graphics);
|
||||||
|
virtual ~SimulationComputePass() override;
|
||||||
|
virtual void beginFrame(const Seele::Component::Camera &camera, const Seele::Component::Transform &transform) override;
|
||||||
|
virtual void render() override;
|
||||||
|
virtual void endFrame() override;
|
||||||
|
virtual void publishOutputs() override;
|
||||||
|
virtual void createRenderPass() override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setBoundsPass(Seele::Gfx::PShaderBuffer buffer, int b);
|
||||||
|
void linearSolvePass(Seele::Gfx::PShaderBuffer next, Seele::Gfx::PShaderBuffer current, Seele::Gfx::PShaderBuffer grid0, float a, float c);
|
||||||
|
void divergencePass(Seele::Gfx::PShaderBuffer divergence, Seele::Gfx::PShaderBuffer pressure, Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY, Seele::Gfx::PShaderBuffer velocityZ);
|
||||||
|
void projectPass(Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY, Seele::Gfx::PShaderBuffer velocityZ, Seele::Gfx::PShaderBuffer pressure);
|
||||||
|
void advectPass(Seele::Gfx::PShaderBuffer quantity, Seele::Gfx::PShaderBuffer quantity0, Seele::Gfx::PShaderBuffer velocityX, Seele::Gfx::PShaderBuffer velocityY, Seele::Gfx::PShaderBuffer velocityZ, float dt);
|
||||||
|
float viscosity = 0.001f;
|
||||||
|
float diffusion = 0.0001f;
|
||||||
|
float dt = 0.1f;
|
||||||
|
constexpr static uint gridSize = 128;
|
||||||
|
struct SetBounds
|
||||||
|
{
|
||||||
|
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||||
|
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||||
|
Seele::Gfx::OComputeShader shader;
|
||||||
|
Seele::Gfx::PComputePipeline pipeline;
|
||||||
|
Seele::Gfx::OComputeShader shaderEdges;
|
||||||
|
Seele::Gfx::PComputePipeline pipelineEdges;
|
||||||
|
Seele::Gfx::OComputeShader shaderCorners;
|
||||||
|
Seele::Gfx::PComputePipeline pipelineCorners;
|
||||||
|
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||||
|
} setBounds;
|
||||||
|
struct LinearSolve
|
||||||
|
{
|
||||||
|
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||||
|
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||||
|
Seele::Gfx::OComputeShader shader;
|
||||||
|
Seele::Gfx::PComputePipeline pipeline;
|
||||||
|
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||||
|
} linearSolve;
|
||||||
|
struct ComputeDivergence
|
||||||
|
{
|
||||||
|
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||||
|
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||||
|
Seele::Gfx::OComputeShader shader;
|
||||||
|
Seele::Gfx::PComputePipeline pipeline;
|
||||||
|
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||||
|
} computeDivergence;
|
||||||
|
struct Project
|
||||||
|
{
|
||||||
|
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||||
|
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||||
|
Seele::Gfx::OComputeShader shader;
|
||||||
|
Seele::Gfx::PComputePipeline pipeline;
|
||||||
|
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||||
|
} project;
|
||||||
|
struct Advect
|
||||||
|
{
|
||||||
|
Seele::Gfx::OPipelineLayout pipelineLayout;
|
||||||
|
Seele::Gfx::ODescriptorLayout descriptorLayout;
|
||||||
|
Seele::Gfx::OComputeShader shader;
|
||||||
|
Seele::Gfx::PComputePipeline pipeline;
|
||||||
|
constexpr static Seele::UVector threadGroupSize = {32, 8, 1};
|
||||||
|
} advect;
|
||||||
|
Seele::Gfx::OShaderBuffer densityBuffer;
|
||||||
|
Seele::Gfx::OShaderBuffer scratchBuffer;
|
||||||
|
Seele::Gfx::OShaderBuffer velocityXNextBuffer;
|
||||||
|
Seele::Gfx::OShaderBuffer velocityYNextBuffer;
|
||||||
|
Seele::Gfx::OShaderBuffer velocityZNextBuffer;
|
||||||
|
Seele::Gfx::OShaderBuffer velocityXBuffer;
|
||||||
|
Seele::Gfx::OShaderBuffer velocityYBuffer;
|
||||||
|
Seele::Gfx::OShaderBuffer velocityZBuffer;
|
||||||
|
Seele::Gfx::OShaderBuffer velocityX0Buffer;
|
||||||
|
Seele::Gfx::OShaderBuffer velocityY0Buffer;
|
||||||
|
Seele::Gfx::OShaderBuffer velocityZ0Buffer;
|
||||||
|
};
|
||||||
|
DEFINE_REF(SimulationComputePass)
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
#include "FluidSimulationView.h"
|
||||||
|
#include "Graphics/Initializer.h"
|
||||||
|
#include "Graphics/Vulkan/Graphics.h"
|
||||||
|
#include "Window/WindowManager.h"
|
||||||
|
|
||||||
|
using namespace Seele;
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Gfx::OGraphics graphics = new Vulkan::Graphics();
|
||||||
|
graphics->init(GraphicsInitializer());
|
||||||
|
OWindowManager windowManager = new WindowManager();
|
||||||
|
auto window = windowManager->addWindow(graphics, WindowCreateInfo{
|
||||||
|
.title = "Seele Fluid Simulation",
|
||||||
|
.width = 1280,
|
||||||
|
.height = 720,
|
||||||
|
});
|
||||||
|
auto view = new FluidSimulationView(graphics, window,
|
||||||
|
ViewportCreateInfo{
|
||||||
|
.dimensions =
|
||||||
|
{
|
||||||
|
.size =
|
||||||
|
{
|
||||||
|
1280,
|
||||||
|
720,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
view->setFocused();
|
||||||
|
window->show();
|
||||||
|
while(!window->shouldClose()) {
|
||||||
|
windowManager->render();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"dependencies": [
|
||||||
|
{
|
||||||
|
"name": "vulkan"
|
||||||
|
},
|
||||||
|
"vulkan-loader",
|
||||||
|
{
|
||||||
|
"name": "vulkan-memory-allocator"
|
||||||
|
},
|
||||||
|
"assimp",
|
||||||
|
"stb",
|
||||||
|
"entt",
|
||||||
|
"freetype",
|
||||||
|
"glfw3",
|
||||||
|
"glm",
|
||||||
|
"ktx",
|
||||||
|
"nlohmann-json",
|
||||||
|
"fmt",
|
||||||
|
"gtest",
|
||||||
|
"lunasvg",
|
||||||
|
"harfbuzz",
|
||||||
|
"shader-slang",
|
||||||
|
"metis",
|
||||||
|
"meshoptimizer"
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user