fleeting-garden/src/pipelines/render/render.wgsl
2026-05-16 16:15:54 +01:00

67 lines
2.3 KiB
WebGPU Shading Language

struct Settings {
colorA: vec3<f32>,
backgroundColorPadding0: f32,
colorB: vec3<f32>,
backgroundColorPadding1: f32,
colorC: vec3<f32>,
backgroundColorPadding2: f32,
backgroundColor: vec3<f32>,
clarity: f32,
cameraCenter: vec2<f32>,
cameraZoom: f32,
padding0: f32,
};
@group(1) @binding(0) var<uniform> settings: Settings;
@group(1) @binding(1) var Sampler: sampler;
@group(1) @binding(2) var trailMap: texture_2d<f32>;
@group(1) @binding(3) var sourceMap: texture_2d<f32>;
@fragment
fn fragment(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
let cameraUv = settings.cameraCenter / state.size;
let viewUv = (uv - vec2(0.5)) / settings.cameraZoom + cameraUv;
let traces = textureSample(trailMap, Sampler, viewUv);
let sources = textureSample(sourceMap, Sampler, viewUv);
let traceStrengths = vec3(
clarity(traces.r),
clarity(traces.g),
clarity(traces.b)
);
let sourceStrengths = vec3(
clarity(sources.r),
clarity(sources.g),
clarity(sources.b)
);
let strengths = max(traceStrengths, sourceStrengths);
let traceColor =
strengths.r * settings.colorA
+ strengths.g * settings.colorB
+ strengths.b * settings.colorC;
let normalizedTraceColor = traceColor / max(1.0, strengths.r + strengths.g + strengths.b);
let brushColor =
sourceStrengths.r * settings.colorA
+ sourceStrengths.g * settings.colorB
+ sourceStrengths.b * settings.colorC;
let brushStrength = clamp(max(max(sourceStrengths.r, sourceStrengths.g), sourceStrengths.b), 0, 1);
let color = max(normalizedTraceColor, brushColor * (1.2 + brushStrength * 1.6));
let strength = clamp(max(max(max(strengths.r, strengths.g), strengths.b), brushStrength), 0, 1);
let background = getTexturedBackground(uv);
return vec4(mix(background, clamp(color, vec3(0), vec3(1)), strength), 1);
}
fn clarity(strength: f32) -> f32 {
return pow(clamp(strength, 0, 1), settings.clarity);
}
fn getTexturedBackground(uv: vec2<f32>) -> vec3<f32> {
let noiseSize = vec2<f32>(textureDimensions(noise, 0));
let pixel = floor(uv * state.size);
let noiseCoord = vec2<i32>(fract(pixel / noiseSize) * noiseSize);
let grain = textureLoad(noise, noiseCoord, 0).r - 0.5;
return clamp(settings.backgroundColor + vec3(grain * 0.018), vec3(0), vec3(1));
}