Skip to content

Instantly share code, notes, and snippets.

@laod
Last active December 15, 2015 12:28
Show Gist options
  • Save laod/5260092 to your computer and use it in GitHub Desktop.
Save laod/5260092 to your computer and use it in GitHub Desktop.
Experiments with three.js. Horrible hacks.
<html>
<head>
<title>Experiment 6</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="coffee-script.js"></script>
<script src="underscore.js"></script>
<script src="three.js"></script>
<script>
/*
Thanks to Florian Boesch http://codeflow.org/entries/2010/dec/09/minecraft-like-rendering-experiments-in-opengl-4/
for the inspiration and significant chunks of code.
*/
var grad = [
[1.0,1.0,0.0],[-1.0,1.0,0.0],[1.0,-1.0,0.0],[-1.0,-1.0,0.0],
[1.0,0.0,1.0],[-1.0,0.0,1.0],[1.0,0.0,-1.0],[-1.0,0.0,-1.0],
[0.0,1.0,1.0],[0.0,-1.0,1.0],[0.0,1.0,-1.0],[0.0,-1.0,-1.0]
];
var perm = [151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180, 151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180];
var dot = function(x, y, z, g){
return x*g[0] + y*g[1] + z*g[2];
}
var noise = function(xin, yin, zin){
var F3 = 1.0/3.0,
s = (xin+yin+zin)*F3,
i = Math.floor(xin+s),
j = Math.floor(yin+s),
k = Math.floor(zin+s),
G3 = 1.0/6.0,
t = (i+j+k)*G3,
X0 = i-t,
Y0 = j-t,
Z0 = k-t,
x0 = xin-X0,
y0 = yin-Y0,
z0 = zin-Z0;
var i1,j1,k1,i2,j2,k2;
if(x0 >= y0){
if(y0 >= z0){
i1=1; j1=0; k1=0; i2=1; j2=1; k2=0;
}
else if(x0 >= z0){
i1=1; j1=0; k1=0; i2=1; j2=0; k2=1;
}
else{
i1=0; j1=0; k1=1; i2=1; j2=0; k2=1;
}
}
else{
if(y0 < z0){
i1=0; j1=0; k1=1; i2=0; j2=1; k2=1;
}
else if(x0 < z0){
i1=0; j1=1; k1=0; i2=0; j2=1; k2=1;
}
else{
i1=0; j1=1; k1=0; i2=1; j2=1; k2=0;
}
}
var x1 = x0 - i1 + G3,
y1 = y0 - j1 + G3,
z1 = z0 - k1 + G3,
x2 = x0 - i2 + 2.0*G3,
y2 = y0 - j2 + 2.0*G3,
z2 = z0 - k2 + 2.0*G3,
x3 = x0 - 1.0 + 3.0*G3,
y3 = y0 - 1.0 + 3.0*G3,
z3 = z0 - 1.0 + 3.0*G3,
ii = i & 255,
jj = j & 255,
kk = k & 255,
gi0 = perm[ii+perm[jj+perm[kk]]] % 12,
gi1 = perm[ii+i1+perm[jj+j1+perm[kk+k1]]] % 12,
gi2 = perm[ii+i2+perm[jj+j2+perm[kk+k2]]] % 12,
gi3 = perm[ii+1+perm[jj+1+perm[kk+1]]] % 12;
var t0 = 0.6 - x0*x0 - y0*y0 - z0*z0;
var n0, n1, n2, n3;
if(t0<0){
n0 = 0.0;
}
else{
t0 *= t0;
n0 = t0 * t0 * dot(x0, y0, z0, grad[gi0]);
}
var t1 = 0.6 - x1*x1 - y1*y1 - z1*z1;
if(t1<0){
n1 = 0.0;
}
else{
t1 *= t1;
n1 = t1 * t1 * dot(x1, y1, z1, grad[gi1]);
}
var t2 = 0.6 - x2*x2 - y2*y2 - z2*z2;
if(t2<0){
n2 = 0.0;
}
else{
t2 *= t2;
n2 = t2 * t2 * dot(x2, y2, z2, grad[gi2]);
}
var t3 = 0.6 - x3*x3 - y3*y3 - z3*z3;
if(t3<0){
n3 = 0.0;
}
else{
t3 *= t3;
n3 = t3 * t3 * dot(x3, y3, z3, grad[gi3]);
}
return 16.0*(n0 + n1 + n2 + n3)+1.0;
}
var simplex_noise = function(octaves, x, y, z){
var value = 0.0;
for(var i=0; i<octaves; i++){
value += noise(
x*Math.pow(i, 2),
y*Math.pow(i, 2),
z*Math.pow(i, 2)
);
}
return value;
}
</script>
<script type="text/glsl" id="shlightf">
varying vec3 vn;
uniform float ScaleFactor;
const float C1 = 0.429043;
const float C2 = 0.511664;
const float C3 = 0.743125;
const float C4 = 0.886227;
const float C5 = 0.247708;
struct SHC{
vec3 L00, L1m1, L10, L11, L2m2, L2m1, L20, L21, L22;
};
SHC beach = SHC(
vec3( 0.6841148, 0.6929004, 0.7069543),
vec3( 0.3173355, 0.3694407, 0.4406839),
vec3(-0.1747193, -0.1737154, -0.1657420),
vec3(-0.4496467, -0.4155184, -0.3416573),
vec3(-0.1690202, -0.1703022, -0.1525870),
vec3(-0.0837808, -0.0940454, -0.1027518),
vec3(-0.0319670, -0.0214051, -0.0147691),
vec3( 0.1641816, 0.1377558, 0.1010403),
vec3( 0.3697189, 0.3097930, 0.2029923)
);
void main()
{
float x = vn.x;
float y = vn.y;
float z = vn.z;
SHC l = beach;
const float C1 = 0.429043;
const float C2 = 0.511664;
const float C3 = 0.743125;
const float C4 = 0.886227;
const float C5 = 0.247708;
vec3 d = (
C1 * l.L22 * (x * x - y * y) +
C3 * l.L20 * z * z +
C4 * l.L00 -
C5 * l.L20 +
2.0 * C1 * l.L2m2 * x * y +
2.0 * C1 * l.L21 * x * z +
2.0 * C1 * l.L2m1 * y * z +
2.0 * C2 * l.L11 * x +
2.0 * C2 * l.L1m1 * y +
2.0 * C2 * l.L10 * z
);
gl_FragColor = vec4(d*0.5, 1.0);
}
</script>
<script type="text/glsl" id="shlightv">
varying vec3 vn;
void main()
{
vn = normal;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
</script>
<script type="text/coffeescript">
$ ->
renderer = new THREE.WebGLRenderer()
camera = new THREE.PerspectiveCamera 45, 400/300, 0.1, 10000
scene = new THREE.Scene()
renderer.setClearColor new THREE.Color(0, 1)
renderer.setSize 800, 600
$("body").append(renderer.domElement)
s = 32
nsh = s/-2
idx = (x,y,z,ss) ->
ss ||= s
x + y*ss + z*ss*ss
cube_loop = (fn) ->
r = []
for z in [0..s-1]
for y in [0..s-1]
for x in [0..s-1]
r.push fn(x,y,z,idx(x,y,z))
r
do ->
v = new THREE.Vector3(nsh,nsh,nsh)
THREE.Vector3.prototype.repos = _.partial(THREE.Vector3.prototype.add, v)
#http://www.softimageblog.com/archives/115
sphere_dist = (n) ->
dist = []
inc = Math.PI * (3 - Math.sqrt 5)
o = 2/n
for i in [1..n]
y = i * o - 1 + (o/2)
r = Math.sqrt(1) - y*y
phi = i * inc
dist.push [Math.cos(phi) * r, y, Math.sin(phi) * r]
dist
no_idea = (x,y,z) ->
sx = x*0.2
sy = y*0.2
sz = z*0.2
x = 0.0
y = 0.0
z = 0.0
cx = 0
cy = 0
cz = 0
points = []
while points.length < s
ncx = Math.floor x
ncy = Math.floor y
ncz = Math.floor z
if ncx != cx or ncy != cy or ncz != cz
depth = Math.sqrt x*x+y*y+z*z
cx = ncx
cy = ncy
cz = ncz
#points.push [depth, cx, cy, cz]
points.push [cx, cy, cz]
x+=sx
y+=sy
z+=sz
points
camera.position.z = s * 2.5
lookup = (c,x,y,z) ->
r = [0..s-1]
if x in r and y in r and z in r then c[idx x,y,z] else false
place = (c,x,y,z,v) ->
r = [0..s-1]
if x in r and y in r and z in r then c[idx x,y,z] = v else false
cube = cube_loop (x,y,z) ->
tv = new THREE.Vector3(x,y,z).repos().normalize() #.multiplyScalar(1.1)
noise(tv.x,tv.y,tv.z) > 1.1
cube = []
rays = sphere_dist 50
rayoffs = (no_idea r... for r in rays)
(place cube, p[0] - nsh, p[1] - nsh, p[2] - nsh, true for p in ray for ray in rayoffs)
console.log cube if s < 5
neigh = (cube,x,y,z) ->
vof = (dir, c) ->
oob = (c[dir] < 0 or c[dir] >= s)
if oob then false else lookup cube, c...
n = [[0,[x-1,y,z]],[0,[x+1,y,z]],[1,[x,y-1,z]],[1,[x,y+1,z]],[2,[x,y,z-1]],[2,[x,y,z+1]]]
(vof i... for i in n)
tp = [0,0,0]
console.log "cube @ ", tp, lookup(cube,tp...)
console.log "idx @ ", tp, idx(tp...)
console.log "neigh @ ", tp, neigh(cube,tp...)
g = new THREE.Geometry()
idxvs = (x,y,z) ->
g.vertices.push new THREE.Vector3(x,y,z).repos()
g.vertices.length - 1
cube_loop (x,y,z,i) ->
if cube[i]
_.each neigh(cube,x,y,z), (e2,i2) ->
unless e2
f = switch i2
when 0 then new THREE.Face4 idxvs(x,y,z), idxvs(x,y,z+1), idxvs(x,y+1,z+1), idxvs(x,y+1,z)
when 1 then new THREE.Face4 idxvs(x+1,y,z), idxvs(x+1,y+1,z), idxvs(x+1,y+1,z+1), idxvs(x+1,y,z+1)
when 2 then new THREE.Face4 idxvs(x,y,z), idxvs(x+1,y,z), idxvs(x+1,y,z+1), idxvs(x,y,z+1)
when 3 then new THREE.Face4 idxvs(x,y+1,z), idxvs(x,y+1,z+1), idxvs(x+1,y+1,z+1), idxvs(x+1,y+1,z)
when 4 then new THREE.Face4 idxvs(x,y,z), idxvs(x,y+1,z), idxvs(x+1,y+1,z), idxvs(x+1,y,z)
when 5 then new THREE.Face4 idxvs(x,y,z+1), idxvs(x+1,y,z+1), idxvs(x+1,y+1,z+1), idxvs(x,y+1,z+1)
g.faces.push f
console.log g if s < 5
m = new THREE.Mesh g, new THREE.ShaderMaterial({
vertexShader: $('#shlightv').text(),
fragmentShader: $('#shlightf').text(),
uniforms: {ScaleFactor: 1.0}})
scene.add m
g.computeFaceNormals()
g.computeVertexNormals()
g.normalsNeedUpdate = true
precalc = ([s * Math.sin(i), s * Math.cos(i)] for i in [0.0..2*Math.PI] by 0.005)
doit = (t) ->
u = precalc[Math.floor(t % precalc.length)] or [0,1]
camera.position.x = u[0]
camera.position.y = u[1]
camera.lookAt scene.position
renderer.render scene, camera
requestAnimationFrame doit
doit 0
</script>
</head>
<body>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment