mirror of
https://github.com/wahyd4/three.js.git
synced 2026-08-09 04:56:01 +10:00
Got tired of redoing deltas all the time. Not sure about API or implementation details, but so far seems to be useful. In future, we could for example have clocks that are slower / faster than realtime, or fixed step based.
401 lines
10 KiB
HTML
401 lines
10 KiB
HTML
<!doctype html>
|
|
<html lang="en">
|
|
<head>
|
|
<title>three.js webgl - shadow map</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 {
|
|
font-family: Monospace;
|
|
background-color: #000;
|
|
color: #fff;
|
|
margin: 0px;
|
|
overflow: hidden;
|
|
}
|
|
#info {
|
|
position: absolute;
|
|
top: 10px;
|
|
width: 100%;
|
|
text-align: center;
|
|
z-index: 100;
|
|
display:block;
|
|
}
|
|
#info a { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<div id="info">
|
|
<a href="http://github.com/mrdoob/three.js" target="_blank">three.js</a> - shadowmap - models by <a href="http://mirada.com/">mirada</a> from <a href="http://ro.me">rome</a></br>
|
|
move camera with WASD / RF + mouse
|
|
</div>
|
|
|
|
<script src="../build/Three.js"></script>
|
|
|
|
<script src="js/ShaderExtras.js"></script>
|
|
|
|
<script src="js/Detector.js"></script>
|
|
<script src="js/RequestAnimationFrame.js"></script>
|
|
<script src="js/Stats.js"></script>
|
|
|
|
<script src="fonts/helvetiker_bold.typeface.js"></script>
|
|
|
|
<script>
|
|
|
|
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
|
|
|
|
var SHADOW_MAP_WIDTH = 2048, SHADOW_MAP_HEIGHT = 1024;
|
|
|
|
var MARGIN = 100;
|
|
|
|
var SCREEN_WIDTH = window.innerWidth;
|
|
var SCREEN_HEIGHT = window.innerHeight - 2 * MARGIN;
|
|
var FLOOR = -250;
|
|
|
|
var camera, controls, scene, renderer;
|
|
var container, stats;
|
|
|
|
var NEAR = 5, FAR = 3000;
|
|
|
|
var sceneHUD, cameraOrtho, hudMaterial;
|
|
|
|
var morph, morphs = [];
|
|
|
|
var light;
|
|
|
|
var clock = new THREE.Clock();
|
|
|
|
init();
|
|
animate();
|
|
|
|
|
|
function init() {
|
|
|
|
container = document.createElement( 'div' );
|
|
document.body.appendChild( container );
|
|
|
|
// SCENE CAMERA
|
|
|
|
camera = new THREE.PerspectiveCamera( 23, SCREEN_WIDTH / SCREEN_HEIGHT, NEAR, FAR );
|
|
camera.position.set( 700, 50, 1900 );
|
|
|
|
controls = new THREE.FirstPersonControls( camera );
|
|
|
|
controls.lookSpeed = 0.0125;
|
|
controls.movementSpeed = 500;
|
|
controls.noFly = false;
|
|
controls.lookVertical = true;
|
|
controls.constrainVertical = true;
|
|
controls.verticalMin = 1.5;
|
|
controls.verticalMax = 2.0;
|
|
|
|
controls.lon = -110;
|
|
|
|
// SCENE
|
|
|
|
scene = new THREE.Scene();
|
|
scene.fog = new THREE.Fog( 0xffaa55, 1000, FAR );
|
|
THREE.ColorUtils.adjustHSV( scene.fog.color, 0.02, -0.15, -0.65 );
|
|
|
|
// LIGHTS
|
|
|
|
var ambient = new THREE.AmbientLight( 0x444444 );
|
|
scene.add( ambient );
|
|
|
|
light = new THREE.SpotLight( 0xffffff );
|
|
light.position.set( 0, 1500, 1000 );
|
|
light.target.position.set( 0, 0, 0 );
|
|
light.castShadow = true;
|
|
scene.add( light );
|
|
|
|
createHUD();
|
|
createScene();
|
|
|
|
// RENDERER
|
|
|
|
renderer = new THREE.WebGLRenderer( { clearColor: 0x000000, clearAlpha: 1, antialias: false } );
|
|
renderer.setSize( SCREEN_WIDTH, SCREEN_HEIGHT );
|
|
renderer.domElement.style.position = "relative";
|
|
renderer.domElement.style.top = MARGIN + 'px';
|
|
container.appendChild( renderer.domElement );
|
|
|
|
renderer.setClearColor( scene.fog.color, 1 );
|
|
renderer.autoClear = false;
|
|
|
|
renderer.shadowCameraNear = 3;
|
|
renderer.shadowCameraFar = camera.far;
|
|
renderer.shadowCameraFov = 50;
|
|
|
|
renderer.shadowMapBias = 0.0039;
|
|
renderer.shadowMapDarkness = 0.5;
|
|
renderer.shadowMapWidth = SHADOW_MAP_WIDTH;
|
|
renderer.shadowMapHeight = SHADOW_MAP_HEIGHT;
|
|
|
|
renderer.shadowMapEnabled = true;
|
|
renderer.shadowMapSoft = true;
|
|
|
|
// STATS
|
|
|
|
stats = new Stats();
|
|
stats.domElement.style.position = 'absolute';
|
|
stats.domElement.style.top = '0px';
|
|
stats.domElement.style.zIndex = 100;
|
|
//container.appendChild( stats.domElement );
|
|
|
|
}
|
|
|
|
function createHUD() {
|
|
|
|
cameraOrtho = new THREE.OrthographicCamera( SCREEN_WIDTH / - 2, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_HEIGHT / - 2, -10, 1000 );
|
|
cameraOrtho.position.z = 10;
|
|
|
|
var shader = THREE.ShaderExtras[ "screen" ];
|
|
var uniforms = new THREE.UniformsUtils.clone( shader.uniforms );
|
|
|
|
hudMaterial = new THREE.ShaderMaterial( { vertexShader: shader.vertexShader, fragmentShader: shader.fragmentShader, uniforms: uniforms } );
|
|
|
|
var hudGeo = new THREE.PlaneGeometry( SHADOW_MAP_WIDTH / 2, SHADOW_MAP_HEIGHT / 2 );
|
|
var hudMesh = new THREE.Mesh( hudGeo, hudMaterial );
|
|
hudMesh.position.x = ( SCREEN_WIDTH - SHADOW_MAP_WIDTH / 2 ) * -0.5;
|
|
hudMesh.position.y = ( SCREEN_HEIGHT - SHADOW_MAP_HEIGHT / 2 ) * -0.5;
|
|
|
|
sceneHUD = new THREE.Scene();
|
|
sceneHUD.add( hudMesh );
|
|
|
|
cameraOrtho.lookAt( sceneHUD.position );
|
|
|
|
}
|
|
|
|
function createScene( ) {
|
|
|
|
// GROUND
|
|
|
|
var geometry = new THREE.PlaneGeometry( 100, 100 );
|
|
var planeMaterial = new THREE.MeshLambertMaterial( { color: 0xffdd99 } );
|
|
THREE.ColorUtils.adjustHSV( planeMaterial.color, 0, 0, 0.9 );
|
|
|
|
var ground = new THREE.Mesh( geometry, planeMaterial );
|
|
|
|
ground.position.set( 0, FLOOR, 0 );
|
|
ground.rotation.x = -Math.PI/2;
|
|
ground.scale.set( 100, 100, 100 );
|
|
|
|
ground.castShadow = false;
|
|
ground.receiveShadow = true;
|
|
|
|
scene.add( ground );
|
|
|
|
// TEXT
|
|
|
|
var textGeo = new THREE.TextGeometry( "THREE.JS", {
|
|
|
|
size: 200,
|
|
height: 50,
|
|
curveSegments: 12,
|
|
|
|
font: "helvetiker",
|
|
weight: "bold",
|
|
style: "normal",
|
|
|
|
bevelThickness: 2,
|
|
bevelSize: 5,
|
|
bevelEnabled: true
|
|
|
|
});
|
|
|
|
textGeo.computeBoundingBox();
|
|
var centerOffset = -0.5 * ( textGeo.boundingBox.x[ 1 ] - textGeo.boundingBox.x[ 0 ] );
|
|
|
|
var textMaterial = new THREE.MeshPhongMaterial( { color: 0xff0000, specular: 0xffffff, ambient: 0xaa0000 } );
|
|
|
|
var mesh = new THREE.Mesh( textGeo, textMaterial );
|
|
mesh.position.x = centerOffset;
|
|
mesh.position.y = FLOOR + 67;
|
|
|
|
mesh.castShadow = true;
|
|
mesh.receiveShadow = true;
|
|
|
|
scene.add( mesh );
|
|
|
|
// CUBES
|
|
|
|
var mesh = new THREE.Mesh( new THREE.CubeGeometry( 1500, 220, 150 ), planeMaterial );
|
|
|
|
mesh.position.y = FLOOR - 50;
|
|
mesh.position.z = 20;
|
|
|
|
mesh.castShadow = true;
|
|
mesh.receiveShadow = true;
|
|
|
|
scene.add( mesh );
|
|
|
|
var mesh = new THREE.Mesh( new THREE.CubeGeometry( 1600, 170, 250 ), planeMaterial );
|
|
|
|
mesh.position.y = FLOOR - 50;
|
|
mesh.position.z = 20;
|
|
|
|
mesh.castShadow = true;
|
|
mesh.receiveShadow = true;
|
|
|
|
scene.add( mesh );
|
|
|
|
// MORPHS
|
|
|
|
function addMorph( geometry, speed, duration, x, y, z, fudgeColor ) {
|
|
|
|
var material = new THREE.MeshLambertMaterial( { color: 0xffaa55, morphTargets: true, vertexColors: THREE.FaceColors } );
|
|
|
|
if ( fudgeColor ) THREE.ColorUtils.adjustHSV( material.color, 0, 0.5 - Math.random(), 0.5 - Math.random() );
|
|
|
|
var meshAnim = new THREE.MorphAnimMesh( geometry, material );
|
|
|
|
meshAnim.speed = speed;
|
|
meshAnim.duration = duration;
|
|
meshAnim.time = 600 * Math.random();
|
|
|
|
meshAnim.position.set( x, y, z );
|
|
meshAnim.rotation.y = Math.PI/2;
|
|
|
|
meshAnim.castShadow = true;
|
|
meshAnim.receiveShadow = false;
|
|
|
|
scene.add( meshAnim );
|
|
|
|
morphs.push( meshAnim );
|
|
|
|
}
|
|
|
|
function morphColorsToFaceColors( geometry ) {
|
|
|
|
if ( geometry.morphColors && geometry.morphColors.length ) {
|
|
|
|
var colorMap = geometry.morphColors[ 0 ];
|
|
|
|
for ( var i = 0; i < colorMap.colors.length; i ++ ) {
|
|
|
|
geometry.faces[ i ].color = colorMap.colors[ i ];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
var loader = new THREE.JSONLoader();
|
|
|
|
loader.load( { model: "models/animated/horse.js", callback: function( geometry ) {
|
|
|
|
morphColorsToFaceColors( geometry );
|
|
|
|
addMorph( geometry, 0.55, 1000, 100 - Math.random() * 1000, FLOOR, 300, true );
|
|
addMorph( geometry, 0.55, 1000, 100 - Math.random() * 1000, FLOOR, 450, true );
|
|
addMorph( geometry, 0.55, 1000, 100 - Math.random() * 1000, FLOOR, 600, true );
|
|
|
|
addMorph( geometry, 0.55, 1000, 100 - Math.random() * 1000, FLOOR, -300, true );
|
|
addMorph( geometry, 0.55, 1000, 100 - Math.random() * 1000, FLOOR, -450, true );
|
|
addMorph( geometry, 0.55, 1000, 100 - Math.random() * 1000, FLOOR, -600, true );
|
|
|
|
} } );
|
|
|
|
/*
|
|
loader.load( { model: "obj/morphs/fox.js", callback: function( geometry ) {
|
|
|
|
morphColorsToFaceColors( geometry );
|
|
addMorph( geometry, 0.2, 1000, 100 - Math.random() * 500, FLOOR - 5, 600 );
|
|
|
|
} } );
|
|
|
|
loader.load( { model: "obj/morphs/shdw3walk.js", callback: function( geometry ) {
|
|
|
|
morphColorsToFaceColors( geometry );
|
|
addMorph( geometry, 0.04, 2000, -500, FLOOR + 60, 245 );
|
|
|
|
} } );
|
|
|
|
loader.load( { model: "obj/morphs/flamingo.js", callback: function( geometry ) {
|
|
|
|
morphColorsToFaceColors( geometry );
|
|
addMorph( geometry, 0.5, 1000, 500 - Math.random() * 500, FLOOR + 350, 40 );
|
|
|
|
} } );
|
|
|
|
loader.load( { model: "obj/morphs/stork.js", callback: function( geometry ) {
|
|
|
|
morphColorsToFaceColors( geometry );
|
|
addMorph( geometry, 0.35, 1000, 500 - Math.random() * 500, FLOOR + 350, 340 );
|
|
|
|
} } );
|
|
|
|
loader.load( { model: "obj/morphs/mountainlion.js", callback: function( geometry ) {
|
|
|
|
morphColorsToFaceColors( geometry );
|
|
addMorph( geometry, 0.4, 1000, 500 - Math.random() * 500, FLOOR - 5, 700 );
|
|
|
|
} } );
|
|
|
|
loader.load( { model: "obj/morphs/bearBrown.js", callback: function( geometry ) {
|
|
|
|
morphColorsToFaceColors( geometry );
|
|
addMorph( geometry, 0.3, 2500, -500, FLOOR - 5, -750 );
|
|
|
|
} } );
|
|
|
|
loader.load( { model: "obj/morphs/parrot.js", callback: function( geometry ) {
|
|
|
|
morphColorsToFaceColors( geometry );
|
|
addMorph( geometry, 0.45, 500, 500 - Math.random() * 500, FLOOR + 300, 700 );
|
|
|
|
} } );
|
|
*/
|
|
|
|
}
|
|
|
|
//
|
|
|
|
function animate() {
|
|
|
|
requestAnimationFrame( animate );
|
|
|
|
render();
|
|
stats.update();
|
|
|
|
}
|
|
|
|
function render() {
|
|
|
|
var delta = clock.delta();
|
|
|
|
for ( var i = 0; i < morphs.length; i ++ ) {
|
|
|
|
morph = morphs[ i ];
|
|
|
|
morph.updateAnimation( delta );
|
|
|
|
morph.position.x += morph.speed * delta;
|
|
|
|
if ( morph.position.x > 2000 ) {
|
|
|
|
morph.position.x = -1000 - Math.random() * 500;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
controls.update();
|
|
|
|
renderer.clear();
|
|
renderer.render( scene, camera );
|
|
|
|
// Render debug HUD with shadow map
|
|
|
|
//hudMaterial.uniforms.tDiffuse.texture = renderer.shadowMap[ 0 ];
|
|
//renderer.render( sceneHUD, cameraOrtho );
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
</body>
|
|
</html>
|