Drawing Newton's fractal using pure js, rust-wasm, SIMDs, threads and GPU

Overview

Newton's fractal

Runtime Newton's fractal renderer.

>>Click<< to open in your browser

Inspired by 3blue1brown's video about Newton's fractal.

Demo preview

Drawing techniques

1. Javascript fractal_calculation.ts and geometry.ts

2. Rust-WASM: scalar fractal_calculation.rs and geometry.rs

3. Rust-WASM: SIMD commands fractal_calculation.rs and simd_math.rs (includes comments)

4. GPU glslsources: webgl2_drawing.ts and gl_manager.ts
shaders: vertex.vert and fragment.frag

5. Multithreading for 1-3 techniquesdrawing_manager.ts and drawing_worker.ts

You might also like...

GPU supercharged attraction-graph visualizations built on top of Three.js

Force Directed Graph GPU supercharged attraction-graph visualizations for the web built on top of Three.js. Importable as an ES6 module. Simulation co

Dec 9, 2022

A WASM shell parser and formatter with bash support, based on mvdan/sh

sh-syntax A WASM shell parser and formatter with bash support, based on mvdan/sh TOC Usage Install API Changelog License Usage Install # yarn yarn add

Jan 1, 2023

Cross provider map drawing library, supporting Mapbox, Google Maps and Leaflet out the box

Terra Draw Frictionless map drawing across mapping providers. TerraDraw centralises map drawing logic and provides a host of out the box drawing modes

Dec 31, 2022

JustGage is a handy JavaScript plugin for generating and animating nice & clean dashboard gauges. It is based on Raphaël library for vector drawing.

JustGage is a handy JavaScript plugin for generating and animating nice & clean dashboard gauges. It is based on Raphaël library for vector drawing.

JustGage JustGage is a handy JavaScript plugin for generating and animating nice & clean dashboard gauges. It is based on Raphaël library for vector d

Jan 3, 2023

JavaScript library to make drawing animation on SVG

JavaScript library to make drawing animation on SVG

vivus.js Demo available on http://maxwellito.github.io/vivus Play with it on Vivus Instant Vivus is a lightweight JavaScript class (with no dependenci

Jan 3, 2023

Simple Jai to WASM Proof-of-Concept

Simple Jai to WASM Proof-of-Concept Jai does not officially support WebAssembly compilation target. BUT! It allows you to dump LLVM IR via the llvm_op

Dec 14, 2022

A web app demonstrating how the Fourier series can be used to approximate user-inputted line drawing

Fourier Series Animation An interactive React web app that demonstrates how an arbitrary user-inputted line drawing can be approximated using the Four

Dec 22, 2022

High-order Virtual Machine (HVM) wrapper on JavaScript, via WASM

HVM on JavaScript HVM is now available as a JavaScript library! Installing npm i --save hvm-js Examples Evaluating a term to normal form import hvm fr

Nov 24, 2022

A JavaScript library for drawing network graphs.

Gnet.js Gnet is a JavaScript library for network graph visualization, developed by Goutham. First I want to thank D3.js developers for creating such a

