3d Voxel Sphere

by Matt Timmermans

HTML

<script src="https://ajax.googleapis.com/ajax/libs/threejs/r83/three.min.js"></script>

JavaScript

var radiusInVoxels=10.5
var voxelsize=1/radiusInVoxels;
var shrink=0.9;
var material = new THREE.MeshLambertMaterial( { color: 0xd0d0d0, transparent: true, opacity: 0.85 } );
var group = new THREE.Group();

function drawSphere(R) {
	var maxR2 = Math.floor(R*R);
  var x,y,z;
  var zx = Math.floor(R);
	for (x=0; ;++x)
	{
  	//max z for this x value.
    while(x*x+zx*zx > maxR2 && zx>=x)
    	--zx;
    if (zx<x)
      break; //with this x, z can't be largest
    z=zx;
    for(y=0; ;++y)
    {
      while(x*x+y*y+z*z > maxR2 && z>=x && z>=y)
        --z;
      if (z<x||z<y)
        break; //with this x and y, z can't be largest
      fillAll(x,y,z); //... and up to 23 reflections of it
    }
  }
}

function fill1(x,y,z) {
	var box = new THREE.BoxGeometry( voxelsize*shrink, voxelsize*shrink, voxelsize*shrink );
	box = new THREE.Mesh( box, material );
	box.translateX(x*voxelsize);
  box.translateY(y*voxelsize);
  box.translateZ(z*voxelsize);
	group.add( box );
}
function fillSigns(x,y,z) {
	fill1(x,y,z);
  for (;;) {
    if ((z=-z) >= 0) {
      if ((y=-y) >= 0) {
        if ((x=-x) >= 0) {
          break;
        }
      }
    }
    fill1(x,y,z);
  }
}
function fillAll(x,y,z) {
	fillSigns(x,y,z);
  if (z>y) {
   	fillSigns(x,z,y);
  }
  if (z>x && z>y) {
    fillSigns(z,y,x);
  }
}

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, 	
	window.innerWidth/window.innerHeight, 0.1, 1000 );

var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

scene.add(new THREE.AmbientLight( 0xFFFFFF, .1 ));
var light = new THREE.DirectionalLight( 0xFFFFFF, .9 );
light.position.set( 5, 10, 10 );
scene.add( light );

drawSphere(radiusInVoxels);
scene.add( group );

camera.position.z = 2;
camera.position.x = 0;

var render = function (ms) {
  requestAnimationFrame( render );
  
  var angle1 = ms/10000;angle1-=Math.floor(angle1);
  var angle2 =...