Last active
December 15, 2015 12:28
-
-
Save laod/5260092 to your computer and use it in GitHub Desktop.
Experiments with three.js. Horrible hacks.
This file contains 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
<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