mirror of
https://github.com/wahyd4/three.js.git
synced 2026-08-09 13:06:01 +10:00
This should allow attaching of lights to objects. As a side effect, directional lights positions don't need to be normalized explicitly anymore. Also changed viewport dimensions passed to render plugins to work with render targets with different dimensions than the screen framebuffer. And fixed new dependencies in build script.
318 lines
8.4 KiB
HTML
318 lines
8.4 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<title>three.js webgl - fly camera - earth</title>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
|
|
<style>
|
|
body {
|
|
background:#000;
|
|
color: #eee;
|
|
padding:0;
|
|
margin:0;
|
|
font-weight:bold;
|
|
overflow:hidden;
|
|
|
|
font-family:Monospace;
|
|
font-size:13px;
|
|
text-align:center;
|
|
}
|
|
|
|
#info {
|
|
position: absolute;
|
|
top: 0px; width: 100%;
|
|
padding: 5px;
|
|
z-index:100;
|
|
}
|
|
|
|
a {
|
|
|
|
color: #0080ff;
|
|
}
|
|
|
|
b { color:orange }
|
|
</style>
|
|
|
|
<script src="../build/Three.js"></script>
|
|
|
|
<script src="js/ShaderExtras.js"></script>
|
|
|
|
<script src="js/postprocessing/EffectComposer.js"></script>
|
|
<script src="js/postprocessing/ShaderPass.js"></script>
|
|
<script src="js/postprocessing/MaskPass.js"></script>
|
|
<script src="js/postprocessing/RenderPass.js"></script>
|
|
<script src="js/postprocessing/FilmPass.js"></script>
|
|
|
|
<script src="js/Detector.js"></script>
|
|
<script src="js/RequestAnimationFrame.js"></script>
|
|
<script src="js/Stats.js"></script>
|
|
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="info"><a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - earth [fly camera]<br/><br/>
|
|
<b>WASD</b> move, <b>R|F</b> up | down, <b>Q|E</b> roll, <b>up|down</b> pitch, <b>left|right</b> yaw<br/>
|
|
</div>
|
|
|
|
<script>
|
|
|
|
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
|
|
|
|
var radius = 6371;
|
|
var tilt = 0.41;
|
|
var rotationSpeed = 0.02;
|
|
|
|
var cloudsScale = 1.005;
|
|
var moonScale = 0.23;
|
|
|
|
var MARGIN = 0;
|
|
var SCREEN_HEIGHT = window.innerHeight - MARGIN * 2;
|
|
var SCREEN_WIDTH = window.innerWidth;
|
|
|
|
var container, stats;
|
|
var camera, controls, scene, sceneCube, renderer;
|
|
var geometry, meshPlanet, meshClouds, meshMoon;
|
|
var dirLight, pointLight, ambientLight;
|
|
|
|
var d, dPlanet, dMoon, dMoonVec = new THREE.Vector3();
|
|
|
|
var clock = new THREE.Clock();
|
|
|
|
init();
|
|
animate();
|
|
|
|
function init() {
|
|
|
|
container = document.createElement( 'div' );
|
|
document.body.appendChild( container );
|
|
|
|
camera = new THREE.PerspectiveCamera( 25, SCREEN_WIDTH / SCREEN_HEIGHT, 50, 1e7 );
|
|
camera.position.z = radius * 5;
|
|
|
|
controls = new THREE.FlyControls( camera );
|
|
|
|
controls.movementSpeed = 1000;
|
|
controls.domElement = container;
|
|
controls.rollSpeed = Math.PI / 24;
|
|
controls.autoForward = false;
|
|
controls.dragToLook = false
|
|
|
|
|
|
scene = new THREE.Scene();
|
|
scene.fog = new THREE.FogExp2( 0x000000, 0.00000025 );
|
|
|
|
dirLight = new THREE.DirectionalLight( 0xffffff );
|
|
dirLight.position.set( -1, 0, 1 ).normalize();
|
|
scene.add( dirLight );
|
|
|
|
ambientLight = new THREE.AmbientLight( 0x000000 );
|
|
scene.add( ambientLight );
|
|
|
|
var planetTexture = THREE.ImageUtils.loadTexture( "textures/planets/earth_atmos_2048.jpg" );
|
|
var cloudsTexture = THREE.ImageUtils.loadTexture( "textures/planets/earth_clouds_1024.png" );
|
|
var normalTexture = THREE.ImageUtils.loadTexture( "textures/planets/earth_normal_2048.jpg" );
|
|
var specularTexture = THREE.ImageUtils.loadTexture( "textures/planets/earth_specular_2048.jpg" );
|
|
|
|
var moonTexture = THREE.ImageUtils.loadTexture( "textures/planets/moon_1024.jpg" );
|
|
|
|
var shader = THREE.ShaderUtils.lib[ "normal" ];
|
|
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
|
|
|
|
uniforms[ "tNormal" ].texture = normalTexture;
|
|
uniforms[ "uNormalScale" ].value = 0.85;
|
|
|
|
uniforms[ "tDiffuse" ].texture = planetTexture;
|
|
uniforms[ "tSpecular" ].texture = specularTexture;
|
|
|
|
uniforms[ "enableAO" ].value = false;
|
|
uniforms[ "enableDiffuse" ].value = true;
|
|
uniforms[ "enableSpecular" ].value = true;
|
|
|
|
uniforms[ "uDiffuseColor" ].value.setHex( 0xffffff );
|
|
uniforms[ "uSpecularColor" ].value.setHex( 0x333333 );
|
|
uniforms[ "uAmbientColor" ].value.setHex( 0x000000 );
|
|
|
|
uniforms[ "uShininess" ].value = 15;
|
|
|
|
var parameters = {
|
|
|
|
fragmentShader: shader.fragmentShader,
|
|
vertexShader: shader.vertexShader,
|
|
uniforms: uniforms,
|
|
lights: true,
|
|
fog: true
|
|
|
|
};
|
|
|
|
var materialNormalMap = new THREE.ShaderMaterial( parameters );
|
|
|
|
// planet
|
|
|
|
geometry = new THREE.SphereGeometry( radius, 100, 50 );
|
|
geometry.computeTangents();
|
|
|
|
meshPlanet = new THREE.Mesh( geometry, materialNormalMap );
|
|
meshPlanet.rotation.y = 0;
|
|
meshPlanet.rotation.z = tilt;
|
|
scene.add( meshPlanet );
|
|
|
|
// clouds
|
|
|
|
var materialClouds = new THREE.MeshLambertMaterial( { color: 0xffffff, map: cloudsTexture, transparent: true } );
|
|
|
|
meshClouds = new THREE.Mesh( geometry, materialClouds );
|
|
meshClouds.scale.set( cloudsScale, cloudsScale, cloudsScale );
|
|
meshClouds.rotation.z = tilt;
|
|
scene.add( meshClouds );
|
|
|
|
// moon
|
|
|
|
var materialMoon = new THREE.MeshPhongMaterial( { color: 0xffffff, map: moonTexture } );
|
|
|
|
meshMoon = new THREE.Mesh( geometry, materialMoon );
|
|
meshMoon.position.set( radius * 5, 0, 0 );
|
|
meshMoon.scale.set( moonScale, moonScale, moonScale );
|
|
scene.add( meshMoon );
|
|
|
|
// stars
|
|
|
|
var i, r = radius, starsGeometry = [ new THREE.Geometry(), new THREE.Geometry() ];
|
|
|
|
for ( i = 0; i < 250; i ++ ) {
|
|
|
|
vector1 = new THREE.Vector3( Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1 );
|
|
vector1.multiplyScalar( r );
|
|
|
|
starsGeometry[ 0 ].vertices.push( new THREE.Vertex( vector1 ) );
|
|
|
|
}
|
|
|
|
for ( i = 0; i < 1500; i ++ ) {
|
|
|
|
vector1 = new THREE.Vector3( Math.random() * 2 - 1, Math.random() * 2 - 1, Math.random() * 2 - 1 );
|
|
vector1.multiplyScalar( r );
|
|
|
|
starsGeometry[ 1 ].vertices.push( new THREE.Vertex( vector1 ) );
|
|
|
|
}
|
|
|
|
var stars;
|
|
var starsMaterials = [
|
|
new THREE.ParticleBasicMaterial( { color: 0x555555, size: 2, sizeAttenuation: false } ),
|
|
new THREE.ParticleBasicMaterial( { color: 0x555555, size: 1, sizeAttenuation: false } ),
|
|
new THREE.ParticleBasicMaterial( { color: 0x333333, size: 2, sizeAttenuation: false } ),
|
|
new THREE.ParticleBasicMaterial( { color: 0x3a3a3a, size: 1, sizeAttenuation: false } ),
|
|
new THREE.ParticleBasicMaterial( { color: 0x1a1a1a, size: 2, sizeAttenuation: false } ),
|
|
new THREE.ParticleBasicMaterial( { color: 0x1a1a1a, size: 1, sizeAttenuation: false } )
|
|
];
|
|
|
|
for ( i = 10; i < 30; i ++ ) {
|
|
|
|
stars = new THREE.ParticleSystem( starsGeometry[ i % 2 ], starsMaterials[ i % 6 ] );
|
|
|
|
stars.rotation.x = Math.random() * 6;
|
|
stars.rotation.y = Math.random() * 6;
|
|
stars.rotation.z = Math.random() * 6;
|
|
|
|
s = i * 10;
|
|
stars.scale.set( s, s, s );
|
|
|
|
stars.matrixAutoUpdate = false;
|
|
stars.updateMatrix();
|
|
|
|
scene.add( stars );
|
|
|
|
}
|
|
|
|
renderer = new THREE.WebGLRenderer( { clearColor: 0x000000, clearAlpha: 1 } );
|
|
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
|
|
renderer.sortObjects = false;
|
|
|
|
renderer.autoClear = false;
|
|
|
|
container.appendChild( renderer.domElement );
|
|
|
|
stats = new Stats();
|
|
stats.domElement.style.position = 'absolute';
|
|
stats.domElement.style.top = '0px';
|
|
stats.domElement.style.zIndex = 100;
|
|
container.appendChild( stats.domElement );
|
|
|
|
window.addEventListener( 'resize', onWindowResize, false );
|
|
|
|
// postprocessing
|
|
|
|
var renderModel = new THREE.RenderPass( scene, camera );
|
|
var effectFilm = new THREE.FilmPass( 0.35, 0.75, 2048, false );
|
|
|
|
effectFilm.renderToScreen = true;
|
|
|
|
composer = new THREE.EffectComposer( renderer );
|
|
|
|
composer.addPass( renderModel );
|
|
composer.addPass( effectFilm );
|
|
|
|
};
|
|
|
|
function onWindowResize( event ) {
|
|
|
|
SCREEN_HEIGHT = window.innerHeight;
|
|
SCREEN_WIDTH = window.innerWidth;
|
|
|
|
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
|
|
|
|
camera.aspect = SCREEN_WIDTH / SCREEN_HEIGHT;
|
|
camera.updateProjectionMatrix();
|
|
|
|
composer.reset();
|
|
|
|
};
|
|
|
|
function animate() {
|
|
|
|
requestAnimationFrame( animate );
|
|
|
|
render();
|
|
stats.update();
|
|
|
|
};
|
|
|
|
function render() {
|
|
|
|
// rotate the planet and clouds
|
|
|
|
var delta = clock.getDelta();
|
|
|
|
meshPlanet.rotation.y += rotationSpeed * delta;
|
|
meshClouds.rotation.y += 1.25 * rotationSpeed * delta;
|
|
|
|
// slow down as we approach the surface
|
|
|
|
dPlanet = camera.position.length();
|
|
|
|
dMoonVec.sub( camera.position, meshMoon.position );
|
|
dMoon = dMoonVec.length();
|
|
|
|
if ( dMoon < dPlanet ) {
|
|
|
|
d = ( dMoon - radius * moonScale * 1.01 );
|
|
|
|
} else {
|
|
|
|
d = ( dPlanet - radius * 1.01 );
|
|
|
|
}
|
|
|
|
controls.movementSpeed = 0.33 * d;
|
|
controls.update( delta );
|
|
|
|
renderer.clear();
|
|
composer.render( delta );
|
|
|
|
};
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|