May 9, 2021
Comments
  • Optimize computation algorithm

    Optimize computation algorithm

    This isn't all JS-specific (in fact, most of it isn't), though I used JS for familiarity. I haven't tested or benchmarked this (part of why it's a draft PR), but I created the PR anyways just to help explain.

    The long 104-line comment explains most of it, but there's a few key insights into this:

    • Every object allocated in JS is allocated on the heap. (Even stacks are commonly heap-allocated.) In performance-critical code, it's common to avoid object allocation entirely. Temporaries that are immediately read from and dropped are typically optimized for and usually are only allocated in the really fast nursery, so the allocation cost here is relatively low (though still non-negligible in hot loops).
    • CPUs do better if you can do everything in a row, and memory loads outside L1 cache tend to be significantly costlier than the computation. This is why I flattened the roots: to ensure that the inner loop is dealing with exactly one contiguous array. (I'm using a typed array to match idioms, but normal arrays are more idiomatic.)
    • You should prefer a * sqrt(1 + (a/b)^2) for computing the two-dimensional Euclidean norm, as it's more numerically stable. (JS has a Math.hypot(...components) for this reason.) This happens to require an extra floating point division, but you can reclaim with a floating-point fma where available. (This applies across the board, though I see you're already using the WebGL distance function, so that's not an issue in the GPU code.)
    • You can do a little math and take advantage of both sides being positive to only do one comparison in the inner loop - this may yield a moderate performance boost as you wouldn't need to do the 2 absolute values + 2 floating-point comparisons, but only one single comparison with an already-calculated result. I explain the math in the big comment as well. This holds for all variants, and would also simplify your SIMD condition substantially.

    Also, separately, I have a couple larger nits:

    • In the TypeScript stuff, using type Root = [number, number] and root: Root[] would be more idiomatic of a type for your roots. (You can also label them as [x: number, y: number] for added clarity.) Likewise, type Color = [number, number, number, number] + colors: Color[] would be clearer and more idiomatic. This would also cause the array's length to get checked for, so you wouldn't be as likely to accidentally forget an entry or add one too many entries.
    • You're using 32-bit floating point arithmetic for WebAssembly, while JS uses 64-bit floating point arithmetic natively, so it's not really an apples-to-apples comparison. This should be made clear in the demo.
    • In your SIMD calculation, {i,u}8x16_swizzle(a) may yield slightly faster code for the lane shifting than *_shuffle(a, a) due to better instruction selection, though that will need benchmarked.
    • In your SIMD calculation, I would suggest loading chunks of 4 and doing let real = f32x4_shuffle::<0, 2, 4, 6>(a, b); let imag = f32x4_shuffle::<0, 2, 4, 6>(a, b); so you can do it in full batches of 4 using a similar algorithm to the scalar variant. This would require slightly more registers of course and it'd also complicate finding the matching lane (TL;DR: let lane_idx = i32x4_bitmask(f32x4_lt(square_norm, f32x4_splat(0.000002))).trailing_zeros(), lane found if lane_idx < 4), but you might derive a full 1.5x speedup from that if not more as you're doing even the expensive operations like sqrt fully parallel.
    opened by dead-claudia 8
Remix sandbox repo for Rust compiled to WASM and to native N-API modules

Rust <-> Remix Sandbox Now with both native Rust and WASM versions! If you want to combine the Web Fundamentals & Modern UX of Remix together with the

Ben Wishovich 26 Dec 30, 2022
A Remix stack setup to run on Deno with support for Rust WASM modules!

Remix + Deno + Rust -> Webassembly - The Air Metal Stack Welcome to the Air Metal Stack for Remix! ?? + ?? This stack is a good choice if you want to

Ben Wishovich 60 Jan 5, 2023
Parallel/concurrent async work, optionally using multiple threads or processes

parallel-park Parallel/concurrent async work, optionally using multiple processes Usage parallel-park exports two functions: runJobs and inChildProces

Lily Scott 10 Mar 1, 2022
A light microservice serving Atom 1.0 Feeds for MusicThread threads

MusicThread Web Feeds A light microservice to serve Atom 1.0 Feeds for MusicThread. People use web feeds for following updates to specific threads via

Brushed Type 4 Jun 15, 2022
Um bot de suporte feito usando threads para o Discord, 100% customizável, feito em JavaScript e inspirado no Rio Helper do servidor Elixir Lab e na Loritta Helper do serivdor de suporte da Loritta.

Ticket Bot Um bot de suporte feito usando threads para o Discord, 100% customizável, feito em JavaScript e inspirado no Rio Helper do servidor Elixir

ADG 6 Dec 21, 2022
The Easiest Way To Write Twitter Threads 🐦

Twotion | The Easiest Way To Write Twitter Threads Write Twitter threads and post them in one click without leaving Notion. Completely Free No Need To

Osada Vidath Chandrasekara 9 Nov 24, 2022
A flexible gateway for running ML inference jobs through cloud providers or your own GPU. Powered by Replicate and Cloudflare Workers.

Cogflare (Working title) Cogflare is a Cloudflare Workers application that aims to simplify running distributed ML inference jobs through a central AP

NightmareBot 14 Dec 12, 2022
GPU-accelerated Augmented Reality for the web.

MARTINS.js WebAR engine Create amazing Augmented Reality experiences with MARTINS.js, a GPU-accelerated Augmented Reality engine for the web. Get star

Alexandre Martins 19 Dec 16, 2022
🐜 GPU-accelerated ant colony simulation

Ants simulation A simple ant colony GPU-accelerated simulation made with Three.js. Live demo Rules Ants can emit two types of pheromones: to-home pher

null 10 Nov 28, 2022
GPU Drops' captcha solving extension without affiliate tracking code injection

Noptcha, without affiliate link injection Noptcha is a reCaptcha and hCaptcha solving extension created by GPU Drops. This fork was made because I hat

Sqaaakoi 201 Dec 26, 2022