So many changes again

This commit is contained in:
2026-04-15 16:56:19 +02:00
parent 495e683522
commit 424dea0012
30 changed files with 566 additions and 235 deletions
+35
View File
@@ -0,0 +1,35 @@
import FluidGridData;
struct Params
{
// read-write: phi to add source to
FluidGridData<float> phi;
FluidGridData<float> density;
};
ParameterBlock<Params> params;
[shader("compute")]
[numthreads(32, 8, 1)]
void addSource(uint3 dispatchThreadID : SV_DispatchThreadID)
{
FluidGridData<float> phi = params.phi;
FluidGridData<float> density = params.density;
int x = dispatchThreadID.x + 1;
int y = dispatchThreadID.y + 1;
int z = dispatchThreadID.z + 1;
if(x >= gridParams.gridSize.x - 1 || y >= gridParams.gridSize.y - 1 || z >= gridParams.gridSize.z - 1) return;
// Add a spherical source and union it into the existing level set.
float3 center = float3(gridParams.gridSize) * 0.5f;
float radius = min(gridParams.gridSize.x, min(gridParams.gridSize.y, gridParams.gridSize.z)) * 0.25f;
float3 pos = float3(x, y, z);
float dist = length(pos - center);
float sourcePhi = dist - radius;
phi[x, y, z] = min(phi[x, y, z], sourcePhi);
if (sourcePhi < 0.0f)
{
density[x, y, z] += 0.5f;
density[x, y, z] = min(density[x, y, z], 1.0f);
}
}
+7 -7
View File
@@ -30,16 +30,16 @@ void advect(uint3 dispatchThreadID : SV_DispatchThreadID)
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;
if(x >= gridParams.gridSize.x - 1 || y >= gridParams.gridSize.y - 1 || z >= gridParams.gridSize.z - 1) return;
float dt0x = dt * (gridSize.x - 2);
float dt0y = dt * (gridSize.y - 2);
float dt0z = dt * (gridSize.z - 2);
float dt0x = dt * (gridParams.gridSize.x - 2);
float dt0y = dt * (gridParams.gridSize.y - 2);
float dt0z = dt * (gridParams.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);
pos.x = clamp(pos.x, 0.5f, gridParams.gridSize.x - 1.5f);
pos.y = clamp(pos.y, 0.5f, gridParams.gridSize.y - 1.5f);
pos.z = clamp(pos.z, 0.5f, gridParams.gridSize.z - 1.5f);
int3 i0 = int3(pos);
int3 i1 = i0 + int3(1, 1, 1);
+31
View File
@@ -0,0 +1,31 @@
import FluidGridData;
struct Params
{
FluidGridData<float> velocityX;
FluidGridData<float> velocityY;
FluidGridData<float> velocityZ;
float3 force;
float dt;
};
ParameterBlock<Params> params;
[shader("compute")]
[numthreads(32, 8, 1)]
void applyForces(uint3 dispatchThreadID : SV_DispatchThreadID)
{
FluidGridData<float> velocityX = params.velocityX;
FluidGridData<float> velocityY = params.velocityY;
FluidGridData<float> velocityZ = params.velocityZ;
float3 force = params.force;
float dt = params.dt;
int x = dispatchThreadID.x + 1;
int y = dispatchThreadID.y + 1;
int z = dispatchThreadID.z + 1;
if(x >= gridParams.gridSize.x - 1 || y >= gridParams.gridSize.y - 1 || z >= gridParams.gridSize.z - 1) return;
velocityX[x, y, z] += force.x * dt;
velocityY[x, y, z] += force.y * dt;
velocityZ[x, y, z] += force.z * dt;
}
+6 -7
View File
@@ -1,7 +1,6 @@
import FluidGridData;
struct Params
{
struct Params {
// read-only
FluidGridData<float> velocityX;
// read-only
@@ -17,8 +16,7 @@ ParameterBlock<Params> params;
[shader("compute")]
[numthreads(32, 8, 1)]
void computeDivergence(uint3 dispatchThreadID : SV_DispatchThreadID)
{
void computeDivergence(uint3 dispatchThreadID: SV_DispatchThreadID) {
FluidGridData<float> velocityX = params.velocityX;
FluidGridData<float> velocityY = params.velocityY;
FluidGridData<float> velocityZ = params.velocityZ;
@@ -28,8 +26,9 @@ void computeDivergence(uint3 dispatchThreadID : SV_DispatchThreadID)
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;
if (x >= gridParams.gridSize.x - 1 || y >= gridParams.gridSize.y - 1 || z >= gridParams.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;
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]);
pressure[x, y, z] = 0;
}
}
+2 -2
View File
@@ -13,7 +13,7 @@ ParameterBlock<Parameter> params;
float getDensity(uint x, uint y, uint z)
{
return params.density[x + gridSize.x * y + gridSize.x * gridSize.y * z];
return params.density[x + gridParams.gridSize.x * y + gridParams.gridSize.x * gridParams.gridSize.y * z];
}
[shader("compute")]
@@ -24,7 +24,7 @@ void main(uint3 dispatchThreadID : SV_DispatchThreadID)
uint y = dispatchThreadID.y+1;
uint z = dispatchThreadID.z+1;
FluidGridData<float> density = params.density;
if(x >= gridSize.x-3 || y >= gridSize.y-3 || z >= gridSize.z-3) return;
if(x >= gridParams.gridSize.x-3 || y >= gridParams.gridSize.y-3 || z >= gridParams.gridSize.z-3) return;
float phi[8] = {
getDensity(x, y, z),
+9 -5
View File
@@ -1,15 +1,19 @@
static const uint3 gridSize = uint3(256, 256, 256);
struct GridParams
{
uint3 gridSize;
};
ParameterBlock<GridParams> gridParams;
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; }
get { return dataGrid[index.x + index.y * gridParams.gridSize.x + index.z * gridParams.gridSize.x * gridParams.gridSize.y]; }
set { dataGrid[index.x + index.y * gridParams.gridSize.x + index.z * gridParams.gridSize.x * gridParams.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; }
get { return dataGrid[x + y * gridParams.gridSize.x + z * gridParams.gridSize.x * gridParams.gridSize.y]; }
set { dataGrid[x + y * gridParams.gridSize.x + z * gridParams.gridSize.x * gridParams.gridSize.y] = newValue; }
}
};
+1 -1
View File
@@ -26,7 +26,7 @@ void linearSolve(uint3 dispatchThreadID : SV_DispatchThreadID)
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;
if(x >= gridParams.gridSize.x - 1 || y >= gridParams.gridSize.y - 1 || z >= gridParams.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;
}
+3 -3
View File
@@ -12,7 +12,7 @@ struct Params
ParameterBlock<Params> params;
const static float isoLevel = 0.0f;
const static float3 cellSize = 1.0f / gridSize;
const static float3 cellSize = 1.0f / gridParams.gridSize;
float3 vertexInterp(float isoLevel, float3 p1, float3 p2, float valp1, float valp2)
{
@@ -86,7 +86,7 @@ void marchingCubes(uint3 dispatchThreadID : SV_DispatchThreadID, uint groupIndex
// Don't early-return — all threads must participate in barriers.
// Use a flag to skip work for out-of-bounds threads.
bool valid = (x < gridSize.x - 2 && y < gridSize.y - 2 && z < gridSize.z - 2);
bool valid = (x < gridParams.gridSize.x - 2 && y < gridParams.gridSize.y - 2 && z < gridParams.gridSize.z - 2);
float val[8];
uint cubeIndex = 0;
@@ -169,7 +169,7 @@ void marchingCubes(uint3 dispatchThreadID : SV_DispatchThreadID, uint groupIndex
float3 v0 = vertList[triTable[cubeIndex][i]];
float3 v1 = vertList[triTable[cubeIndex][i + 1]];
float3 v2 = vertList[triTable[cubeIndex][i + 2]];
float3 n = normalize(cross(v1 - v0, v2 - v0));
float3 n = normalize(cross(v2 - v0, v1 - v0));
localVertices[localOff] = v0;
localVertices[localOff + 1] = v1;
+4 -4
View File
@@ -25,9 +25,9 @@ void project(uint3 dispatchThreadID : SV_DispatchThreadID)
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;
if(x >= gridParams.gridSize.x - 1 || y >= gridParams.gridSize.y - 1 || z >= gridParams.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;
velocityX[x, y, z] -= 0.5f * (pressure[x + 1, y, z] - pressure[x - 1, y, z]);
velocityY[x, y, z] -= 0.5f * (pressure[x, y + 1, z] - pressure[x, y - 1, z]);
velocityZ[x, y, z] -= 0.5f * (pressure[x, y, z + 1] - pressure[x, y, z - 1]);
}
+4 -1
View File
@@ -5,6 +5,7 @@ import MaterialParameter;
struct Params
{
float4x4 transform;
StructuredBuffer<float> vertexBuffer;
StructuredBuffer<float> normalBuffer;
StructuredBuffer<uint> indexBuffer;
@@ -25,10 +26,12 @@ VertexOut vertexMain(uint vertexId : SV_VertexID)
uint index = params.indexBuffer[vertexId];
float3 vertex = float3(params.vertexBuffer[index * 3 + 0],
params.vertexBuffer[index * 3 + 1],
params.vertexBuffer[index * 3 + 2]) * 5;
params.vertexBuffer[index * 3 + 2]);
float3 normal = float3(params.normalBuffer[index * 3 + 0],
params.normalBuffer[index * 3 + 1],
params.normalBuffer[index * 3 + 2]);
vertex = mul(params.transform, float4(vertex, 1)).xyz;
normal = mul((float3x3)params.transform, normal);
output.position_WS = vertex;
output.position_CS = mul(pViewParams.viewProjectionMatrix, float4(vertex, 1));
output.normal = normal;
+54 -32
View File
@@ -14,18 +14,29 @@ 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];
int i = dispatchThreadID.x + 1;
int j = dispatchThreadID.y + 1;
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];
// X-faces: indices range over (gridSize.y, gridSize.z)
if(i < gridParams.gridSize.y - 1 && j < gridParams.gridSize.z - 1)
{
grid[0, i, j] = b == 1 ? -grid[1, i, j] : grid[1, i, j];
grid[gridParams.gridSize.x - 1, i, j] = b == 1 ? -grid[gridParams.gridSize.x - 2, i, j] : grid[gridParams.gridSize.x - 2, i, j];
}
// Y-faces: indices range over (gridSize.x, gridSize.z)
if(i < gridParams.gridSize.x - 1 && j < gridParams.gridSize.z - 1)
{
grid[i, 0, j] = b == 2 ? -grid[i, 1, j] : grid[i, 1, j];
grid[i, gridParams.gridSize.y - 1, j] = b == 2 ? -grid[i, gridParams.gridSize.y - 2, j] : grid[i, gridParams.gridSize.y - 2, j];
}
// Z-faces: indices range over (gridSize.x, gridSize.y)
if(i < gridParams.gridSize.x - 1 && j < gridParams.gridSize.y - 1)
{
grid[i, j, 0] = b == 3 ? -grid[i, j, 1] : grid[i, j, 1];
grid[i, j, gridParams.gridSize.z - 1] = b == 3 ? -grid[i, j, gridParams.gridSize.z - 2] : grid[i, j, gridParams.gridSize.z - 2];
}
}
[shader("compute")]
@@ -34,22 +45,33 @@ 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]);
// X-axis edges: x ranges [1, gridSize.x-2]
if(x < gridParams.gridSize.x - 1)
{
grid[x, 0, 0] = 0.5f * (grid[x, 1, 0] + grid[x, 0, 1]);
grid[x, gridParams.gridSize.y - 1, 0] = 0.5f * (grid[x, gridParams.gridSize.y - 2, 0] + grid[x, gridParams.gridSize.y - 1, 1]);
grid[x, 0, gridParams.gridSize.z - 1] = 0.5f * (grid[x, 1, gridParams.gridSize.z - 1] + grid[x, 0, gridParams.gridSize.z - 2]);
grid[x, gridParams.gridSize.y - 1, gridParams.gridSize.z - 1] = 0.5f * (grid[x, gridParams.gridSize.y - 2, gridParams.gridSize.z - 1] + grid[x, gridParams.gridSize.y - 1, gridParams.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]);
// Y-axis edges: x ranges [1, gridSize.y-2]
if(x < gridParams.gridSize.y - 1)
{
grid[0, x, 0] = 0.5f * (grid[1, x, 0] + grid[0, x, 1]);
grid[0, x, gridParams.gridSize.z - 1] = 0.5f * (grid[1, x, gridParams.gridSize.z - 1] + grid[0, x, gridParams.gridSize.z - 2]);
grid[gridParams.gridSize.x - 1, x, 0] = 0.5f * (grid[gridParams.gridSize.x - 2, x, 0] + grid[gridParams.gridSize.x - 1, x, 1]);
grid[gridParams.gridSize.x - 1, x, gridParams.gridSize.z - 1] = 0.5f * (grid[gridParams.gridSize.x - 2, x, gridParams.gridSize.z - 1] + grid[gridParams.gridSize.x - 1, x, gridParams.gridSize.z - 2]);
}
// Z-axis edges: x ranges [1, gridSize.z-2]
if(x < gridParams.gridSize.z - 1)
{
grid[0, 0, x] = 0.5f * (grid[1, 0, x] + grid[0, 1, x]);
grid[0, gridParams.gridSize.y - 1, x] = 0.5f * (grid[1, gridParams.gridSize.y - 1, x] + grid[0, gridParams.gridSize.y - 2, x]);
grid[gridParams.gridSize.x - 1, 0, x] = 0.5f * (grid[gridParams.gridSize.x - 2, 0, x] + grid[gridParams.gridSize.x - 1, 1, x]);
grid[gridParams.gridSize.x - 1, gridParams.gridSize.y - 1, x] = 0.5f * (grid[gridParams.gridSize.x - 2, gridParams.gridSize.y - 1, x] + grid[gridParams.gridSize.x - 1, gridParams.gridSize.y - 2, x]);
}
}
[shader("compute")]
@@ -59,13 +81,13 @@ 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 x = ((threadIdx & 1) == 0) ? 0 : (gridParams.gridSize.x - 1);
uint y = ((threadIdx & 2) == 0) ? 0 : (gridParams.gridSize.y - 1);
uint z = ((threadIdx & 4) == 0) ? 0 : (gridParams.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);
uint nx = (x == 0) ? 1 : (gridParams.gridSize.x - 2);
uint ny = (y == 0) ? 1 : (gridParams.gridSize.y - 2);
uint nz = (z == 0) ? 1 : (gridParams.gridSize.z - 2);
grid[x, y, z] = 0.33f * (grid[nx, y, z] + grid[x, ny, z] + grid[x, y, nz]);
grid[x, y, z] = (1.0f / 3.0f) * (grid[nx, y, z] + grid[x, ny, z] + grid[x, y, nz]);
}
+1 -1
View File
@@ -25,7 +25,7 @@ void reinitialize(uint3 dispatchThreadID : SV_DispatchThreadID)
uint z = dispatchThreadID.z + 1;
FluidGridData<float> phi = params.phi;
FluidGridData<float> phi0 = params.phi0;
if(x >= gridSize.x - 1 || y >= gridSize.y - 1 || z >= gridSize.z - 1) return;
if(x >= gridParams.gridSize.x - 1 || y >= gridParams.gridSize.y - 1 || z >= gridParams.gridSize.z - 1) return;
float dtau = params.dtau;
float dx = 1.0f;