Last active
March 17, 2017 14:36
-
-
Save filippovitale/ee79a0986e6b2129ba9fc0f58d22375a to your computer and use it in GitHub Desktop.
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> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
</head> | |
<body onload=setInterval(aaa,64)> | |
<canvas id="c"></canvas> | |
<script id="jsbin-source-javascript" type="text/javascript">/* | |
http://www.p01.org/tea_storm/ | |
Casts 64x64 rays with up to 40 checks along the rays which amounts to a maximum | |
of 64x64x40 = 165,000 tests. | |
No fixed step raymarching but a distance function that gives an estimate of how | |
far is the surface of the object at each point in 3D space and the rays march on | |
until they get close enough. | |
That part is trivial: A canvas, a body element with onload event setting a timer | |
that clears the canvas, adjust the time variable, go through each pixel and | |
render them. | |
*/ | |
var u = 4; | |
var t = 32; | |
var s = 64; | |
function draw(ctx, x, y, i) { | |
ctx.globalAlpha=i/4; | |
ctx.fillRect(x * u, y * u, i, i); | |
} | |
function compute_intensity(x, y, s, t, ppp) { | |
var d = 4; // the distance, how far we marched along the current camera ray | |
var e = 1; // distance to the object is estimated in `e`. This safe considering the origin of the camera. | |
// At each step, the new position along the camera ray is computed in 3D space in X, Y and Z, | |
// the distance to the object is estimated in d and added to D, and N decreased by 0.1. | |
// The condition `.1 < e * intensity`: | |
// - Ensure that we stop when `intensity` reaches 0 or we have reached the object. | |
// - The multiplication `e * intensity` introduces an approximation of the focal distance | |
for (var intensity = 4; .1 < e * intensity; intensity -= .1) { | |
// The origin of the camera lies in {0, 0, -9} and looks toward {0, 0, 0} | |
var X = d * (x / s) - d / 2; | |
var Y = d * y / s - d / 2; | |
var Z = d / 2 - 9; | |
// Sphere | |
// e = (X*X+Y*Y+Z*Z)/15-1; | |
// e = (X*X+Y*Y+Z*Z)/9-1; | |
// Sphere morphing into a cylinder | |
// e = (X*X+Y*Y*Math.cos(t/6)+Z*Z)/9-1; | |
// Bumpy sphere | |
// e = (X*X+Y*Y+Z*Z)/9-1+Math.cos(X+t)*Math.cos(Y-t); | |
// Bumpy sphere-cylinder | |
// e = (X*X+Y*Y*Math.cos(t/6)+Z*Z)/9-1+Math.cos(X+t)*Math.cos(Y-t); | |
// Bumpy twirling morphing sphere-cylinder \(';;')/ | |
// e = (X * X + Y * Y * Math.cos(t / 6 + Math.cos(d - X - Y)) + Z * Z) / 9 - 1 + Math.cos(X + t) * Math.cos(Y - t); | |
e = (X * X + Y * Y * Math.cos(t / 6 + Math.cos(d - X - Y)) + Z * Z) / 15 - 1 + Math.cos(X + t) * Math.cos(Y - t); | |
// the further we are from the origin of the camera, the bigger the margin of | |
// error we can allow without any visual artifact. Of course this is not | |
// entirely correct since N does not represent the distance travelled but the | |
// number of iterations, but this is good enough. | |
d += e; | |
} | |
// intensity == number of iterations ~= distance travelled (good enough) | |
return intensity; | |
} | |
function aaa() { | |
// adjust the time variable | |
t -= .1; | |
// clear the canvas | |
var c = document.getElementById("c"); | |
var ctx = c.getContext('2d'); | |
c.height = s * u; | |
c.width = s * u; | |
for (var x = s; x--;) { | |
for (var y = s; y--;) { | |
var i = compute_intensity(x, y, s, t, false); | |
draw(ctx, x, y, i); | |
} | |
} | |
} | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment