Clean up
This commit is contained in:
parent
ea0304356f
commit
7c70f15e49
65 changed files with 1122 additions and 1906 deletions
|
|
@ -14,6 +14,7 @@ export class EraserAgentPipeline {
|
|||
private readonly pipeline: GPUComputePipeline;
|
||||
private readonly uniforms: GPUBuffer;
|
||||
private readonly uniformValues = new Float32Array(EraserAgentPipeline.UNIFORM_COUNT);
|
||||
private readonly uniformUintValues = new Uint32Array(this.uniformValues.buffer);
|
||||
private readonly uniformCache = createCachedFloat32BufferWrite(
|
||||
EraserAgentPipeline.UNIFORM_COUNT
|
||||
);
|
||||
|
|
@ -93,7 +94,7 @@ export class EraserAgentPipeline {
|
|||
this.activeSegmentCount = this.pendingSegmentCount;
|
||||
this.pendingSegmentCount = 0;
|
||||
|
||||
this.uniformValues[0] = agentCount;
|
||||
this.uniformUintValues[0] = Math.max(0, Math.floor(agentCount));
|
||||
this.uniformValues[1] = eraserMaskAlphaThreshold;
|
||||
this.uniformValues[2] = 0;
|
||||
this.uniformValues[3] = 0;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
struct Settings {
|
||||
agentCount: f32,
|
||||
agentCount: u32,
|
||||
eraserMaskAlphaThreshold: f32,
|
||||
padding1: f32,
|
||||
padding2: f32,
|
||||
|
|
@ -15,7 +15,7 @@ fn main(
|
|||
) {
|
||||
let id = get_id(global_id, num_workgroups);
|
||||
|
||||
if id >= u32(settings.agentCount) {
|
||||
if id >= settings.agentCount {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -32,7 +32,7 @@ fn main(
|
|||
);
|
||||
let maskSample = textureLoad(eraserMask, maskPosition, 0);
|
||||
|
||||
if maskSample.a < settings.eraserMaskAlphaThreshold {
|
||||
if maskSample.r < settings.eraserMaskAlphaThreshold {
|
||||
agents[id].colorIndex = -1.0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,7 +64,12 @@ export class EraserTexturePipeline {
|
|||
});
|
||||
|
||||
const shaderModule = smartCompile(device, CommonState.shaderCode, shader);
|
||||
this.combinedPipeline = this.createPipeline(shaderModule, 'fragmentCombined', 4);
|
||||
this.combinedPipeline = this.createPipeline(shaderModule, 'fragmentCombined', [
|
||||
'r8unorm',
|
||||
'rgba16float',
|
||||
'rgba16float',
|
||||
'rgba16float',
|
||||
]);
|
||||
|
||||
this.uniforms = this.device.createBuffer({
|
||||
size: EraserTexturePipeline.UNIFORM_COUNT * Float32Array.BYTES_PER_ELEMENT,
|
||||
|
|
@ -119,7 +124,7 @@ export class EraserTexturePipeline {
|
|||
this.uniformValues[3] = eraserClearGreen;
|
||||
this.uniformValues[4] = eraserClearBlue;
|
||||
this.uniformValues[5] = eraserClearAlpha;
|
||||
this.uniformValues[6] = 0;
|
||||
this.uniformValues[6] = eraserRadius;
|
||||
this.uniformValues[7] = 0;
|
||||
writeFloat32BufferIfChanged(
|
||||
this.device,
|
||||
|
|
@ -225,7 +230,7 @@ export class EraserTexturePipeline {
|
|||
private createPipeline(
|
||||
shaderModule: GPUShaderModule,
|
||||
fragmentEntryPoint: string,
|
||||
colorTargetCount: number
|
||||
targetFormats: Array<GPUTextureFormat>
|
||||
): GPURenderPipeline {
|
||||
return this.device.createRenderPipeline({
|
||||
layout: this.device.createPipelineLayout({
|
||||
|
|
@ -258,9 +263,7 @@ export class EraserTexturePipeline {
|
|||
fragment: {
|
||||
module: shaderModule,
|
||||
entryPoint: fragmentEntryPoint,
|
||||
targets: Array.from({ length: colorTargetCount }, () => ({
|
||||
format: 'rgba16float' as const,
|
||||
})),
|
||||
targets: targetFormats.map((format) => ({ format })),
|
||||
},
|
||||
primitive: {
|
||||
topology: 'triangle-list',
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ struct Settings {
|
|||
clearGreen: f32,
|
||||
clearBlue: f32,
|
||||
clearAlpha: f32,
|
||||
padding0: f32,
|
||||
eraserRadius: f32,
|
||||
padding1: f32,
|
||||
};
|
||||
|
||||
|
|
@ -15,7 +15,8 @@ struct VertexOutput {
|
|||
@builtin(position) position: vec4<f32>,
|
||||
@location(0) screenPosition: vec2<f32>,
|
||||
@location(1) @interpolate(flat) start: vec2<f32>,
|
||||
@location(2) @interpolate(flat) end: vec2<f32>
|
||||
@location(2) @interpolate(flat) direction: vec2<f32>,
|
||||
@location(3) @interpolate(flat) inverseLengthSquared: f32,
|
||||
}
|
||||
|
||||
struct EraserTextureTargets {
|
||||
|
|
@ -37,19 +38,26 @@ fn vertex(
|
|||
@location(0) start: vec2<f32>,
|
||||
@location(1) end: vec2<f32>
|
||||
) -> VertexOutput {
|
||||
let screenPosition = segment_vertex_position(vertexIndex, start, end, sqrt(settings.eraserRadiusSquared));
|
||||
let direction = end - start;
|
||||
let denominator = dot(direction, direction);
|
||||
var inverseLengthSquared = 0.0;
|
||||
if denominator > settings.lineDistanceEpsilon {
|
||||
inverseLengthSquared = 1.0 / denominator;
|
||||
}
|
||||
let screenPosition = segment_vertex_position(vertexIndex, start, end, settings.eraserRadius);
|
||||
let uv = screenPosition / state.size;
|
||||
let position = vec2(uv.x * 2.0 - 1.0, 1.0 - uv.y * 2.0);
|
||||
return VertexOutput(vec4(position, 0.0, 1.0), screenPosition, start, end);
|
||||
return VertexOutput(vec4(position, 0.0, 1.0), screenPosition, start, direction, inverseLengthSquared);
|
||||
}
|
||||
|
||||
@fragment
|
||||
fn fragment(
|
||||
@location(0) screenPosition: vec2<f32>,
|
||||
@location(1) @interpolate(flat) start: vec2<f32>,
|
||||
@location(2) @interpolate(flat) end: vec2<f32>
|
||||
@location(2) @interpolate(flat) direction: vec2<f32>,
|
||||
@location(3) @interpolate(flat) inverseLengthSquared: f32
|
||||
) -> @location(0) vec4<f32> {
|
||||
if shouldDiscardEraserFragment(screenPosition, start, end) {
|
||||
if shouldDiscardEraserFragment(screenPosition, start, direction, inverseLengthSquared) {
|
||||
discard;
|
||||
}
|
||||
|
||||
|
|
@ -60,9 +68,10 @@ fn fragment(
|
|||
fn fragmentMrt(
|
||||
@location(0) screenPosition: vec2<f32>,
|
||||
@location(1) @interpolate(flat) start: vec2<f32>,
|
||||
@location(2) @interpolate(flat) end: vec2<f32>
|
||||
@location(2) @interpolate(flat) direction: vec2<f32>,
|
||||
@location(3) @interpolate(flat) inverseLengthSquared: f32
|
||||
) -> EraserTextureTargets {
|
||||
if shouldDiscardEraserFragment(screenPosition, start, end) {
|
||||
if shouldDiscardEraserFragment(screenPosition, start, direction, inverseLengthSquared) {
|
||||
discard;
|
||||
}
|
||||
|
||||
|
|
@ -74,14 +83,19 @@ fn fragmentMrt(
|
|||
fn fragmentCombined(
|
||||
@location(0) screenPosition: vec2<f32>,
|
||||
@location(1) @interpolate(flat) start: vec2<f32>,
|
||||
@location(2) @interpolate(flat) end: vec2<f32>
|
||||
@location(2) @interpolate(flat) direction: vec2<f32>,
|
||||
@location(3) @interpolate(flat) inverseLengthSquared: f32
|
||||
) -> EraserCombinedTargets {
|
||||
if shouldDiscardEraserFragment(screenPosition, start, end) {
|
||||
if shouldDiscardEraserFragment(screenPosition, start, direction, inverseLengthSquared) {
|
||||
discard;
|
||||
}
|
||||
|
||||
let cleared = getEraserClearValue();
|
||||
return EraserCombinedTargets(cleared, cleared, cleared, cleared);
|
||||
return EraserCombinedTargets(getEraserMaskValue(), cleared, cleared, cleared);
|
||||
}
|
||||
|
||||
fn getEraserMaskValue() -> vec4<f32> {
|
||||
return vec4<f32>(settings.clearAlpha, 0.0, 0.0, 1.0);
|
||||
}
|
||||
|
||||
fn getEraserClearValue() -> vec4<f32> {
|
||||
|
|
@ -96,21 +110,25 @@ fn getEraserClearValue() -> vec4<f32> {
|
|||
fn shouldDiscardEraserFragment(
|
||||
screenPosition: vec2<f32>,
|
||||
start: vec2<f32>,
|
||||
end: vec2<f32>
|
||||
direction: vec2<f32>,
|
||||
inverseLengthSquared: f32
|
||||
) -> bool {
|
||||
return distanceSquaredFromLine(screenPosition, start, end) > settings.eraserRadiusSquared;
|
||||
return distanceSquaredFromLine(screenPosition, start, direction, inverseLengthSquared) > settings.eraserRadiusSquared;
|
||||
}
|
||||
|
||||
fn distanceSquaredFromLine(position: vec2<f32>, start: vec2<f32>, end: vec2<f32>) -> f32 {
|
||||
fn distanceSquaredFromLine(
|
||||
position: vec2<f32>,
|
||||
start: vec2<f32>,
|
||||
direction: vec2<f32>,
|
||||
inverseLengthSquared: f32
|
||||
) -> f32 {
|
||||
let pa = position - start;
|
||||
let direction = end - start;
|
||||
let denominator = dot(direction, direction);
|
||||
|
||||
if denominator <= settings.lineDistanceEpsilon {
|
||||
if inverseLengthSquared <= 0.0 {
|
||||
return dot(pa, pa);
|
||||
}
|
||||
|
||||
let q = clamp(dot(pa, direction) / denominator, 0.0, 1.0);
|
||||
let q = clamp(dot(pa, direction) * inverseLengthSquared, 0.0, 1.0);
|
||||
let nearestOffset = pa - direction * q;
|
||||
return dot(nearestOffset, nearestOffset);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue