// RUN: %dxc -E main -T cs_6_0 %s | FileCheck %s // CHECK: threadId // CHECK: bufferLoad // CHECK: FMax // CHECK: FMin // CHECK: IMad // CHECK: bufferStore //-------------------------------------------------------------------------------------- // File: FluidCS11.hlsl // // Copyright (c) Microsoft Corporation. All rights reserved. //-------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------- // Smoothed Particle Hydrodynamics Algorithm Based Upon: // Particle-Based Fluid Simulation for Interactive Applications // Matthias Müller //-------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------- // Optimized Grid Algorithm Based Upon: // Broad-Phase Collision Detection with CUDA // Scott Le Grand //-------------------------------------------------------------------------------------- struct Particle { float2 position; float2 velocity; }; struct ParticleForces { float2 acceleration; }; struct ParticleDensity { float density; }; cbuffer cbSimulationConstants : register( b0 ) { uint g_iNumParticles; float g_fTimeStep; float g_fSmoothlen; float g_fPressureStiffness; float g_fRestDensity; float g_fDensityCoef; float g_fGradPressureCoef; float g_fLapViscosityCoef; float g_fWallStiffness; float4 g_vGravity; float4 g_vGridDim; float3 g_vPlanes[4]; }; //-------------------------------------------------------------------------------------- // Fluid Simulation //-------------------------------------------------------------------------------------- #define SIMULATION_BLOCK_SIZE 256 //-------------------------------------------------------------------------------------- // Structured Buffers //-------------------------------------------------------------------------------------- RWStructuredBuffer ParticlesRW : register( u0 ); StructuredBuffer ParticlesRO : register( t0 ); RWStructuredBuffer ParticlesDensityRW : register( u0 ); StructuredBuffer ParticlesDensityRO : register( t1 ); RWStructuredBuffer ParticlesForcesRW : register( u0 ); StructuredBuffer ParticlesForcesRO : register( t2 ); RWStructuredBuffer GridRW : register( u0 ); StructuredBuffer GridRO : register( t3 ); RWStructuredBuffer GridIndicesRW : register( u0 ); StructuredBuffer GridIndicesRO : register( t4 ); //-------------------------------------------------------------------------------------- // Grid Construction //-------------------------------------------------------------------------------------- // For simplicity, this sample uses a 16-bit hash based on the grid cell and // a 16-bit particle ID to keep track of the particles while sorting // This imposes a limitation of 64K particles and 256x256 grid work // You could extended the implementation to support large scenarios by using a uint2 float2 GridCalculateCell(float2 position) { return clamp(position * g_vGridDim.xy + g_vGridDim.zw, float2(0, 0), float2(255, 255)); } unsigned int GridConstuctKey(uint2 xy) { // Bit pack [-----UNUSED-----][----Y---][----X---] // 16-bit 8-bit 8-bit return dot(xy.yx, uint2(256, 1)); } unsigned int GridConstuctKeyValuePair(uint2 xy, uint value) { // Bit pack [----Y---][----X---][-----VALUE------] // 8-bit 8-bit 16-bit return dot(uint3(xy.yx, value), uint3(256*256*256, 256*256, 1)); } unsigned int GridGetKey(unsigned int keyvaluepair) { return (keyvaluepair >> 16); } unsigned int GridGetValue(unsigned int keyvaluepair) { return (keyvaluepair & 0xFFFF); } //-------------------------------------------------------------------------------------- // Build Grid //-------------------------------------------------------------------------------------- [numthreads(SIMULATION_BLOCK_SIZE, 1, 1)] void main( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex ) { const unsigned int P_ID = DTid.x; // Particle ID to operate on float2 position = ParticlesRO[P_ID].position; float2 grid_xy = GridCalculateCell( position ); GridRW[P_ID] = GridConstuctKeyValuePair((uint2)grid_xy, P_ID); }