From 2dcbde4d69fe2f01ccb6d4c3fd556c024beb94b4 Mon Sep 17 00:00:00 2001 From: "Mr.doob" Date: Tue, 7 Dec 2010 09:13:32 +0000 Subject: [PATCH] Added webgl terrain example. --- README.md | 2 + examples/geometry_minecraft.html | 77 ++++----- examples/geometry_terrain.html | 104 ++++-------- examples/geometry_terrain_gl.html | 262 ++++++++++++++++++++++++++++++ 4 files changed, 337 insertions(+), 108 deletions(-) create mode 100644 examples/geometry_terrain_gl.html diff --git a/README.md b/README.md index dce55e6d..6a34b3ec 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ More? irc.freenode.net #three.js #### WebGL #### +[![geometry_terrain_gl](http://mrdoob.github.com/three.js/assets/examples/30_geometry_terrain_gl.png)](http://mrdoob.github.com/three.js/examples/geometry_terrain_gl.html) [![geometry_minecraft](http://mrdoob.github.com/three.js/assets/examples/29_geometry_minecraft.png)](http://mrdoob.github.com/three.js/examples/geometry_minecraft.html) [![materials_shader_fresnel](http://mrdoob.github.com/three.js/assets/examples/28_materials_shaders_fresnel.png)](http://mrdoob.github.com/three.js/examples/materials_shaders_fresnel.html) [![materials_cars](http://mrdoob.github.com/three.js/assets/examples/25_materials_cars.png)](http://mrdoob.github.com/three.js/examples/materials_cars.html) @@ -50,6 +51,7 @@ More? irc.freenode.net #three.js ### Featured projects ### +[![Sculpt](http://mrdoob.github.com/three.js/assets/projects/11_sculpt.png)](http://antimatter15.com/wp/2010/11/digital-sculpting-with-three-js/) [![Voxels](http://mrdoob.github.com/three.js/assets/projects/10_voxels.png)](http://mrdoob.com/projects/voxels/) [![The Wilderness Downtown](http://mrdoob.github.com/three.js/assets/projects/09_arcadefire.png)](http://thewildernessdowntown.com/) [![CloudSCAD](http://mrdoob.github.com/three.js/assets/projects/08_cloudscad.png)](http://cloudscad.com/stl_viewer/) diff --git a/examples/geometry_minecraft.html b/examples/geometry_minecraft.html index 2ec5eee0..7be88a44 100644 --- a/examples/geometry_minecraft.html +++ b/examples/geometry_minecraft.html @@ -31,7 +31,7 @@





