mirror of
https://github.com/wahyd4/three.js.git
synced 2026-08-09 13:06:01 +10:00
This allows to work around ANGLE antialiasing issue appearing when compositing WebGL framebuffer with transparent background color with HTML canvas element background (while keeping antialiasing on).
WebGLRenderer constructor now takes JSON object with few optional parameters:
renderer = new THREE.WebGLRenderer { scene: scene,
antialias: true,
clearColor: 0x000000,
clearAlpha: 0 };
Here is how to change clear color in runtime:
renderer.setClearColor( 0xff0000, 1 );
319 lines
7.8 KiB
HTML
319 lines
7.8 KiB
HTML
<!DOCTYPE HTML>
|
|
<html lang="en">
|
|
<head>
|
|
<title>three.js - geometry - minecraft</title>
|
|
<meta charset="utf-8">
|
|
<style type="text/css">
|
|
body {
|
|
color: #61443e;
|
|
font-family:Monospace;
|
|
font-size:13px;
|
|
text-align:center;
|
|
|
|
background-color: #bfd1e5;
|
|
margin: 0px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
#info {
|
|
position: absolute;
|
|
top: 0px; width: 100%;
|
|
padding: 5px;
|
|
}
|
|
|
|
a {
|
|
|
|
color: #a06851;
|
|
}
|
|
|
|
</style>
|
|
</head>
|
|
<body>
|
|
|
|
<div id="container"><br /><br /><br /><br /><br />Generating world...</div>
|
|
<div id="info"><a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - <a href="http://www.minecraft.net/" target="_blank">minecraft</a> demo. featuring <a href="http://painterlypack.net/" target="_blank">painterly pack</a><br />(left click: forward, right click: backward)</div>
|
|
|
|
<script type="text/javascript" src="js/Stats.js"></script>
|
|
<script type="text/javascript" src="js/ImprovedNoise.js"></script>
|
|
|
|
<script type="text/javascript" src="../build/Three.js"></script>
|
|
<script type="text/javascript" src="../src/extras/GeometryUtils.js"></script>
|
|
<script type="text/javascript" src="../src/extras/primitives/Cube.js"></script>
|
|
|
|
<script type="text/javascript">
|
|
|
|
var container, stats;
|
|
|
|
var camera, scene, renderer;
|
|
|
|
var mesh;
|
|
|
|
var worldWidth = 128, worldDepth = 128,
|
|
worldHalfWidth = worldWidth / 2, worldHalfDepth = worldDepth / 2,
|
|
data = generateHeight( worldWidth, worldDepth );
|
|
|
|
var mouseX = 0, mouseY = 0,
|
|
lat = 0, lon = 0, phy = 0, theta = 0;
|
|
|
|
var direction = new THREE.Vector3(),
|
|
moveForward = false, moveBackward = false;
|
|
|
|
var windowHalfX = window.innerWidth / 2;
|
|
var windowHalfY = window.innerHeight / 2;
|
|
|
|
|
|
init();
|
|
setInterval( loop, 1000 / 60 );
|
|
|
|
|
|
function init() {
|
|
|
|
container = document.getElementById( 'container' );
|
|
|
|
camera = new THREE.Camera( 60, window.innerWidth / window.innerHeight, 1, 20000 );
|
|
camera.target.position.z = - 100;
|
|
|
|
scene = new THREE.Scene();
|
|
|
|
var grass_dirt = loadTexture( 'textures/minecraft/grass_dirt.png' ),
|
|
grass = loadTexture( 'textures/minecraft/grass.png' ),
|
|
dirt = loadTexture( 'textures/minecraft/dirt.png' );
|
|
|
|
var materials = [
|
|
|
|
grass_dirt, // right
|
|
grass_dirt, // left
|
|
grass, // top
|
|
dirt, // bottom
|
|
grass_dirt, // back
|
|
grass_dirt // front
|
|
|
|
];
|
|
|
|
var h, h2, px, nx, pz, nz, cubes = [];
|
|
|
|
for ( var i = 0; i < 16; i++ ) {
|
|
|
|
px = (i & 8) == 8;
|
|
nx = (i & 4) == 4;
|
|
pz = (i & 2) == 2;
|
|
nz = (i & 1) == 1;
|
|
cubes[ i ] = new Cube( 100, 100, 100, 1, 1, materials, false, { px: px, nx: nx, py: true, ny: false, pz: pz, nz: nz } );
|
|
|
|
}
|
|
|
|
var geometry = new THREE.Geometry();
|
|
|
|
camera.position.y = getY( worldHalfWidth, worldHalfDepth ) * 100 + 100;
|
|
camera.target.position.y = camera.position.y;
|
|
|
|
for ( var z = 0; z < worldDepth; z ++ ) {
|
|
|
|
for ( var x = 0; x < worldWidth; x ++ ) {
|
|
|
|
px = nx = pz = nz = 0;
|
|
|
|
h = getY( x, z );
|
|
|
|
h2 = getY( x - 1, z );
|
|
px = ( h2 != h && h2 != h + 1 ) || x == 0 ? 1 : 0;
|
|
|
|
h2 = getY( x + 1, z );
|
|
nx = ( h2 != h && h2 != h + 1 ) || x == worldWidth - 1 ? 1 : 0;
|
|
|
|
h2 = getY( x, z + 1 );
|
|
pz = ( h2 != h && h2 != h + 1 ) || z == worldDepth - 1 ? 1 : 0;
|
|
|
|
h2 = getY( x, z - 1 );
|
|
nz = ( h2 != h && h2 != h + 1 ) || z == 0 ? 1 : 0;
|
|
|
|
mesh = new THREE.Mesh( cubes[ px * 8 + nx * 4 + pz * 2 + nz ] );
|
|
|
|
mesh.position.x = x * 100 - worldHalfWidth * 100;
|
|
mesh.position.y = h * 100;
|
|
mesh.position.z = z * 100 - worldHalfDepth * 100;
|
|
|
|
GeometryUtils.merge( geometry, mesh );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
geometry.sortFacesByMaterial();
|
|
|
|
mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() );
|
|
scene.addObject( mesh );
|
|
|
|
var ambientLight = new THREE.AmbientLight( 0xcccccc );
|
|
scene.addLight( ambientLight );
|
|
|
|
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( { scene: scene } );
|
|
renderer.setSize( window.innerWidth, window.innerHeight );
|
|
|
|
container.innerHTML = "";
|
|
|
|
container.appendChild( renderer.domElement );
|
|
|
|
stats = new Stats();
|
|
stats.domElement.style.position = 'absolute';
|
|
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 );
|
|
|
|
}
|
|
|
|
function generateAO( image, sides ) {
|
|
|
|
var c = document.createElement('canvas');
|
|
c.width = image.width;
|
|
c.height = image.height;
|
|
c.getContext( "2d" ).drawImage( image, 0, 0 );
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
function loadTexture( path ) {
|
|
|
|
var image = new Image();
|
|
image.onload = function () { this.loaded = true; };
|
|
image.src = path;
|
|
|
|
return new THREE.MeshLambertMaterial( { map: new THREE.Texture( image, new THREE.UVMapping(), THREE.ClampToEdgeWrapping, THREE.ClampToEdgeWrapping, THREE.NearestFilter, THREE.LinearMipMapLinearFilter ) } );
|
|
|
|
}
|
|
|
|
function generateHeight( width, height ) {
|
|
|
|
var data = [], perlin = new ImprovedNoise(),
|
|
size = width * height, quality = 2, z = Math.random() * 100;
|
|
|
|
for ( var j = 0; j < 4; j ++ ) {
|
|
|
|
if ( j == 0 ) for ( var i = 0; i < size; i ++ ) data[ i ] = 0;
|
|
|
|
for ( var i = 0; i < size; i ++ ) {
|
|
|
|
var x = i % width, y = ~~ ( i / width );
|
|
data[ i ] += perlin.noise( x / quality, y / quality, z ) * quality;
|
|
|
|
|
|
}
|
|
|
|
quality *= 4
|
|
|
|
}
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
function getY( x, z ) {
|
|
|
|
return ~~( data[ x + z * worldWidth ] * 0.2 );
|
|
|
|
}
|
|
|
|
function onDocumentMouseDown( event ) {
|
|
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
switch ( event.button ) {
|
|
|
|
case 0: moveForward = true; break;
|
|
case 2: moveBackward = true; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function onDocumentMouseUp( event ) {
|
|
|
|
event.preventDefault();
|
|
event.stopPropagation();
|
|
|
|
switch ( event.button ) {
|
|
|
|
case 0: moveForward = false; break;
|
|
case 2: moveBackward = false; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function onDocumentMouseMove(event) {
|
|
|
|
mouseX = event.clientX - windowHalfX;
|
|
mouseY = event.clientY - windowHalfY;
|
|
|
|
}
|
|
|
|
function onDocumentKeyDown( event ) {
|
|
|
|
switch( event.keyCode ) {
|
|
|
|
case 38: /*↑*/ moveForward = true; break;
|
|
case 40: /*↓*/ moveBackward = true; break;
|
|
|
|
case 87: /*W*/ moveForward = true; break;
|
|
case 83: /*S*/ moveBackward = true; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function onDocumentKeyUp( event ) {
|
|
|
|
switch( event.keyCode ) {
|
|
|
|
case 38: /*↑*/ moveForward = false; break;
|
|
case 40: /*↓*/ moveBackward = false; break;
|
|
|
|
case 87: /*W*/ moveForward = false; break;
|
|
case 83: /*S*/ moveBackward = false; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
function loop() {
|
|
|
|
if ( moveForward ) camera.translateZ( - 15 );
|
|
if ( moveBackward ) camera.translateZ( 15 );
|
|
|
|
lon += mouseX * 0.005;
|
|
lat -= mouseY * 0.005;
|
|
|
|
lat = Math.max( - 85, Math.min( 85, lat ) );
|
|
phi = ( 90 - lat ) * Math.PI / 180;
|
|
theta = lon * Math.PI / 180;
|
|
|
|
camera.target.position.x = 100 * Math.sin( phi ) * Math.cos( theta ) + camera.position.x;
|
|
camera.target.position.y = 100 * Math.cos( phi ) + camera.position.y;
|
|
camera.target.position.z = 100 * Math.sin( phi ) * Math.sin( theta ) + camera.position.z;
|
|
|
|
renderer.render(scene, camera);
|
|
stats.update();
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|