Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

render clifford attractor #20

Merged
merged 12 commits into from
May 20, 2024
36 changes: 36 additions & 0 deletions calcit.cirru

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion compact.cirru
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@
def skip-rendering? $ = "\"true" (get-env "\"skip" "\"false")
|tabs $ %{} :CodeEntry (:doc |)
:code $ quote
def tabs $ [] (:: :fireworks |Fireworks :dark) (:: :lorenz |Lorenz :dark) (:: :aizawa |Aizawa :dark) (:: :fourwing "|Four Wing" :dark) (:: :fractal |Fractal :dark) (:: :collision |Collision :dark) (:: :bounce |Bounce :dark) (:: :feday |FEDAY :dark) (:: :bifurcation "\"Bifurcation" :dark) (:: :ball-spin "\"Ball Spin" :dark) (:: :lifegame "\"Lifegame" :dark) (:: :lifegame-trail "\"Lifegame Trail" :dark) (:: :bounce-trail "|Bounce Trail" :dark) (:: :orbit-spark "|Orbit Spark" :dark) (:: :chen |Chen :dark) (:: :sprott |Sprott :dark) (:: :lorenz83 |Lorenz83 :dark) (:: :orbits |Orbits :dark) (:: :lamps |Lamps :dark) (:: :debug-grid "|Debug Grid" :dark) (:: :den-tsucs "\"Den Tsucs" :dark) (:: :bouali "\"Bouali" :dark) (:: :orbits2 "\"Orbits 2" :dark)
def tabs $ [] (:: :fireworks |Fireworks :dark) (:: :lorenz |Lorenz :dark) (:: :aizawa |Aizawa :dark) (:: :fourwing "|Four Wing" :dark) (:: :fractal |Fractal :dark) (:: :collision |Collision :dark) (:: :bounce |Bounce :dark) (:: :feday |FEDAY :dark) (:: :bifurcation "\"Bifurcation" :dark) (:: :ball-spin "\"Ball Spin" :dark) (:: :lifegame "\"Lifegame" :dark) (:: :lifegame-trail "\"Lifegame Trail" :dark) (:: :bounce-trail "|Bounce Trail" :dark) (:: :orbit-spark "|Orbit Spark" :dark) (:: :chen |Chen :dark) (:: :sprott |Sprott :dark) (:: :lorenz83 |Lorenz83 :dark) (:: :orbits |Orbits :dark) (:: :lamps |Lamps :dark) (:: :debug-grid "|Debug Grid" :dark) (:: :den-tsucs "\"Den Tsucs" :dark) (:: :bouali "\"Bouali" :dark) (:: :orbits2 "\"Orbits 2" :dark) (:: :halvorsen "\"Halvorsen" :dark) (:: :clifford "\"Clifford" :dark)
|threshold $ %{} :CodeEntry (:doc |)
:code $ quote
def threshold $ js/parseFloat
Expand Down Expand Up @@ -146,6 +146,8 @@
:debug-grid $ debug-grid/loadRenderer canvas
:den-tsucs $ den-tsucs/loadRenderer canvas
:bouali $ bouali/loadRenderer canvas
:halvorsen $ halvorsen/loadRenderer canvas
:clifford $ clifford/loadRenderer canvas
|reload! $ %{} :CodeEntry (:doc |)
:code $ quote
defn reload! () (hint-fn async)
Expand Down Expand Up @@ -199,6 +201,7 @@
"\"../src/apps/attractor-sprott" :as sprott
"\"../src/apps/attractor-lorenz83" :as lorenz-83
"\"../src/apps/attractor-bouali" :as bouali
"\"../src/apps/attractor-halvorsen" :as halvorsen
"\"../src/apps/fractal" :as fractal
"\"../src/apps/collision" :as collision
"\"../src/apps/bounce" :as bounce
Expand All @@ -214,6 +217,7 @@
"\"../src/apps/lamps" :as lamps
"\"../src/apps/debug-grid" :as debug-grid
"\"../src/apps/attractor-den-tsucs" :as den-tsucs
"\"../src/apps/clifford" :as clifford
"\"../src/index" :refer $ setupInitials
"\"../src/config" :as js-config
"\"../src/index" :refer $ listenShaderError
Expand Down
81 changes: 81 additions & 0 deletions src/apps/clifford.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { createRenderer } from "../index.mjs";
import computeOrbits from "./clifford.wgsl?raw";
import { fiboGridN } from "../math.mjs";

