,
This commit is contained in:
parent
70423851ba
commit
1fe5015056
55 changed files with 2077 additions and 726 deletions
|
|
@ -7,24 +7,28 @@ struct Settings {
|
|||
|
||||
|
||||
@group(1) @binding(0) var<uniform> settings: Settings;
|
||||
@group(1) @binding(1) var Sampler: sampler;
|
||||
@group(1) @binding(2) var trailMap: texture_2d<f32>;
|
||||
|
||||
|
||||
@fragment
|
||||
fn fragment(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
|
||||
var current = textureSample(trailMap, Sampler, uv);
|
||||
fn fragment(@builtin(position) position: vec4<f32>) -> @location(0) vec4<f32> {
|
||||
let textureSize = vec2<i32>(textureDimensions(trailMap, 0));
|
||||
let pixel = clamp(vec2<i32>(position.xy), vec2<i32>(0), textureSize - vec2<i32>(1));
|
||||
var current = textureLoad(trailMap, pixel, 0);
|
||||
let random = random_from_pixel(pixel);
|
||||
let trailWeight = diffusion_weight(random, settings.inverseDiffusionRateTrails);
|
||||
let brushWeight = diffusion_weight(random, settings.inverseDiffusionRateBrush);
|
||||
|
||||
current += (
|
||||
propagate(uv, vec2(-1.0, -1.0), current)
|
||||
+ propagate(uv, vec2(-1.0, 1.0), current)
|
||||
+ propagate(uv, vec2(1.0, -1.0), current)
|
||||
+ propagate(uv, vec2(1.0, 1.0), current)
|
||||
propagate(pixel, textureSize, vec2<i32>(-1, -1), current, trailWeight, brushWeight)
|
||||
+ propagate(pixel, textureSize, vec2<i32>(-1, 1), current, trailWeight, brushWeight)
|
||||
+ propagate(pixel, textureSize, vec2<i32>(1, -1), current, trailWeight, brushWeight)
|
||||
+ propagate(pixel, textureSize, vec2<i32>(1, 1), current, trailWeight, brushWeight)
|
||||
|
||||
+ propagate(uv, vec2(-1.0, 0.0), current)
|
||||
+ propagate(uv, vec2(0.0, -1.0), current)
|
||||
+ propagate(uv, vec2(1.0, 0.0), current)
|
||||
+ propagate(uv, vec2(0.0, 1.0), current)
|
||||
+ propagate(pixel, textureSize, vec2<i32>(-1, 0), current, trailWeight, brushWeight)
|
||||
+ propagate(pixel, textureSize, vec2<i32>(0, -1), current, trailWeight, brushWeight)
|
||||
+ propagate(pixel, textureSize, vec2<i32>(1, 0), current, trailWeight, brushWeight)
|
||||
+ propagate(pixel, textureSize, vec2<i32>(0, 1), current, trailWeight, brushWeight)
|
||||
) / 8;
|
||||
|
||||
let decayed = clamp(vec4(
|
||||
|
|
@ -36,13 +40,64 @@ fn fragment(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
|
|||
}
|
||||
|
||||
|
||||
fn propagate(uv: vec2<f32>, offset: vec2<f32>, currentColor: vec4<f32>) -> vec4<f32> {
|
||||
let neighbour = textureSample(trailMap, Sampler, uv + offset / state.size);
|
||||
var random = textureSample(noise, noiseSampler, uv + offset / state.size * 0.5).r;
|
||||
fn propagate(
|
||||
pixel: vec2<i32>,
|
||||
textureSize: vec2<i32>,
|
||||
offset: vec2<i32>,
|
||||
currentColor: vec4<f32>,
|
||||
trailWeight: f32,
|
||||
brushWeight: f32
|
||||
) -> vec4<f32> {
|
||||
let neighbour = textureLoad(
|
||||
trailMap,
|
||||
clamp(pixel + offset, vec2<i32>(0), textureSize - vec2<i32>(1)),
|
||||
0
|
||||
);
|
||||
let difference = clamp(neighbour - currentColor, vec4(0), vec4(1));
|
||||
|
||||
return vec4(
|
||||
vec3(length(neighbour.rgb) * pow(random, settings.inverseDiffusionRateTrails)),
|
||||
length(neighbour.a) * pow(random, settings.inverseDiffusionRateBrush)
|
||||
vec3(length(neighbour.rgb) * trailWeight),
|
||||
neighbour.a * brushWeight
|
||||
) * difference;
|
||||
}
|
||||
|
||||
fn random_from_pixel(pixel: vec2<i32>) -> f32 {
|
||||
let p = vec2<u32>(pixel);
|
||||
var hash = p.x * 1664525u + p.y * 1013904223u + 374761393u;
|
||||
hash = (hash ^ (hash >> 16u)) * 2246822519u;
|
||||
hash = (hash ^ (hash >> 13u)) * 3266489917u;
|
||||
hash = hash ^ (hash >> 16u);
|
||||
return f32(hash) * 2.3283064365386963e-10;
|
||||
}
|
||||
|
||||
fn diffusion_weight(random: f32, inverseRate: f32) -> f32 {
|
||||
let r = clamp(random, 0.0, 1.0);
|
||||
let r2 = r * r;
|
||||
let r4 = r2 * r2;
|
||||
let r8 = r4 * r4;
|
||||
|
||||
if inverseRate < 1.0 {
|
||||
let rootApproximation = r / max(0.5 + r * 0.5, 0.0001);
|
||||
return mix(
|
||||
rootApproximation,
|
||||
r,
|
||||
clamp((inverseRate - 0.5) * 2.0, 0.0, 1.0)
|
||||
);
|
||||
}
|
||||
|
||||
if inverseRate < 2.0 {
|
||||
return mix(r, r2, inverseRate - 1.0);
|
||||
}
|
||||
|
||||
if inverseRate < 4.0 {
|
||||
return mix(r2, r4, (inverseRate - 2.0) * 0.5);
|
||||
}
|
||||
|
||||
if inverseRate < 8.0 {
|
||||
return mix(r4, r8, (inverseRate - 4.0) * 0.25);
|
||||
}
|
||||
|
||||
let r16 = r8 * r8;
|
||||
return mix(r8, r16, clamp((inverseRate - 8.0) * 0.125, 0.0, 1.0))
|
||||
* min(1.0, 16.0 / inverseRate);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue