Skip to content

Instantly share code, notes, and snippets.

@filippovitale
Last active March 17, 2017 14:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save filippovitale/ee79a0986e6b2129ba9fc0f58d22375a to your computer and use it in GitHub Desktop.
Save filippovitale/ee79a0986e6b2129ba9fc0f58d22375a to your computer and use it in GitHub Desktop.
<!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