Generating world...
-
three.js - minecraft demo. featuring painterly pack
(camera move: WASD/↑←↓→)
+
three.js - minecraft demo. featuring painterly pack
(right click: forward, left click: backward)
@@ -56,8 +56,7 @@ lat = 0, lon = 0, phy = 0, theta = 0; var direction = new THREE.Vector3(), - moveForward = false, moveBackwards = false, - moveLeft = false, moveRight = false; + moveForward = false, moveBackwards = false; var windowHalfX = window.innerWidth / 2; var windowHalfY = window.innerHeight / 2; @@ -115,12 +114,12 @@ var ambientLight = new THREE.AmbientLight( 0xcccccc ); scene.addLight( ambientLight ); - var pointLight = new THREE.DirectionalLight( 0xffffff, 1.5 ); - pointLight.position.x = 1; - pointLight.position.y = 1; - pointLight.position.z = 0.5; - pointLight.position.normalize; - scene.addLight( pointLight ); + var directionalLight = new THREE.DirectionalLight( 0xffffff, 1.5 ); + directionalLight.position.x = 1; + directionalLight.position.y = 1; + directionalLight.position.z = 0.5; + directionalLight.position.normalize(); + scene.addLight( directionalLight ); renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); @@ -134,7 +133,11 @@ stats.domElement.style.top = '0px'; container.appendChild( stats.domElement ); + document.addEventListener( 'mousedown', onDocumentMouseDown, false ); + document.addEventListener( 'mouseup', onDocumentMouseUp, false ); document.addEventListener( 'mousemove', onDocumentMouseMove, false ); + document.addEventListener( 'contextmenu', function ( event ) { event.preventDefault(); }, false ); + document.addEventListener( 'keydown', onDocumentKeyDown, false ); document.addEventListener( 'keyup', onDocumentKeyUp, false ); @@ -181,6 +184,34 @@ } + function onDocumentMouseDown( event ) { + + event.preventDefault(); + event.stopPropagation(); + + switch ( event.button ) { + + case 0: moveForward = true; break; + case 2: moveBackwards = true; break; + + } + + } + + function onDocumentMouseUp( event ) { + + event.preventDefault(); + event.stopPropagation(); + + switch ( event.button ) { + + case 0: moveForward = false; break; + case 2: moveBackwards = false; break; + + } + + } + function onDocumentMouseMove(event) { mouseX = event.clientX - windowHalfX; @@ -189,20 +220,14 @@ } function onDocumentKeyDown( event ) { - - // console.log( event.keyCode ); switch( event.keyCode ) { case 38: /*↑*/ moveForward = true; break; case 40: /*↓*/ moveBackwards = true; break; - case 37: /*←*/ moveLeft = true; break; - case 39: /*→*/ moveRight = true; break; case 87: /*W*/ moveForward = true; break; case 83: /*S*/ moveBackwards = true; break; - case 65: /*A*/ moveLeft = true; break; - case 68: /*D*/ moveRight = true; break; } @@ -214,13 +239,9 @@ case 38: /*↑*/ moveForward = false; break; case 40: /*↓*/ moveBackwards = false; break; - case 37: /*←*/ moveLeft = false; break; - case 39: /*→*/ moveRight = false; break; case 87: /*W*/ moveForward = false; break; case 83: /*S*/ moveBackwards = false; break; - case 65: /*A*/ moveLeft = false; break; - case 68: /*D*/ moveRight = false; break; } @@ -244,24 +265,6 @@ } - if ( moveLeft ) { - - direction.copy( camera.target.position ).subSelf( camera.position ).normalize().multiplyScalar( - 15 ); - direction.cross( direction.clone(), new THREE.Vector3( 0, 1, 0 ) ); - camera.position.addSelf( direction ); - camera.target.position.addSelf( direction ); - - } - - if ( moveRight ) { - - direction.copy( camera.target.position ).subSelf( camera.position ).normalize().multiplyScalar( 15 ); - direction.cross( direction.clone(), new THREE.Vector3( 0, 1, 0 ) ); - camera.position.addSelf( direction ); - camera.target.position.addSelf( direction ); - - }; - lon += mouseX * 0.005; lat -= mouseY * 0.005; diff --git a/examples/geometry_terrain.html b/examples/geometry_terrain.html index fdea7916..12eca50e 100644 --- a/examples/geometry_terrain.html +++ b/examples/geometry_terrain.html @@ -67,28 +67,16 @@ scene = new THREE.Scene(); - var heightMap = height( 1024, 1024 ); + var data = generateHeight( 1024, 1024 ); + var material = new THREE.MeshBasicMaterial( { map: new THREE.Texture( generateTexture( data, 1024, 1024 ) ) } ); - var texture = new THREE.Texture( shadow( heightMap ) ); - texture.image.loaded = true; + var quality = 16, step = 1024 / quality; + var plane = new Plane( 2000, 2000, quality - 1, quality - 1 ); - var material = new THREE.MeshBasicMaterial( { map: texture } ); + for ( var i = 0, l = plane.vertices.length; i < l; i ++ ) { - var quality = 20; - var quality1 = quality + 1; - - var plane = new Plane( 2000, 2000, quality, quality ); - - var data = heightMap.getContext( '2d' ).getImageData( 0, 0, heightMap.width, heightMap.height ).data; - var pixelsPerTriangle = Math.floor( heightMap.width / quality ); - - for ( var y = 0; y < quality1; y++ ) { - - for (var x = 0; x < quality1; x++ ) { - - plane.vertices[x + y * quality1].position.z = data[((x * pixelsPerTriangle) + (y * pixelsPerTriangle) * heightMap.width) * 4] * 2 - 128; - - } + var x = i % quality, y = ~~ ( i / quality ); + plane.vertices[ i ].position.z = data[ ( x * step ) + ( y * step ) * 1024 ] * 2 - 128; } @@ -98,7 +86,7 @@ mesh = new THREE.Mesh( plane, material ); mesh.rotation.x = -90 * Math.PI / 180; mesh.overdraw = true; - scene.addObject(mesh); + scene.addObject( mesh ); renderer = new THREE.CanvasRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); @@ -133,60 +121,39 @@ } - function height( width, height ) { + function generateHeight( width, height ) { - var canvas, context, image, data; + var data = Float32Array ? new Float32Array() : [], perlin = new ImprovedNoise(), + size = width * height, quality = 2, z = Math.random() * 100; - canvas = document.createElement( 'canvas' ); - canvas.width = width; - canvas.height = height; + for ( var i = 0; i < size; i ++ ) { - context = canvas.getContext( '2d' ); - context.fillStyle = '#000'; - context.fillRect( 0, 0, width, height ); + data[ i ] = 0 - image = context.getImageData( 0, 0, width, height ); - data = image.data; - - var perlin = new ImprovedNoise(); - - var size = width * height; - var quality = 2; - var zz = Math.random() * 100; + } for ( var j = 0; j < 4; j ++ ) { - var x = 0, y = 0, yy = 0; - quality *= 4; for ( var i = 0; i < size; i ++ ) { - data[ i * 4 ] += Math.floor( Math.abs( perlin.noise( x / quality, yy, zz ) * 0.5 ) * quality + 10 ); + var x = i % width, y = ~~ ( i / width ); + data[ i ] += Math.abs( perlin.noise( x / quality, y / quality, z ) * 0.5 * quality + 10 ); - x++; - - if (x == width) - { - x = 0; - y ++; - yy = y / quality; - } } + } - context.putImageData( image, 0, 0 ); - - return canvas; + return data; } - function shadow( texture ) { + function generateTexture( data, width, height ) { - var canvas, context, image, data, src_data, - index, level, diff, width = texture.width, height = texture.height, - vector3, sun, shade; + var canvas, context, image, imageData, + level, diff, vector3, sun, shade; vector3 = new THREE.Vector3( 0, 0, 0 ); @@ -196,39 +163,34 @@ canvas = document.createElement( 'canvas' ); canvas.width = width; canvas.height = height; + canvas.loaded = true; context = canvas.getContext( '2d' ); context.fillStyle = '#000'; context.fillRect( 0, 0, width, height ); image = context.getImageData( 0, 0, width, height ); - data = image.data; + imageData = image.data; - src_data = texture.getContext( '2d' ).getImageData( 0, 0, width, height ).data; + for ( var i = 0, j = 0, l = imageData.length; i < l; i += 4, j ++ ) { - for ( var y = 0; y < height; y++ ) { + vector3.x = data[ j - 1 ] - data[ j + 1 ]; + vector3.y = 2; + vector3.z = data[ j - width ] - data[ j + width ]; + vector3.normalize(); - for ( var x = 0; x < width; x++ ) { + shade = vector3.dot( sun ); - index = ( x + y * width ) * 4; + imageData[ i ] = ( 96 + shade * 128 ) * ( data[ j ] * 0.007 ); + imageData[ i + 1 ] = ( 32 + shade * 96 ) * ( data[ j ] * 0.007 ); + imageData[ i + 2 ] = ( shade * 96 ) * ( data[ j ] * 0.007 ); - vector3.x = src_data[ index - 4 ] - src_data[ index + 4 ]; - vector3.y = 2; - vector3.z = src_data[ index - ( width * 4 ) ] - src_data[ index + ( width * 4 ) ]; - vector3.normalize(); - - shade = vector3.dot(sun); - - data[ index ] = ( 96 + shade * 128 ) * ( src_data[ index ] * 0.007 ); - data[ index + 1 ] = ( 32 + shade * 96 ) * ( src_data[ index ] * 0.007 ); - data[ index + 2 ] = ( shade * 96 ) * ( src_data[ index ] * 0.007 ); - - } } context.putImageData( image, 0, 0 ); return canvas; + } diff --git a/examples/geometry_terrain_gl.html b/examples/geometry_terrain_gl.html new file mode 100644 index 00000000..9516a643 --- /dev/null +++ b/examples/geometry_terrain_gl.html @@ -0,0 +1,262 @@ + + + + three.js - geometry - webgl terrain + + + + + +





Generating world...
+
three.js - webgl terrain demo
(right click: forward, left click: backward)
+ + + + + + + + + + + +