More clean up

This commit is contained in:
Andras Schmelczer 2026-05-20 21:03:41 +01:00
commit f03da42b5e
43 changed files with 818 additions and 1076 deletions

View file

@ -14,6 +14,7 @@ export class RenderPipeline {
private readonly bindGroupLayout: GPUBindGroupLayout;
private readonly pipeline: GPURenderPipeline;
private readonly noSourcePipeline: GPURenderPipeline;
private readonly uniforms: GPUBuffer;
private readonly uniformValues = new Float32Array(RenderPipeline.UNIFORM_COUNT);
private readonly uniformCache = createCachedFloat32BufferWrite(
@ -36,6 +37,7 @@ export class RenderPipeline {
const format = navigator.gpu.getPreferredCanvasFormat();
this.pipeline = this.createPipeline(format, vertex, 'fragment');
this.noSourcePipeline = this.createPipeline(format, vertex, 'fragmentNoSource');
this.uniforms = this.device.createBuffer({
size: RenderPipeline.UNIFORM_COUNT * Float32Array.BYTES_PER_ELEMENT,
@ -112,7 +114,8 @@ export class RenderPipeline {
public execute(
commandEncoder: GPUCommandEncoder,
colorTexture: GPUTextureView,
sourceTexture: GPUTextureView
sourceTexture: GPUTextureView,
useSourceTexture = true
): GPUTexture {
const bindGroup = this.getBindGroup(colorTexture, sourceTexture);
const canvasTexture = this.context.getCurrentTexture();
@ -128,7 +131,7 @@ export class RenderPipeline {
],
};
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
passEncoder.setPipeline(this.pipeline);
passEncoder.setPipeline(useSourceTexture ? this.pipeline : this.noSourcePipeline);
this.commonState.execute(passEncoder);
passEncoder.setBindGroup(1, bindGroup);
passEncoder.draw(3, 1);

View file

@ -27,9 +27,18 @@ fn fragment(@builtin(position) position: vec4<f32>) -> @location(0) vec4<f32> {
return renderColor(traces, sources, pixel);
}
@fragment
fn fragmentNoSource(@builtin(position) position: vec4<f32>) -> @location(0) vec4<f32> {
let pixel = vec2<i32>(position.xy);
let traces = textureLoad(trailMap, pixel, 0);
return renderColor(traces, vec4<f32>(0.0), pixel);
}
fn renderColor(traces: vec4<f32>, sources: vec4<f32>, pixel: vec2<i32>) -> vec4<f32> {
let background = getTexturedBackground(pixel);
if max(max(max(traces.r, traces.g), traces.b), max(max(sources.r, sources.g), sources.b)) <= 0.0 {
let tracesMax = maxComponent(traces.rgb);
let sourcesMax = maxComponent(sources.rgb);
if max(tracesMax, sourcesMax) <= 0.0 {
return vec4(background, 1);
}
@ -38,13 +47,13 @@ fn renderColor(traces: vec4<f32>, sources: vec4<f32>, pixel: vec2<i32>) -> vec4<
clarity(traces.g),
clarity(traces.b)
);
if max(max(sources.r, sources.g), sources.b) <= 0.0 {
if sourcesMax <= 0.0 {
let traceColor =
traceStrengths.r * settings.colorA
+ traceStrengths.g * settings.colorB
+ traceStrengths.b * settings.colorC;
let normalizedTraceColor = normalizeColorIntensity(traceColor);
let traceStrength = max(max(traceStrengths.r, traceStrengths.g), traceStrengths.b);
let traceStrength = maxComponent(traceStrengths);
return vec4(mix(background, clamp(normalizedTraceColor, vec3(0), vec3(1)), traceStrength), 1);
}
@ -64,7 +73,7 @@ fn renderColor(traces: vec4<f32>, sources: vec4<f32>, pixel: vec2<i32>) -> vec4<
+ sourceStrengths.g * settings.colorB
+ sourceStrengths.b * settings.colorC;
let normalizedBrushColor = normalizeColorIntensity(brushColor);
let brushStrength = max(max(sourceStrengths.r, sourceStrengths.g), sourceStrengths.b);
let brushStrength = maxComponent(sourceStrengths);
let brushVisibility = clamp(
brushStrength * (
settings.brushColorBase +
@ -75,20 +84,27 @@ fn renderColor(traces: vec4<f32>, sources: vec4<f32>, pixel: vec2<i32>) -> vec4<
);
let color = max(normalizedTraceColor, normalizedBrushColor);
let strength = max(max(max(strengths.r, strengths.g), strengths.b), brushVisibility);
let strength = max(maxComponent(strengths), brushVisibility);
return vec4(mix(background, clamp(color, vec3(0), vec3(1)), strength), 1);
}
fn maxComponent(v: vec3<f32>) -> f32 {
return max(max(v.r, v.g), v.b);
}
fn clarity(strength: f32) -> f32 {
return pow(clamp(strength, 0, 1), settings.clarity);
}
fn normalizeColorIntensity(color: vec3<f32>) -> vec3<f32> {
let brightestChannel = max(max(color.r, color.g), color.b);
let brightestChannel = maxComponent(color);
return color / max(settings.traceNormalizationFloor, brightestChannel);
}
fn getTexturedBackground(pixel: vec2<i32>) -> vec3<f32> {
if settings.backgroundGrainStrength == 0.0 {
return clamp(settings.backgroundColor, vec3(0), vec3(1));
}
let noiseCoord = vec2<i32>(vec2<u32>(pixel) & vec2<u32>(NOISE_TEXTURE_MASK));
let grain = textureLoad(noise, noiseCoord, 0).r - 0.5;