export let loadRenderer = async (canvas: HTMLCanvasElement) => {
let seedSize = 4194240;
// 4194304

let renderFrame = await createRenderer(
canvas,
{
seedSize,
seedData: makeSeed(seedSize, 0),
params: [
0.004, // deltaT
0.6, // height
0.2, // width
0.8, // opacity
],
// computeShader: updateSpritesWGSL,
// computeShader: computeGravityWgsl,
computeShader: computeOrbits,
},
{
vertexCount: 1,
vertexData: [0, 1, 2, 3],
indexData: [0, 1, 2, 1, 2, 3],
vertexBufferLayout: vertexBufferLayout,
// topology: "line-list",
bgColor: [0.1, 0.0, 0.2, 1.0],
}
);

return renderFrame;
};

function makeSeed(numParticles: number, _s: number): Float32Array {
const unit = 8;
const buf = new Float32Array(numParticles * unit);
// let scale = 200 * (Math.random() * 0.5 + 0.5);
let scale_base = 2;
// let p = [-0.4, 0.6] as [number, number];
// p = [Math.random(), Math.random()];
for (let i = 0; i < numParticles; ++i) {
let p = fiboGridN(i, numParticles).slice(0, 2) as [number, number];

let b = unit * i;
// buf[b + 0] = p[0] * scale;
// buf[b + 1] = p[1] * scale;
buf[b + 0] = p[0] * scale_base;
buf[b + 1] = p[1] * scale_base;
buf[b + 2] = Math.random();
buf[b + 3] = 0; // times
buf[b + 4] = p[0] * scale_base;
buf[b + 5] = p[1] * scale_base;
buf[b + 6] = Math.random();
buf[b + 7] = 0; // times
}

return buf;
}

let vertexBufferLayout: GPUVertexBufferLayout[] = [
{
// instanced particles buffer
arrayStride: 8 * 4,
stepMode: "instance",
attributes: [
{ shaderLocation: 0, offset: 0, format: "float32x3" },
{ shaderLocation: 1, offset: 3 * 4, format: "float32" },
{ shaderLocation: 2, offset: 4 * 4, format: "float32x3" },
{ shaderLocation: 3, offset: 7 * 4, format: "float32" },
],
},
{
// vertex buffer
arrayStride: 1 * 4,
stepMode: "vertex",
attributes: [{ shaderLocation: 4, offset: 0, format: "uint32" }],
},
];
163 changes: 163 additions & 0 deletions src/apps/clifford.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@

#import protea::perspective
#import protea::colors

struct Particle {
pos: vec3<f32>,
times: f32,
pos0: vec3<f32>,
times2: f32,
// p1: f32,
// p2: f32,
// p3: f32,
// p4: f32,
}

struct Params {
delta_t: f32,
height: f32,
width: f32,
opacity: f32,
}

struct Particles {
particles: array<Particle>,
}

@group(0) @binding(1) var<uniform> params: Params;
@group(1) @binding(0) var<storage, read> pass_in: Particles;
@group(1) @binding(1) var<storage, read_write> pass_out: Particles;

fn rand(n: f32) -> f32 { return fract(sin(n) * 43758.5453123); }

fn pick_param(n: u32) -> vec4f {
switch n {
case 0u: {
return vec4f(-1.1, -1.1, 1.1, 1.1);
}
case 1u: {
return vec4f(-1.4, 1.6, 1.0, 0.7);
}
case 2u: {
return vec4f(1.6, -0.6, -1.2, 1.6);
}
case 3u: {
return vec4f(1.7, 1.7, 0.6, 1.2);
}
case 4u: {
return vec4f(1.5, -1.8, 1.6, 0.9);
}
case 5u: {
return vec4f(-1.7, 1.3, -.1, -1.2);
}
case 6u: {
return vec4f(-1.7, 1.8, -1.9, -0.4);
}
case 7u: {
return vec4f(-2.0, 2., 1., 1.);;
}
case 8u:{
return vec4f(2., 2., 2., 2.);
}
default: {
return vec4f(-1.8, -2., -0.5, -0.9);
}
}
}

