simplify more
This commit is contained in:
parent
f03da42b5e
commit
2fe3c69963
40 changed files with 690 additions and 873 deletions
|
|
@ -1,25 +1,9 @@
|
|||
const AGENT_WORKGROUP_SIZE = 64;
|
||||
const AGENT_MAX_DISPATCH_WORKGROUPS_PER_DIMENSION = 65_535;
|
||||
export const AGENT_MAX_DISPATCHABLE_COUNT =
|
||||
AGENT_MAX_DISPATCH_WORKGROUPS_PER_DIMENSION * AGENT_WORKGROUP_SIZE;
|
||||
|
||||
const getAgentDispatchWorkgroups = (agentCount: number): [number, number] => {
|
||||
if (!Number.isFinite(agentCount) || agentCount <= 0) {
|
||||
throw new Error('Agent count must be a positive finite number');
|
||||
}
|
||||
|
||||
const workgroupCount = Math.ceil(agentCount / AGENT_WORKGROUP_SIZE);
|
||||
if (workgroupCount > AGENT_MAX_DISPATCH_WORKGROUPS_PER_DIMENSION) {
|
||||
throw new Error('Agent count exceeds dispatchable workgroup range');
|
||||
}
|
||||
|
||||
return [workgroupCount, 1];
|
||||
};
|
||||
export const AGENT_MAX_DISPATCHABLE_COUNT = 65_535 * AGENT_WORKGROUP_SIZE;
|
||||
|
||||
export const dispatchAgentWorkgroups = (
|
||||
passEncoder: GPUComputePassEncoder,
|
||||
agentCount: number
|
||||
): void => {
|
||||
const [workgroupX, workgroupY] = getAgentDispatchWorkgroups(agentCount);
|
||||
passEncoder.dispatchWorkgroups(workgroupX, workgroupY);
|
||||
passEncoder.dispatchWorkgroups(Math.ceil(agentCount / AGENT_WORKGROUP_SIZE), 1);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { vec2 } from 'gl-matrix';
|
||||
|
||||
import { createBindGroupCache } from '../../../utils/graphics/bind-group-cache';
|
||||
import { smartCompile } from '../../../utils/graphics/smart-compile';
|
||||
import { AGENT_MAX_DISPATCHABLE_COUNT, dispatchAgentWorkgroups } from '../agent-dispatch';
|
||||
import compactionShader from './agent-compaction.wgsl?raw';
|
||||
|
|
@ -17,10 +18,18 @@ export class AgentGenerationPipeline {
|
|||
|
||||
private readonly bindGroupLayout: GPUBindGroupLayout;
|
||||
private readonly uniforms: GPUBuffer;
|
||||
private readonly bindGroupsByActiveBuffer = new WeakMap<
|
||||
GPUBuffer,
|
||||
WeakMap<GPUBuffer, GPUBindGroup>
|
||||
>();
|
||||
private readonly bindGroupCache = createBindGroupCache<GPUBuffer, GPUBuffer>(
|
||||
(active, inactive) =>
|
||||
this.device.createBindGroup({
|
||||
layout: this.bindGroupLayout,
|
||||
entries: [
|
||||
{ binding: 0, resource: { buffer: this.uniforms } },
|
||||
{ binding: 1, resource: { buffer: active } },
|
||||
{ binding: 2, resource: { buffer: this.countersBuffer } },
|
||||
{ binding: 3, resource: { buffer: inactive } },
|
||||
],
|
||||
})
|
||||
);
|
||||
|
||||
private readonly resizePipeline: GPUComputePipeline;
|
||||
private readonly compactionPipeline: GPUComputePipeline;
|
||||
|
|
@ -244,7 +253,6 @@ export class AgentGenerationPipeline {
|
|||
this.resizeUniformFloatValues[0] = scale[0];
|
||||
this.resizeUniformFloatValues[1] = scale[1];
|
||||
this.resizeUniformUintValues[2] = Math.max(0, Math.floor(agentCount));
|
||||
this.resizeUniformUintValues[3] = 0;
|
||||
this.device.queue.writeBuffer(this.uniforms, 0, this.resizeUniformBuffer);
|
||||
|
||||
const commandEncoder = this.device.createCommandEncoder();
|
||||
|
|
@ -314,49 +322,7 @@ export class AgentGenerationPipeline {
|
|||
}
|
||||
|
||||
private getBindGroup(): GPUBindGroup {
|
||||
let inactiveCache = this.bindGroupsByActiveBuffer.get(this.activeAgentsBuffer);
|
||||
if (!inactiveCache) {
|
||||
inactiveCache = new WeakMap<GPUBuffer, GPUBindGroup>();
|
||||
this.bindGroupsByActiveBuffer.set(this.activeAgentsBuffer, inactiveCache);
|
||||
}
|
||||
|
||||
const cached = inactiveCache.get(this.inactiveAgentsBuffer);
|
||||
if (cached) {
|
||||
return cached;
|
||||
}
|
||||
|
||||
const bindGroup = this.device.createBindGroup({
|
||||
layout: this.bindGroupLayout,
|
||||
entries: [
|
||||
{
|
||||
binding: 0,
|
||||
resource: {
|
||||
buffer: this.uniforms,
|
||||
},
|
||||
},
|
||||
{
|
||||
binding: 1,
|
||||
resource: {
|
||||
buffer: this.activeAgentsBuffer,
|
||||
},
|
||||
},
|
||||
{
|
||||
binding: 2,
|
||||
resource: {
|
||||
buffer: this.countersBuffer,
|
||||
},
|
||||
},
|
||||
{
|
||||
binding: 3,
|
||||
resource: {
|
||||
buffer: this.inactiveAgentsBuffer,
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
inactiveCache.set(this.inactiveAgentsBuffer, bindGroup);
|
||||
return bindGroup;
|
||||
return this.bindGroupCache(this.activeAgentsBuffer, this.inactiveAgentsBuffer);
|
||||
}
|
||||
|
||||
private swapAgentBuffers(): void {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
struct ResizeSettings {
|
||||
scale: vec2<f32>,
|
||||
agentCount: u32,
|
||||
padding: u32,
|
||||
};
|
||||
|
||||
@group(1) @binding(0) var<uniform> resizeSettings: ResizeSettings;
|
||||
|
|
|
|||
|
|
@ -6,9 +6,38 @@ import { smartCompile } from '../../utils/graphics/smart-compile';
|
|||
import { CommonState } from '../common-state/common-state';
|
||||
import { dispatchAgentWorkgroups } from './agent-dispatch';
|
||||
import agentSchema from './agent-generation/agent-schema.wgsl?raw';
|
||||
import { AgentSettings } from './agent-settings';
|
||||
import shader from './agent.wgsl?raw';
|
||||
|
||||
export interface AgentSettings {
|
||||
color1ToColor1: number;
|
||||
color1ToColor2: number;
|
||||
color1ToColor3: number;
|
||||
color2ToColor1: number;
|
||||
color2ToColor2: number;
|
||||
color2ToColor3: number;
|
||||
color3ToColor1: number;
|
||||
color3ToColor2: number;
|
||||
color3ToColor3: number;
|
||||
moveSpeed: number;
|
||||
turnSpeed: number;
|
||||
sensorOffsetAngle: number;
|
||||
sensorOffsetDistance: number;
|
||||
turnWhenLost: number;
|
||||
individualTrailWeight: number;
|
||||
forwardRotationScale: number;
|
||||
introNearDistanceMin: number;
|
||||
introNearSensorOffsetMultiplier: number;
|
||||
introTargetAngleBlend: number;
|
||||
introProgressCutoff: number;
|
||||
introNearDistanceInner: number;
|
||||
introTurnRateMultiplier: number;
|
||||
introRandomTurnMultiplier: number;
|
||||
introFarMoveMultiplier: number;
|
||||
introNearMoveMultiplier: number;
|
||||
introStepStopDistance: number;
|
||||
randomTimeScale: number;
|
||||
}
|
||||
|
||||
export class AgentPipeline {
|
||||
private static readonly UNIFORM_COUNT = 30;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,29 +0,0 @@
|
|||
export interface AgentSettings {
|
||||
color1ToColor1: number;
|
||||
color1ToColor2: number;
|
||||
color1ToColor3: number;
|
||||
color2ToColor1: number;
|
||||
color2ToColor2: number;
|
||||
color2ToColor3: number;
|
||||
color3ToColor1: number;
|
||||
color3ToColor2: number;
|
||||
color3ToColor3: number;
|
||||
moveSpeed: number;
|
||||
turnSpeed: number;
|
||||
sensorOffsetAngle: number;
|
||||
sensorOffsetDistance: number;
|
||||
turnWhenLost: number;
|
||||
individualTrailWeight: number;
|
||||
forwardRotationScale: number;
|
||||
introNearDistanceMin: number;
|
||||
introNearSensorOffsetMultiplier: number;
|
||||
introTargetAngleBlend: number;
|
||||
introProgressCutoff: number;
|
||||
introNearDistanceInner: number;
|
||||
introTurnRateMultiplier: number;
|
||||
introRandomTurnMultiplier: number;
|
||||
introFarMoveMultiplier: number;
|
||||
introNearMoveMultiplier: number;
|
||||
introStepStopDistance: number;
|
||||
randomTimeScale: number;
|
||||
}
|
||||
Loading…
Reference in a new issue