Skip to content

Commit

Permalink
combine explicit integration with assign cell shader, and better ping…
Browse files Browse the repository at this point in the history
…-pong
  • Loading branch information
Wayne Wu authored and Wayne Wu committed May 10, 2023
1 parent 0ef9554 commit 3374d00
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 21 deletions.
3 changes: 2 additions & 1 deletion src/sample/crowd/crowdUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,8 +277,9 @@ export class ComputeBufferManager {
});
}

getBindGroup(flip: boolean = false){
getBindGroup(flip: boolean = false, label: string = ""){
const computeBindGroup = this.device.createBindGroup({
label: label,
layout: this.bindGroupLayout,
entries: [
{
Expand Down
42 changes: 23 additions & 19 deletions src/sample/crowd/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { RenderBufferManager } from './renderUtils';
import renderWGSL from '../../shaders/background.render.wgsl';
import crowdWGSL from '../../shaders/crowd.render.wgsl';
import explicitIntegrationWGSL from '../../shaders/explicitIntegration.compute.wgsl';
import assignCellsWGSL from '../../shaders/assignCells.compute.wgsl';
import bitonicSortWGSL from '../../shaders/bitonicSort.compute.wgsl';
import buildHashGrid from '../../shaders/buildHashGrid.compute.wgsl';
import contactSolveWGSL from '../../shaders/contactSolve.compute.wgsl';
Expand Down Expand Up @@ -50,8 +49,8 @@ function fillSortPipelineList(device,
// set up sort pipelines
// adapted from Wikipedia's non-recursive example of bitonic sort:
// https://en.wikipedia.org/wiki/Bitonic_sorter
for (let k = 2; k <= numAgents; k *= 2){ // k is doubled every iteration
for (let j = k/2; j > 0; j = Math.floor(j/2)){ // j is halved at every iteration, with truncation of fractional parts
for (let k = 2; k <= numAgents; k <<= 1){ // k is doubled every iteration
for (let j = k >> 1; j > 0; j >>= 1){ // j is halved at every iteration, with truncation of fractional parts
computePipelinesSort.push(
device.createComputePipeline({
layout: pipelineLayout,
Expand Down Expand Up @@ -250,7 +249,6 @@ const init: SampleInit = async ({ canvasRef, gui, stats }) => {
{
const computeShadersPreSort = [
headerWGSL + explicitIntegrationWGSL,
headerWGSL + assignCellsWGSL,
];
const computeShadersPostSort = [
headerWGSL + buildHashGrid,
Expand Down Expand Up @@ -363,8 +361,17 @@ const init: SampleInit = async ({ canvasRef, gui, stats }) => {
}

// get compute bind group
var computeBindGroup1 = compBuffManager.getBindGroup(false);
var computeBindGroup2 = compBuffManager.getBindGroup(true);
var computeBindGroup1 = compBuffManager.getBindGroup(false, "R1W2");
var computeBindGroup2 = compBuffManager.getBindGroup(true, "R2W1");

var computeBindGroup = computeBindGroup1;

function pingPongBuffer(){
if (computeBindGroup == computeBindGroup1)
computeBindGroup = computeBindGroup2;
else if (computeBindGroup == computeBindGroup2)
computeBindGroup = computeBindGroup1;
}

var time = 0;
function frame() {
Expand Down Expand Up @@ -459,9 +466,10 @@ const init: SampleInit = async ({ canvasRef, gui, stats }) => {
// reinitilize buffers based on the new number of agents
compBuffManager.initBuffers();

computeBindGroup1 = compBuffManager.getBindGroup(false); // READ agents1 WRITE agents2
computeBindGroup2 = compBuffManager.getBindGroup(true); // READ agents2 WRITE agents1

computeBindGroup1 = compBuffManager.getBindGroup(false, "R1W2"); // READ agents1 WRITE agents2
computeBindGroup2 = compBuffManager.getBindGroup(true, "R2W1"); // READ agents2 WRITE agents1
computeBindGroup = computeBindGroup1;

// the number of steps in the sort pipeline is proportional
// to log2 the number of agents, so reinitiliaze it
fillSortPipelineList(device,
Expand All @@ -478,14 +486,13 @@ const init: SampleInit = async ({ canvasRef, gui, stats }) => {
const computeWorkgroupCount = Math.ceil(compBuffManager.numAgents/64);
const sortWorkgroupCount = Math.ceil(compBuffManager.numAgents/256);


// write the parameters to the Uniform buffer for our compute shaders
compBuffManager.writeSimParams(simulationParams);

// execute each compute shader in the order they were pushed onto
// the computePipelines array
var passEncoder = command.beginComputePass();
passEncoder.setBindGroup(0, computeBindGroup1);
passEncoder.setBindGroup(0, computeBindGroup);

//// ----- Compute Pass Before Sort -----
for (let i = 0; i < computePipelinesPreSort.length; i++){
Expand All @@ -505,21 +512,16 @@ const init: SampleInit = async ({ canvasRef, gui, stats }) => {
passEncoder.setPipeline(computePipelinesPostSort[i]);
passEncoder.dispatchWorkgroups(computeWorkgroupCount);
}

// Stability/Contact solve will write to different buffer
var computeBindGroup = computeBindGroup2;

pingPongBuffer();

// ----- Compute Pass Constraint Solve -----
for (; i < 6; i++) {
passEncoder.setPipeline(computePipelinesPostSort[i]);
passEncoder.setBindGroup(0, computeBindGroup);
passEncoder.dispatchWorkgroups(computeWorkgroupCount);

// ping-pong buffers
if(computeBindGroup == computeBindGroup1)
computeBindGroup = computeBindGroup2;
else if(computeBindGroup == computeBindGroup2)
computeBindGroup = computeBindGroup1;
pingPongBuffer();
}

passEncoder.setBindGroup(0, computeBindGroup);
Expand All @@ -530,6 +532,8 @@ const init: SampleInit = async ({ canvasRef, gui, stats }) => {
passEncoder.dispatchWorkgroups(computeWorkgroupCount);
}

pingPongBuffer();

passEncoder.end();
}
}
Expand Down
31 changes: 30 additions & 1 deletion src/shaders/explicitIntegration.compute.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@ fn getVelocityFromPlanner(agent : Agent) -> vec3<f32> {
fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {

var idx = GlobalInvocationID.x;
var agent = agentData.agents[idx];

if (idx >= u32(sim_params.numAgents)){
return;
}

var agent = agentData.agents[idx];

// velcity planning
var vp = getVelocityFromPlanner(agent);

Expand All @@ -29,6 +30,34 @@ fn main(@builtin(global_invocation_id) GlobalInvocationID : vec3<u32>) {
// explicit integration
agent.xp = agent.x + sim_params.deltaTime * agent.v;

if (distance(agent.x, agent.goal) < 1.0){
// // if we're close enough to the goal, (somewhat) smoothly place them
// // on the goal and set the cell to invalid so future computation largely
// // ignores them
// agent.x = ((agent.x * 10.0) + agent.goal) / 11.0;
agent.cell = -2;
agent.c = rainbowCycle(sim_params.tick);
}
else {
var gridWidth = sim_params.gridWidth;
var gridHeight = sim_params.gridWidth;
var cellWidth = 1000.0 / gridWidth;

var posCellSpace = worldSpacePosToCellSpace(agent.x.x,
agent.x.z,
gridWidth,
cellWidth);

var cellXY = cellSpaceToCell2d(posCellSpace.x, posCellSpace.y, cellWidth);

agent.cell = cell2dto1d(cellXY.x, cellXY.y, gridWidth);
if (cellXY.x >= i32(gridWidth) || cellXY.y >= i32(gridHeight) ||
posCellSpace.x < 0.0 || posCellSpace.y < 0.0) {
agent.cell = -1;
agent.c = vec4<f32>(0.5, 0.5, 0.5, 1.0);
}
}

// Store the new agent value
agentData.agents[idx] = agent;
}

0 comments on commit 3374d00

Please sign in to comment.