fn iterate(p: vec3<f32>, n: u32) -> vec3<f32> {
let x = p[0];
let y = p[1];
let z = p[2];

var vv = pick_param(n);
let a = vv[0];
let b = vv[1];
let c = vv[2];
let d = vv[3];

let next_x = sin(a * y) + c * cos(a * x);
let next_y = sin(b * x) + d * cos(b * y);
return vec3(next_y, next_x, z);
}

// https://github.com/austinEng/Project6-Vulkan-Flocking/blob/master/data/shaders/computeparticles/particle.comp
@compute @workgroup_size(64)
fn main(@builtin(global_invocation_id) GlobalInvocationID: vec3<u32>) {
var index = GlobalInvocationID.x;
let item = pass_in.particles[index];

let duration = 80.;
let try_idx = u32(item.times2 / duration) % 8u;

let next = iterate(item.pos, try_idx);
// let next = iterate(item.pos, 0u);
if item.times < duration {
pass_out.particles[index].pos.x = next.x;
pass_out.particles[index].pos.y = next.y;
pass_out.particles[index].pos.z = item.pos.z;
pass_out.particles[index].times = item.times + 1.;
pass_out.particles[index].times2 = item.times2 + 1.;
} else {
pass_out.particles[index].pos.x = item.pos0.x;
pass_out.particles[index].pos.y = item.pos0.y;
pass_out.particles[index].times = 0.;
pass_out.particles[index].times2 = item.times2 + 1.;
// pass_out.particles[index].pos = item.pos;
}
}

struct VertexOutput {
@builtin(position) position: vec4<f32>,
@location(4) color: vec4<f32>,
}

@vertex
fn vert_main(
@location(0) position0: vec3<f32>,
@location(1) point_idx: f32,
@location(2) velocity: vec3<f32>,
@location(3) times: f32,
@location(4) idx: u32,
) -> VertexOutput {
let position = position0 * 100.;
var pos: vec3<f32>;
let rightward: vec3<f32> = uniforms.rightward;
let upward: vec3<f32> = uniforms.upward;
let right = normalize(rightward);
let up = normalize(upward);

// let front = params.length;
var width = params.width * 0.4;

if idx == 0u {
pos = position + right * width;
// pos += vec3(1.,1.,1.) * 100.0;
} else if idx == 1u {
pos = position;
} else if idx == 2u {
pos = position + right * width + up * width;
} else if idx == 3u {
pos = position + up * width;
} else {
pos = position;
}
pos.z = 0.0;

var output: VertexOutput;
let p0 = vec4(pos * 10.0, 1.0);

let p: vec3<f32> = transform_perspective(p0.xyz).point_position;
let scale: f32 = 0.001;

output.position = vec4(p[0] * scale, p[1] * scale, p[2] * scale, 1.0);
let c3: vec3<f32> = hsl(fract(point_idx / 4000000.), 0.8, max(0.1, 0.9 - 0.2));
output.color = vec4(c3, params.opacity);
return output;
}

@fragment
fn frag_main(@location(4) color: vec4<f32>) -> @location(0) vec4<f32> {
return color;
// return vec4<f32>(1., 0., 0., 1.0);
}
2 changes: 2 additions & 0 deletions src/demo-entry.mts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import {} from "./apps/debug-grid.mjs";
import {} from "./apps/attractor-den-tsucs.mjs";
import {} from "./apps/attractor-bouali.mjs";
import {} from "./apps/orbits-2.mjs";
import {} from "./apps/attractor-halvorsen.mjs";
import * as cliffordd from "./apps/clifford.mjs";
tiye marked this conversation as resolved.
Show resolved Hide resolved

let instanceRenderer: (t: number, skipComputing: boolean) => void;
let canvas = document.querySelector("#canvas-container") as HTMLCanvasElement;
Expand Down
Loading