more
This commit is contained in:
parent
2fe3c69963
commit
6bc125be1c
104 changed files with 3084 additions and 2410 deletions
|
|
@ -1,10 +1,13 @@
|
|||
import { appConfig } from '../config';
|
||||
import { AgentPipeline } from '../pipelines/agents/agent-pipeline';
|
||||
import { BrushPipeline } from '../pipelines/brush/brush-pipeline';
|
||||
import { DiffusionPipeline } from '../pipelines/diffusion/diffusion-pipeline';
|
||||
import { EraserAgentPipeline } from '../pipelines/eraser/eraser-agent-pipeline';
|
||||
import { EraserTexturePipeline } from '../pipelines/eraser/eraser-texture-pipeline';
|
||||
import { RenderPipeline } from '../pipelines/render/render-pipeline';
|
||||
import { settings } from '../settings';
|
||||
import { CanvasReadbackRequest } from './game-loop-types';
|
||||
import { GpuProfiler } from './gpu-profiler';
|
||||
import { SimulationTextures } from './simulation-textures';
|
||||
|
||||
interface SimulationFramePipelines {
|
||||
|
|
@ -17,15 +20,14 @@ interface SimulationFramePipelines {
|
|||
}
|
||||
|
||||
export class SimulationFrameRenderer {
|
||||
private static readonly SOURCE_ACTIVE_FRAMES_AFTER_WRITE = 600;
|
||||
|
||||
private sourceActiveFramesRemaining = 0;
|
||||
private sourceMapsCleared = true;
|
||||
|
||||
public constructor(
|
||||
private readonly device: GPUDevice,
|
||||
private readonly textures: SimulationTextures,
|
||||
private readonly pipelines: SimulationFramePipelines
|
||||
private readonly pipelines: SimulationFramePipelines,
|
||||
private readonly gpuProfiler: GpuProfiler | null = null
|
||||
) {}
|
||||
|
||||
public resetSourceMapActivity(): void {
|
||||
|
|
@ -33,11 +35,16 @@ export class SimulationFrameRenderer {
|
|||
this.sourceMapsCleared = true;
|
||||
}
|
||||
|
||||
public get isSourceMapActive(): boolean {
|
||||
return this.sourceActiveFramesRemaining > 0;
|
||||
}
|
||||
|
||||
public execute(
|
||||
isErasing: boolean,
|
||||
canvasReadbackRequest?: CanvasReadbackRequest | null
|
||||
): void {
|
||||
const commandEncoder = this.device.createCommandEncoder();
|
||||
this.gpuProfiler?.beginFrame();
|
||||
|
||||
this.textures.copyTrailMapAToB(commandEncoder);
|
||||
let wroteSourceMap = false;
|
||||
|
|
@ -48,24 +55,29 @@ export class SimulationFrameRenderer {
|
|||
commandEncoder,
|
||||
eraserMask,
|
||||
this.textures.sourceMapA.getTextureView(),
|
||||
this.textures.trailMapB.getTextureView()
|
||||
this.textures.trailMapB.getTextureView(),
|
||||
this.gpuProfiler?.timestampWrites('eraserTexture')
|
||||
);
|
||||
this.pipelines.eraserAgentPipeline.execute(
|
||||
commandEncoder,
|
||||
eraserMask,
|
||||
this.gpuProfiler?.timestampWrites('eraserAgent')
|
||||
);
|
||||
this.pipelines.eraserAgentPipeline.execute(commandEncoder, eraserMask);
|
||||
}
|
||||
} else {
|
||||
wroteSourceMap = this.pipelines.brushPipeline.executeMultiTarget(
|
||||
commandEncoder,
|
||||
this.textures.sourceMapA.getTextureView()
|
||||
this.textures.sourceMapA.getTextureView(),
|
||||
this.gpuProfiler?.timestampWrites('brush')
|
||||
);
|
||||
}
|
||||
|
||||
if (wroteSourceMap) {
|
||||
this.sourceActiveFramesRemaining =
|
||||
SimulationFrameRenderer.SOURCE_ACTIVE_FRAMES_AFTER_WRITE;
|
||||
this.sourceActiveFramesRemaining = getSourceActiveFrameCount();
|
||||
this.sourceMapsCleared = false;
|
||||
}
|
||||
|
||||
const useSourceMap = this.sourceActiveFramesRemaining > 0;
|
||||
const useSourceMap = this.isSourceMapActive;
|
||||
if (!useSourceMap && !this.sourceMapsCleared) {
|
||||
this.textures.clearSourceMaps(commandEncoder);
|
||||
this.sourceMapsCleared = true;
|
||||
|
|
@ -74,19 +86,22 @@ export class SimulationFrameRenderer {
|
|||
this.pipelines.agentPipeline.execute(
|
||||
commandEncoder,
|
||||
this.textures.trailMapA.getTextureView(),
|
||||
this.textures.trailMapB.getTextureView()
|
||||
this.textures.trailMapB.getTextureView(),
|
||||
this.gpuProfiler?.timestampWrites('agent')
|
||||
);
|
||||
this.pipelines.diffusionPipeline.execute(
|
||||
commandEncoder,
|
||||
this.textures.trailMapB.getTextureView(),
|
||||
this.textures.trailMapA.getTextureView(),
|
||||
this.textures.trailMapA.getSize()
|
||||
this.textures.trailMapA.getSize(),
|
||||
this.gpuProfiler?.timestampWrites('trailDiffusion')
|
||||
);
|
||||
const canvasTexture = this.pipelines.renderPipeline.execute(
|
||||
commandEncoder,
|
||||
this.textures.trailMapA.getTextureView(),
|
||||
this.textures.sourceMapA.getTextureView(),
|
||||
useSourceMap
|
||||
useSourceMap,
|
||||
this.gpuProfiler?.timestampWrites('render')
|
||||
);
|
||||
canvasReadbackRequest?.encode(commandEncoder, canvasTexture);
|
||||
|
||||
|
|
@ -95,10 +110,13 @@ export class SimulationFrameRenderer {
|
|||
commandEncoder,
|
||||
this.textures.sourceMapA.getTextureView(),
|
||||
this.textures.sourceMapB.getTextureView(),
|
||||
this.textures.sourceMapB.getSize()
|
||||
this.textures.sourceMapB.getSize(),
|
||||
this.gpuProfiler?.timestampWrites('sourceDiffusion')
|
||||
);
|
||||
}
|
||||
const afterGpuProfileSubmit = this.gpuProfiler?.resolve(commandEncoder);
|
||||
this.device.queue.submit([commandEncoder.finish()]);
|
||||
afterGpuProfileSubmit?.();
|
||||
canvasReadbackRequest?.afterSubmit();
|
||||
if (useSourceMap) {
|
||||
this.textures.swapSourceMaps();
|
||||
|
|
@ -106,3 +124,12 @@ export class SimulationFrameRenderer {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getSourceActiveFrameCount = (): number => {
|
||||
const frameCount =
|
||||
settings.brushEffectDuration * appConfig.simulation.brushEffectFramesPerSecond;
|
||||
if (Number.isFinite(frameCount) && frameCount > 0) {
|
||||
return Math.ceil(frameCount);
|
||||
}
|
||||
return Math.max(1, appConfig.simulation.sourceActiveFramesAfterWrite);
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in a new issue