Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Function#fork parallel shading
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
<body>
<script>
Function.prototype.fork = function (cb, thisArg) {
var args = [].slice.call(arguments, 2)
var fn = this
setTimeout(function () {
try {
cb(null, fn.apply(thisArg, args))
} catch (e) {
cb(e)
}
}, 0)
}
</script>
<canvas id="c"></canvas>
<script src="shade.js">
</script>
</body>
</html>
/*jshint asi:true, esnext:true */
void function () {
const SHADER_COUNT = 4
const WIDTH = 400
const HEIGHT = 400
function shader (d) {
var i, n, x, y, a
var xf = 2 / d.w
var yf = 2 / d.w / d.h
var img = d.data
var l = img.length
var f = d.f
for (i=0, n=d.s/4; i<l; i+=4, n++) {
x = (n % d.w) * xf - 1.0
y = n * yf - 1.0
a = Math.abs(Math.sin(Math.atan2(x, y) + f * 0.02))
img[i+0] = 255 * Math.abs(x) * a
img[i+1] = 255 * Math.abs(y) * (1.0 - a)
img[i+2] = 255 * Math.sqrt(Math.abs(x * y))
img[i+3] = 255
}
f += 1
return d.id
}
function copies (l, cb) {
var i, r = Array(l)
for (i=0; i<l; i++) {
r[i] = cb(i)
}
return r
}
var rAF =
window.requestAnimationFrame ||
window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.msRequestAnimationFrame ||
function (cb) {
return window.setTimeout(cb, 1000 / 60)
}
function onComplete (err, id) {
if (err) throw err
readyStates[id] = true
if (readyStates.filter(function (s) {
return !!s
}).length === readyStates.length) {
rAF(draw)
}
}
var c = document.getElementById('c')
var w = c.width = WIDTH
var h = c.height = HEIGHT
var f = 0
var ctx = c.getContext('2d')
var iD = ctx.getImageData(0, 0, w, h)
var rT, img
var readyStates = copies(SHADER_COUNT, function () {
return false
})
function draw () {
var i, n, m
iD.data.set(img)
ctx.putImageData(iD, 0, 0)
parallelize()
}
function parallelize () {
var i, s
var l = ~~(iD.data.length / SHADER_COUNT / 4) * 4
if (!img || img.length !== iD.data.length) {
img = new Uint8Array(iD.data.length)
}
for (i=0, s=0; i < SHADER_COUNT-1; i++, s+=l) {
readyStates[i] = false
shader.fork(onComplete, null, {
id: i,
w: w,
h: h,
s: s,
f: f,
data: img.subarray(s, s + l)
})
}
readyStates[i] = false
shader.fork(onComplete, null, {
id: i,
w: w,
h: h,
s: s,
f: f,
data: img.subarray(s)
})
rT = +new Date()
f += 1
}
/* start the weird async loop */
parallelize()
}()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment