-
-
Save Hades32/3c2dd67dcbb52e65d529922c5128589a to your computer and use it in GitHub Desktop.
add possibility to break (obvious) determinism
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head><title>Javascript RT</title></head> | |
<style>canvas {width: 1280px; height: 768px}</style> | |
<body> | |
<canvas id="framebuffer"></canvas> | |
<script type="text/javascript"> | |
/* Fizzlefade using a Feistel network. | |
* Copyright (C) 2017 Salvatore Sanfilippo <[email protected]> | |
* This softare is released under the terms of the BSD two-clause license. | |
* See http://fabiensanglard.net/fizzlefade/index.php for more info. */ | |
var ctx; | |
var pixels; | |
var screen_width = 3480; | |
var screen_height = 2160; | |
var frame = 0; | |
var bits = 2 * Math.ceil(Math.log2(screen_width * screen_height) / 2); | |
var lastFrame = Math.pow(2, bits) | |
var feistelNet = newFeistelNet(bits, Math.random()*Math.pow(2,bits)); | |
/* Here is a very ugly thing that calms my laptop's fan */ | |
var timerKiller = { | |
timer: null, | |
ended: false, | |
setTimer: function (newTimer) { | |
timer = newTimer; | |
if(ended) { | |
clearInterval(timer); | |
} | |
}, | |
end: function () { | |
if(timer != null) { | |
clearInterval(timer); | |
} | |
ended = true; | |
} | |
}; | |
/* Create a context where we can easily write pixels. */ | |
function init() { | |
fb = document.getElementById('framebuffer'); | |
fb.width = screen_width; | |
fb.height = screen_height; | |
ctx = fb.getContext('2d'); | |
pixels = ctx.createImageData(screen_width, screen_height); | |
timerKiller.setTimer(setInterval(draw, 1, timerKiller)); | |
}; | |
/* Write a pixel, just set alpha and RGB channels. */ | |
function setPixel(x,y) { | |
var offset = x*4+y*4*screen_width; | |
pixels.data[offset+3] = 255; | |
pixels.data[offset+0] = 255; | |
pixels.data[offset+1] = 0; | |
pixels.data[offset+2] = 0; | |
} | |
/* Transforms the n bit input into another seemingly pseudo random number | |
* in the same range. Every input n bit input will generate a different | |
* n bit output. This is called a Feistel network. */ | |
function newFeistelNet(bits, extraRandom) { | |
extraRandom &= 0xFFFFFFFF; | |
var mask = Math.pow(2, bits) - 1; | |
var halfBits = bits/2; | |
var halfMask = Math.pow(2, halfBits) - 1; | |
return function(input) { | |
var l = input & halfMask; | |
var r = input >> halfBits; | |
for (var i = 0; i < 5; i++) { | |
var nl = r; | |
var F = (((r * 19) + (r >> 1)) ^ r) & halfMask; | |
r = l ^ F; | |
l = nl; | |
} | |
return (((r << halfBits) | l) & mask) ^ extraRandom; | |
}; | |
} | |
/* Called once every millisecond (or as fast as your browser allows), sets many | |
* pixels. */ | |
function draw(killer) { | |
var j; | |
/* Set many pixels per iteration otherwise it's too slow. */ | |
for (j = 0; j < (lastFrame / 200); j++) { | |
if (frame >= lastFrame) { | |
killer.end(); | |
break; | |
} | |
var fn = feistelNet(frame, bits); | |
var x = fn % screen_width; | |
var y = Math.floor(fn / screen_width); | |
if (x < screen_width && y < screen_height) { | |
setPixel(x,y); | |
} | |
frame++; | |
} | |
ctx.putImageData(pixels, 0, 0); | |
} | |
init(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment