提交 54abb899 编写于 作者: Z zz85

Merge remote-tracking branch 'alteredq/experimental' into experimental

因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -44,7 +44,7 @@ THREE.Matrix4.makeInvert3x3=function(a){var b=a.m33,c=b.m,d=a.n33*a.n22-a.n32*a.
THREE.Matrix4.makeFrustum=function(a,b,c,d,f,g){var e;e=new THREE.Matrix4;e.n11=2*f/(b-a);e.n12=0;e.n13=(b+a)/(b-a);e.n14=0;e.n21=0;e.n22=2*f/(d-c);e.n23=(d+c)/(d-c);e.n24=0;e.n31=0;e.n32=0;e.n33=-(g+f)/(g-f);e.n34=-2*g*f/(g-f);e.n41=0;e.n42=0;e.n43=-1;e.n44=0;return e};THREE.Matrix4.makePerspective=function(a,b,c,d){var f,a=c*Math.tan(a*Math.PI/360);f=-a;return THREE.Matrix4.makeFrustum(f*b,a*b,f,a,c,d)};
THREE.Matrix4.makeOrtho=function(a,b,c,d,f,g){var e,h,i,l;e=new THREE.Matrix4;h=b-a;i=c-d;l=g-f;e.n11=2/h;e.n12=0;e.n13=0;e.n14=-((b+a)/h);e.n21=0;e.n22=2/i;e.n23=0;e.n24=-((c+d)/i);e.n31=0;e.n32=0;e.n33=-2/l;e.n34=-((g+f)/l);e.n41=0;e.n42=0;e.n43=0;e.n44=1;return e};THREE.Matrix4.__v1=new THREE.Vector3;THREE.Matrix4.__v2=new THREE.Vector3;THREE.Matrix4.__v3=new THREE.Vector3;
THREE.Object3D=function(){this.parent=void 0;this.children=[];this.up=new THREE.Vector3(0,1,0);this.position=new THREE.Vector3;this.rotation=new THREE.Vector3;this.eulerOrder="XYZ";this.scale=new THREE.Vector3(1,1,1);this.flipSided=this.doubleSided=this.dynamic=!1;this.renderDepth=null;this.rotationAutoUpdate=!0;this.matrix=new THREE.Matrix4;this.matrixWorld=new THREE.Matrix4;this.matrixRotationWorld=new THREE.Matrix4;this.matrixWorldNeedsUpdate=this.matrixAutoUpdate=!0;this.quaternion=new THREE.Quaternion;
this.useQuaternion=!1;this.boundRadius=0;this.boundRadiusScale=1;this.visible=!0;this._vector=new THREE.Vector3;this.name=""};
this.useQuaternion=!1;this.boundRadius=0;this.boundRadiusScale=1;this.visible=!0;this.receiveShadow=this.castShadow=!1;this._vector=new THREE.Vector3;this.name=""};
THREE.Object3D.prototype={translate:function(a,b){this.matrix.rotateAxis(b);this.position.addSelf(b.multiplyScalar(a))},translateX:function(a){this.translate(a,this._vector.set(1,0,0))},translateY:function(a){this.translate(a,this._vector.set(0,1,0))},translateZ:function(a){this.translate(a,this._vector.set(0,0,1))},lookAt:function(a){this.matrix.lookAt(a,this.position,this.up);this.rotationAutoUpdate&&this.rotation.setRotationFromMatrix(this.matrix)},addChild:function(a){if(this.children.indexOf(a)===
-1){a.parent!==void 0&&a.parent.removeChild(a);a.parent=this;this.children.push(a);for(var b=this;b.parent!==void 0;)b=b.parent;b!==void 0&&b instanceof THREE.Scene&&b.addChildRecurse(a)}},removeChild:function(a){var b=this.children.indexOf(a);if(b!==-1)a.parent=void 0,this.children.splice(b,1)},getChildByName:function(a,b){var c,d,f;c=0;for(d=this.children.length;c<d;c++){f=this.children[c];if(f.name===a)return f;if(b&&(f=f.getChildByName(a,b),f!==void 0))return f}},updateMatrix:function(){this.matrix.setPosition(this.position);
this.useQuaternion?this.matrix.setRotationFromQuaternion(this.quaternion):this.matrix.setRotationFromEuler(this.rotation,this.eulerOrder);if(this.scale.x!==1||this.scale.y!==1||this.scale.z!==1)this.matrix.scale(this.scale),this.boundRadiusScale=Math.max(this.scale.x,Math.max(this.scale.y,this.scale.z));this.matrixWorldNeedsUpdate=!0},update:function(a,b,c){this.matrixAutoUpdate&&this.updateMatrix();if(this.matrixWorldNeedsUpdate||b)a?this.matrixWorld.multiply(a,this.matrix):this.matrixWorld.copy(this.matrix),
......
......@@ -44,7 +44,7 @@ THREE.Matrix4.makeInvert3x3=function(a){var b=a.m33,c=b.m,d=a.n33*a.n22-a.n32*a.
THREE.Matrix4.makeFrustum=function(a,b,c,d,e,g){var f;f=new THREE.Matrix4;f.n11=2*e/(b-a);f.n12=0;f.n13=(b+a)/(b-a);f.n14=0;f.n21=0;f.n22=2*e/(d-c);f.n23=(d+c)/(d-c);f.n24=0;f.n31=0;f.n32=0;f.n33=-(g+e)/(g-e);f.n34=-2*g*e/(g-e);f.n41=0;f.n42=0;f.n43=-1;f.n44=0;return f};THREE.Matrix4.makePerspective=function(a,b,c,d){var e,a=c*Math.tan(a*Math.PI/360);e=-a;return THREE.Matrix4.makeFrustum(e*b,a*b,e,a,c,d)};
THREE.Matrix4.makeOrtho=function(a,b,c,d,e,g){var f,h,j,i;f=new THREE.Matrix4;h=b-a;j=c-d;i=g-e;f.n11=2/h;f.n12=0;f.n13=0;f.n14=-((b+a)/h);f.n21=0;f.n22=2/j;f.n23=0;f.n24=-((c+d)/j);f.n31=0;f.n32=0;f.n33=-2/i;f.n34=-((g+e)/i);f.n41=0;f.n42=0;f.n43=0;f.n44=1;return f};THREE.Matrix4.__v1=new THREE.Vector3;THREE.Matrix4.__v2=new THREE.Vector3;THREE.Matrix4.__v3=new THREE.Vector3;
THREE.Object3D=function(){this.parent=void 0;this.children=[];this.up=new THREE.Vector3(0,1,0);this.position=new THREE.Vector3;this.rotation=new THREE.Vector3;this.eulerOrder="XYZ";this.scale=new THREE.Vector3(1,1,1);this.flipSided=this.doubleSided=this.dynamic=!1;this.renderDepth=null;this.rotationAutoUpdate=!0;this.matrix=new THREE.Matrix4;this.matrixWorld=new THREE.Matrix4;this.matrixRotationWorld=new THREE.Matrix4;this.matrixWorldNeedsUpdate=this.matrixAutoUpdate=!0;this.quaternion=new THREE.Quaternion;
this.useQuaternion=!1;this.boundRadius=0;this.boundRadiusScale=1;this.visible=!0;this._vector=new THREE.Vector3;this.name=""};
this.useQuaternion=!1;this.boundRadius=0;this.boundRadiusScale=1;this.visible=!0;this.receiveShadow=this.castShadow=!1;this._vector=new THREE.Vector3;this.name=""};
THREE.Object3D.prototype={translate:function(a,b){this.matrix.rotateAxis(b);this.position.addSelf(b.multiplyScalar(a))},translateX:function(a){this.translate(a,this._vector.set(1,0,0))},translateY:function(a){this.translate(a,this._vector.set(0,1,0))},translateZ:function(a){this.translate(a,this._vector.set(0,0,1))},lookAt:function(a){this.matrix.lookAt(a,this.position,this.up);this.rotationAutoUpdate&&this.rotation.setRotationFromMatrix(this.matrix)},addChild:function(a){if(this.children.indexOf(a)===
-1){a.parent!==void 0&&a.parent.removeChild(a);a.parent=this;this.children.push(a);for(var b=this;b.parent!==void 0;)b=b.parent;b!==void 0&&b instanceof THREE.Scene&&b.addChildRecurse(a)}},removeChild:function(a){var b=this.children.indexOf(a);if(b!==-1)a.parent=void 0,this.children.splice(b,1)},getChildByName:function(a,b){var c,d,e;c=0;for(d=this.children.length;c<d;c++){e=this.children[c];if(e.name===a)return e;if(b&&(e=e.getChildByName(a,b),e!==void 0))return e}},updateMatrix:function(){this.matrix.setPosition(this.position);
this.useQuaternion?this.matrix.setRotationFromQuaternion(this.quaternion):this.matrix.setRotationFromEuler(this.rotation,this.eulerOrder);if(this.scale.x!==1||this.scale.y!==1||this.scale.z!==1)this.matrix.scale(this.scale),this.boundRadiusScale=Math.max(this.scale.x,Math.max(this.scale.y,this.scale.z));this.matrixWorldNeedsUpdate=!0},update:function(a,b,c){this.matrixAutoUpdate&&this.updateMatrix();if(this.matrixWorldNeedsUpdate||b)a?this.matrixWorld.multiply(a,this.matrix):this.matrixWorld.copy(this.matrix),
......
此差异已折叠。
......@@ -44,7 +44,7 @@ THREE.Matrix4.makeInvert3x3=function(a){var b=a.m33,c=b.m,d=a.n33*a.n22-a.n32*a.
THREE.Matrix4.makeFrustum=function(a,b,c,d,e,g){var f;f=new THREE.Matrix4;f.n11=2*e/(b-a);f.n12=0;f.n13=(b+a)/(b-a);f.n14=0;f.n21=0;f.n22=2*e/(d-c);f.n23=(d+c)/(d-c);f.n24=0;f.n31=0;f.n32=0;f.n33=-(g+e)/(g-e);f.n34=-2*g*e/(g-e);f.n41=0;f.n42=0;f.n43=-1;f.n44=0;return f};THREE.Matrix4.makePerspective=function(a,b,c,d){var e,a=c*Math.tan(a*Math.PI/360);e=-a;return THREE.Matrix4.makeFrustum(e*b,a*b,e,a,c,d)};
THREE.Matrix4.makeOrtho=function(a,b,c,d,e,g){var f,h,k,l;f=new THREE.Matrix4;h=b-a;k=c-d;l=g-e;f.n11=2/h;f.n12=0;f.n13=0;f.n14=-((b+a)/h);f.n21=0;f.n22=2/k;f.n23=0;f.n24=-((c+d)/k);f.n31=0;f.n32=0;f.n33=-2/l;f.n34=-((g+e)/l);f.n41=0;f.n42=0;f.n43=0;f.n44=1;return f};THREE.Matrix4.__v1=new THREE.Vector3;THREE.Matrix4.__v2=new THREE.Vector3;THREE.Matrix4.__v3=new THREE.Vector3;
THREE.Object3D=function(){this.parent=void 0;this.children=[];this.up=new THREE.Vector3(0,1,0);this.position=new THREE.Vector3;this.rotation=new THREE.Vector3;this.eulerOrder="XYZ";this.scale=new THREE.Vector3(1,1,1);this.flipSided=this.doubleSided=this.dynamic=!1;this.renderDepth=null;this.rotationAutoUpdate=!0;this.matrix=new THREE.Matrix4;this.matrixWorld=new THREE.Matrix4;this.matrixRotationWorld=new THREE.Matrix4;this.matrixWorldNeedsUpdate=this.matrixAutoUpdate=!0;this.quaternion=new THREE.Quaternion;
this.useQuaternion=!1;this.boundRadius=0;this.boundRadiusScale=1;this.visible=!0;this._vector=new THREE.Vector3;this.name=""};
this.useQuaternion=!1;this.boundRadius=0;this.boundRadiusScale=1;this.visible=!0;this.receiveShadow=this.castShadow=!1;this._vector=new THREE.Vector3;this.name=""};
THREE.Object3D.prototype={translate:function(a,b){this.matrix.rotateAxis(b);this.position.addSelf(b.multiplyScalar(a))},translateX:function(a){this.translate(a,this._vector.set(1,0,0))},translateY:function(a){this.translate(a,this._vector.set(0,1,0))},translateZ:function(a){this.translate(a,this._vector.set(0,0,1))},lookAt:function(a){this.matrix.lookAt(a,this.position,this.up);this.rotationAutoUpdate&&this.rotation.setRotationFromMatrix(this.matrix)},addChild:function(a){if(this.children.indexOf(a)===
-1){a.parent!==void 0&&a.parent.removeChild(a);a.parent=this;this.children.push(a);for(var b=this;b.parent!==void 0;)b=b.parent;b!==void 0&&b instanceof THREE.Scene&&b.addChildRecurse(a)}},removeChild:function(a){var b=this.children.indexOf(a);if(b!==-1)a.parent=void 0,this.children.splice(b,1)},getChildByName:function(a,b){var c,d,e;c=0;for(d=this.children.length;c<d;c++){e=this.children[c];if(e.name===a)return e;if(b&&(e=e.getChildByName(a,b),e!==void 0))return e}},updateMatrix:function(){this.matrix.setPosition(this.position);
this.useQuaternion?this.matrix.setRotationFromQuaternion(this.quaternion):this.matrix.setRotationFromEuler(this.rotation,this.eulerOrder);if(this.scale.x!==1||this.scale.y!==1||this.scale.z!==1)this.matrix.scale(this.scale),this.boundRadiusScale=Math.max(this.scale.x,Math.max(this.scale.y,this.scale.z));this.matrixWorldNeedsUpdate=!0},update:function(a,b,c){this.matrixAutoUpdate&&this.updateMatrix();if(this.matrixWorldNeedsUpdate||b)a?this.matrixWorld.multiply(a,this.matrix):this.matrixWorld.copy(this.matrix),
......
因为 它太大了无法显示 source diff 。你可以改为 查看blob
......@@ -20,11 +20,11 @@
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
<script type="text/javascript" src="js/Stats.js"></script>
<!-- load the font file from canvas-text -->
<script type="text/javascript" src="fonts/helvetiker_regular.typeface.js"></script>
<script type="text/javascript">
......@@ -69,47 +69,44 @@
// Get text from hash
var theText = "Hello three.js! :)";
var hash = document.location.hash.substr( 1 );
if ( hash.length !== 0 ) {
theText = hash;
}
var text3d = new THREE.TextGeometry( theText, {
size: 80,
var text3d = new THREE.TextGeometry( theText, {
size: 80,
height: 20,
curveSegments: 2,
font: "helvetiker"
});
var textMaterial = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, wireframe:false } );
text3d.computeBoundingBox();
var centerOffset = -0.5 * ( text3d.boundingBox.x[ 1 ] - text3d.boundingBox.x[ 0 ] );
var textMaterial = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, wireframe: false } );
text = new THREE.Mesh( text3d, textMaterial );
text.doubleSided = false;
text.position.y = 0;
text.position.x = centerOffset;
text.position.y = 100;
text.position.z = 0;
text.rotation.x = 0;
text.rotation.y = Math.PI*2;
text.rotation.y = Math.PI * 2;
text.overdraw = true;
scene.addObject( text );
// Plane
plane = new THREE.Mesh( new THREE.PlaneGeometry( 800, 800 ), new THREE.MeshBasicMaterial( { color: 0xe0e0e0, wireframe:true }) );
plane.rotation.x = - 90 * ( Math.PI / 180 );
plane.position.x = 0;
plane.overdraw = true;
parent = new THREE.Object3D();
parent.addChild( text );
//scene.addObject( plane );
scene.addObject( parent );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
......@@ -205,7 +202,7 @@
function render() {
plane.rotation.z = text.rotation.y += ( targetRotation - text.rotation.y ) * 0.05;
parent.rotation.y += ( targetRotation - parent.rotation.y ) * 0.05;
renderer.render( scene, camera );
}
......
......@@ -84,6 +84,7 @@
bevelThickness = 2,
bevelSize = 1.5,
bevelSegments = 3,
bevelEnabled = true,
font = "optimer", // helvetiker, optimer, gentilis, droid sans, droid serif
......@@ -204,55 +205,15 @@
}
textGeo = new THREE.TextGeometry( text, {
size: size,
height: height,
curveSegments: curveSegments,
font: font,
weight: weight,
style: style,
bevelThickness: bevelThickness,
bevelSize: bevelSize,
bevelEnabled: bevelEnabled
});
textMaterial = new THREE.MeshPhongMaterial( { color: 0xffffff, wireframe: false } );
parent = new THREE.Object3D();
textMesh1 = new THREE.Mesh( textGeo, textMaterial );
textMesh1.position.x = 0;
textMesh1.position.y = hover;
textMesh1.position.z = 0;
textMesh1.rotation.x = 0;
textMesh1.rotation.y = Math.PI * 2;
parent.addChild( textMesh1 );
if ( mirror ) {
textMesh2 = new THREE.Mesh( textGeo, textMaterial );
textMesh2.position.x = 0;
textMesh2.position.y = -hover;
textMesh2.position.z = height;
textMesh2.rotation.x = Math.PI;
textMesh2.rotation.y = Math.PI * 2;
parent.addChild( textMesh2 );
}
parent.position.y = 100;
scene.addChild( parent );
createText();
var plane = new THREE.Mesh( new THREE.PlaneGeometry( 10000, 10000 ), new THREE.MeshBasicMaterial( { color: 0xffffff, opacity: 0.5, transparent: true } ) );
plane.rotation.x = -1.57;
plane.position.y = 100;
......@@ -414,11 +375,7 @@
}
function refreshText() {
updatePermalink();
scene.removeChild( textMesh1 );
function createText() {
textGeo = new THREE.TextGeometry( text, {
......@@ -436,9 +393,12 @@
});
textGeo.computeBoundingBox();
var centerOffset = -0.5 * ( textGeo.boundingBox.x[ 1 ] - textGeo.boundingBox.x[ 0 ] );
textMesh1 = new THREE.Mesh( textGeo, textMaterial );
textMesh1.position.x = 0;
textMesh1.position.x = centerOffset;
textMesh1.position.y = hover;
textMesh1.position.z = 0;
......@@ -449,24 +409,34 @@
if ( mirror ) {
scene.removeChild( textMesh2 );
textMesh2 = new THREE.Mesh( textGeo, textMaterial );
textMesh2.position.x = 0;
textMesh2.position.x = centerOffset;
textMesh2.position.y = -hover;
textMesh2.position.z = height;
textMesh2.rotation.x = Math.PI;
textMesh2.rotation.y = Math.PI * 2;
parent.addChild( textMesh2 );
}
}
function refreshText() {
updatePermalink();
scene.removeChild( textMesh1 );
if ( mirror ) scene.removeChild( textMesh2 );
if ( !text ) return;
createText();
}
function onDocumentMouseDown( event ) {
event.preventDefault();
......
<!DOCTYPE HTML>
<html lang="en">
<head>
<title>three.js webgl - shadow map</title>
<meta charset="utf-8">
<style type="text/css">
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 type="text/javascript" src="../build/Three.js"></script>
<script type="text/javascript" src="js/Detector.js"></script>
<script type="text/javascript" src="js/RequestAnimationFrame.js"></script>
<script type="text/javascript" src="js/Stats.js"></script>
<script type="text/javascript" src="fonts/helvetiker_bold.typeface.js"></script>
<script type="text/javascript">
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var SHADOW_MAP_WIDTH = 1024, SHADOW_MAP_HEIGHT = 1024;
var MARGIN = 100;
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight - 2 * MARGIN;
var FLOOR = -250;
var camera, scene, renderer;
var container, stats;
var NEAR = 5, FAR = 3000;
var sceneHUD, cameraOrtho, hudMaterial;
var initPos = new THREE.Vector3( 700, 50, 1900 );
var initLight = new THREE.Vector3( 0, 1500, 1000 );
var deltaCam = new THREE.Vector3();
var morphs = [];
var light;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
// SCENE CAMERA
camera = new THREE.FirstPersonCamera( { fov: 23, aspect: SCREEN_WIDTH / SCREEN_HEIGHT, near: NEAR, far: FAR,
lookSpeed: 0.0125, movementSpeed: 500, noFly: false, lookVertical: true,
constrainVertical: true, verticalMin: 1.5, verticalMax: 2.0
} );
camera.position.set( 700, 50, 1900 );
camera.lon = -110;
// SHADOW TEXTURE
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
shadowTexture = new THREE.WebGLRenderTarget( SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, pars );
// 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.addLight( ambient );
light = new THREE.SpotLight( 0xffffff );
light.position.set( 0, 1500, 1000 );
light.target.position.set( 0, 0, 0 );
light.castShadow = true;
scene.addLight( 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.Camera( 45, SHADOW_MAP_WIDTH / SHADOW_MAP_HEIGHT, NEAR, FAR );
cameraOrtho.projectionMatrix = THREE.Matrix4.makeOrtho( SCREEN_WIDTH / - 2, SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, SCREEN_HEIGHT / - 2, -10, 1000 );
cameraOrtho.position.z = 10;
var shader = THREE.ShaderUtils.lib[ "screen" ];
var uniforms = new THREE.UniformsUtils.clone( shader.uniforms );
hudMaterial = new THREE.MeshShaderMaterial( { 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.addObject( hudMesh );
}
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 = -1.57;
ground.scale.set( 100, 100, 100 );
ground.castShadow = false;
ground.receiveShadow = true;
scene.addObject( ground );
// TEXT
var textGeo = new THREE.TextGeometry( "THREE.JS", {
size: 200,
height: 50,
curveSegments: 7,
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.addObject( 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.addObject( 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.addObject( 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.Mesh( geometry, material );
meshAnim.position.set( x, y, z );
meshAnim.rotation.y = 1.57;
meshAnim.castShadow = true;
meshAnim.receiveShadow = false;
scene.addObject( meshAnim );
morphs.push( { mesh: meshAnim, lastKeyframe: 0, currentKeyframe: 0,
offset: Math.random() * 6, speed: speed, duration: duration,
oldTime: new Date().getTime() } );
}
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 );
} } );
*/
}
var t = 0, newTime, delta;
function updateMorph( morph ) {
// Alternate morph targets
var interpolation = morph.duration / ( morph.mesh.geometry.morphTargets.length - 1 );
var time = ( new Date().getTime() + morph.offset * 100 ) % morph.duration;
var keyframe = Math.floor( time / interpolation ) + 1;
var mesh = morph.mesh;
if ( keyframe != morph.currentKeyframe ) {
mesh.morphTargetInfluences[ morph.lastKeyframe ] = 0;
mesh.morphTargetInfluences[ morph.currentKeyframe ] = 1;
mesh.morphTargetInfluences[ keyframe ] = 0;
morph.lastKeyframe = morph.currentKeyframe;
morph.currentKeyframe = keyframe;
}
mesh.morphTargetInfluences[ keyframe ] = ( time % interpolation ) / interpolation;
mesh.morphTargetInfluences[ morph.lastKeyframe ] = 1 - mesh.morphTargetInfluences[ keyframe ];
var newTime = new Date().getTime();
delta = newTime - morph.oldTime;
morph.oldTime = newTime;
mesh.position.x += morph.speed * delta;
if ( mesh.position.x > 2000 ) {
mesh.position.x = -1000 - Math.random() * 500;
}
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
for ( var i = 0; i < morphs.length; i++ ) updateMorph( morphs[ i ] );
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>
......@@ -17,7 +17,7 @@ THREE.Object3D = function() {
this.scale = new THREE.Vector3( 1, 1, 1 );
this.dynamic = false; // when true it retains arrays so they can be updated with __dirty*
this.doubleSided = false;
this.flipSided = false;
......@@ -40,6 +40,9 @@ THREE.Object3D = function() {
this.visible = true;
this.castShadow = false;
this.receiveShadow = false;
this._vector = new THREE.Vector3();
this.name = "";
......
......@@ -253,11 +253,20 @@ THREE.FirstPersonCamera = function ( parameters ) {
}
var verticalLookRatio = 1;
if ( this.constrainVertical ) {
verticalLookRatio = 3.14 / ( this.verticalMax - this.verticalMin );
}
this.lon += this.mouseX * actualLookSpeed;
if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed;
if( this.lookVertical ) this.lat -= this.mouseY * actualLookSpeed * verticalLookRatio;
this.lat = Math.max( - 85, Math.min( 85, this.lat ) );
this.phi = ( 90 - this.lat ) * Math.PI / 180;
this.theta = this.lon * Math.PI / 180;
if ( this.constrainVertical ) {
......
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
*
* Creates extruded geometry from a path shape.
**/
*
* parameters = {
* size: <float>, // size of the text
* height: <float>, // thickness to extrude text
* curveSegments: <int>, // number of points on the curves
*
* font: <string>, // font name
* weight: <string>, // font weight (normal, bold)
* style: <string>, // font style (normal, italics)
*
* bevelEnabled: <bool>, // turn on bevel
* bevelThickness: <float>, // how deep into text bevel goes
* bevelSize: <float>, // how far from text outline is bevel
* bevelSegments: <int>, // number of bevel layers
* }
**/
THREE.ExtrudeGeometry = function( shapes, options ) {
if( typeof( shapes ) == "undefined" ) {
shapes = [];
return;
}
THREE.Geometry.call( this );
shapes = shapes instanceof Array ? shapes : [ shapes ];
var s=0, sl = shapes.length, shape;
for (;s<sl;s++) {
shape = shapes[s];
var s, sl = shapes.length, shape;
for ( s = 0; s < sl; s ++ ) {
shape = shapes[ s ];
//console.log(shape);
this.addShape( shape, options );
}
};
THREE.ExtrudeGeometry.prototype = new THREE.Geometry();
THREE.ExtrudeGeometry.prototype = new THREE.Geometry();
THREE.ExtrudeGeometry.prototype.constructor = THREE.ExtrudeGeometry;
THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
var amount = options.amount !== undefined ? options.amount : 100;
var bevelThickness = options.bevelThickness !== undefined ? options.bevelThickness : 6; // 10
var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8
var bevelSize = options.bevelSize !== undefined ? options.bevelSize : bevelThickness - 2; // 8
var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
var bevelEnabled = options.bevelEnabled !== undefined ? options.bevelEnabled : true; // false
var bevelSegments = options.bevelSegments !== undefined ? options.bevelSegments : 3;
// We should set bevel segments to 0 if bevel is not enabled.
// (also bevelThickness and bevelSize make mess when bevel is not enabled,
// whole shape gets thicker)
if ( !bevelEnabled ) bevelSegments = 0;
if ( !bevelEnabled ) {
bevelSegments = 0;
bevelThickness = 0;
bevelSize = 0;
}
var steps = options.steps !== undefined ? options.steps : 1;
......@@ -66,7 +93,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
var ahole, h, hl; // looping of holes
var scope = this;
var bevelPoints = [];
var shapesOffset = this.vertices.length;
//extractAllPoints
......@@ -169,138 +196,138 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
}
function scalePt2 (pt, vec, size ) {
function scalePt2 ( pt, vec, size ) {
//return vec.clone().multiplyScalar( size ).addSelf( pt );
return pt.clone().addSelf(vec.clone().multiplyScalar( size ));
return pt.clone().addSelf( vec.clone().multiplyScalar( size ) );
}
var b, bs, t, z,
vert, vlen = vertices.length,
face, flen = faces.length,
cont, clen = contour.length;
//------
// Find directions for point movement
//
var RAD_TO_DEGREES = 180 / Math.PI;
function getBevelVec(pt_i, pt_j, pt_k) {
var anglea = Math.atan2(pt_j.y - pt_i.y, pt_j.x - pt_i.x);
var angleb = Math.atan2(pt_k.y - pt_i.y, pt_k.x - pt_i.x);
if ( anglea > angleb) {
angleb += Math.PI*2;
function getBevelVec( pt_i, pt_j, pt_k ) {
var anglea = Math.atan2( pt_j.y - pt_i.y, pt_j.x - pt_i.x );
var angleb = Math.atan2( pt_k.y - pt_i.y, pt_k.x - pt_i.x );
if ( anglea > angleb ) {
angleb += Math.PI * 2;
}
// var anglea = Math.atan2(pt_i.y - pt_j.y, pt_i.x - pt_j.x);
// var angleb = Math.atan2(pt_i.y - pt_k.y, pt_i.x - pt_k.x);
// console.log('>?', anglea > angleb);
//
//
// if ( anglea < angleb) {
// angleb += Math.PI*2;
// }
//x = Math.cos(anglea) + Math.cos(angleb);
//y = Math.sin(anglea) + Math.sin(angleb);
//anglec = Math.atan2(y,x);
anglec = (anglea + angleb ) / 2;
anglec = ( anglea + angleb ) / 2;
//console.log('angle1', anglea * RAD_TO_DEGREES,'angle2', angleb * RAD_TO_DEGREES, 'anglec', anglec *RAD_TO_DEGREES);
var x = -Math.cos(anglec);
var y = -Math.sin(anglec);
var vec = new THREE.Vector2(x,y).normalize();
var x = - Math.cos( anglec );
var y = - Math.sin( anglec );
var vec = new THREE.Vector2( x, y ).normalize();
return vec;
}
var contourMovements = [];
for ( i = 0, il = contour.length, j = il-1, k = i + 1; i < il; i++,j++,k++ ) {
if (j==il) j = 0;
if (k==il) k = 0;
for ( i = 0, il = contour.length, j = il-1, k = i + 1; i < il; i++, j++, k++ ) {
if ( j == il ) j = 0;
if ( k == il ) k = 0;
// (j)---(i)---(k)
// console.log('i,j,k', i, j , k)
var pt_i = contour[ i ];
var pt_j = contour[ j ];
var pt_k = contour[ k ];
contourMovements[i]= getBevelVec(contour[ i ], contour[ j ], contour[ k ] );
contourMovements[ i ]= getBevelVec( contour[ i ], contour[ j ], contour[ k ] );
}
var holesMovements = [], oneHoleMovements, verticesMovements = contourMovements.concat();
for ( h = 0, hl = holes.length; h < hl; h++ ) {
ahole = holes[h];
ahole = holes[ h ];
oneHoleMovements = [];
for ( i = 0, il = ahole.length, j = il-1, k = i + 1; i < il; i++,j++,k++ ) {
if (j==il) j = 0;
if (k==il) k = 0;
for ( i = 0, il = ahole.length, j = il - 1, k = i + 1; i < il; i++, j++, k++ ) {
if ( j == il ) j = 0;
if ( k == il ) k = 0;
// (j)---(i)---(k)
oneHoleMovements[i]= getBevelVec(ahole[ i ], ahole[ j ], ahole[ k ] );
oneHoleMovements[ i ]= getBevelVec( ahole[ i ], ahole[ j ], ahole[ k ] );
}
holesMovements.push(oneHoleMovements);
verticesMovements = verticesMovements.concat(oneHoleMovements);
holesMovements.push( oneHoleMovements );
verticesMovements = verticesMovements.concat( oneHoleMovements );
}
// Loop bevelSegments, 1 for the front, 1 for the back
for ( b = 0; b < bevelSegments; b ++ ) {
//for ( b = bevelSegments; b > 0; b -- ) {
t = b / bevelSegments;
z = bevelThickness * ( 1-t);
z = bevelThickness * ( 1 - t );
//z = bevelThickness * t;
bs = bevelSize * (Math.sin ((t) * Math.PI/2 )) ; // curved
bs = bevelSize * ( Math.sin ( t * Math.PI/2 ) ) ; // curved
//bs = bevelSize * t ; // linear
// contract shape
for ( i = 0, il = contour.length; i < il; i++ ) {
vert = scalePt2(contour[i], contourMovements[i], bs);
//vert = scalePt( contour[ i ], contourCentroid, bs, false );
v( vert.x, vert.y, - z);
for ( i = 0, il = contour.length; i < il; i ++ ) {
vert = scalePt2( contour[ i ], contourMovements[ i ], bs );
//vert = scalePt( contour[ i ], contourCentroid, bs, false );
v( vert.x, vert.y, - z );
}
// expand holes
for ( h = 0, hl = holes.length; h < hl; h++ ) {
ahole = holes[h];
oneHoleMovements = holesMovements[h];
ahole = holes[ h ];
oneHoleMovements = holesMovements[ h ];
for ( i = 0, il = ahole.length; i < il; i++ ) {
vert = scalePt2(ahole[i], oneHoleMovements[i], bs);
vert = scalePt2( ahole[ i ], oneHoleMovements[ i ], bs );
//vert = scalePt( ahole[ i ], holesCentroids[ h ], bs, true );
v( vert.x, vert.y, -z );
......@@ -318,7 +345,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
for ( i = 0; i < vlen; i ++ ) {
//vert = vertices[ i ];
vert = scalePt2(vertices[ i ], verticesMovements[i], bs);
vert = scalePt2( vertices[ i ], verticesMovements[ i ], bs );
if ( !extrudeByPath ) {
......@@ -345,7 +372,7 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
vert = scalePt2(vertices[ i ], verticesMovements[i], bs);
if ( !extrudeByPath ) {
v( vert.x, vert.y, amount / steps * s );
} else {
......@@ -362,16 +389,16 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
// Add bevel segments planes
//for ( b = 1; b <= bevelSegments; b ++ ) {
for ( b = bevelSegments-1; b >= 0; b -- ) {
for ( b = bevelSegments - 1; b >= 0; b -- ) {
t = b / bevelSegments;
z = bevelThickness * (1-t);
z = bevelThickness * ( 1 - t );
//bs = bevelSize * ( 1-Math.sin ( ( 1 - t ) * Math.PI/2 ) );
bs = bevelSize * Math.sin ( t * Math.PI/2 ) ;
// contract shape
for ( i = 0, il = contour.length; i < il; i++ ) {
for ( i = 0, il = contour.length; i < il; i ++ ) {
vert = scalePt2(contour[i], contourMovements[i], bs);
//vert = scalePt( contour[ i ], contourCentroid, bs, false );
......@@ -381,10 +408,10 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
// expand holes
for ( h = 0, hl = holes.length; h < hl; h++ ) {
for ( h = 0, hl = holes.length; h < hl; h ++ ) {
ahole = holes[ h ];
oneHoleMovements = holesMovements[h];
oneHoleMovements = holesMovements[ h ];
for ( i = 0, il = ahole.length; i < il; i++ ) {
......@@ -526,17 +553,17 @@ THREE.ExtrudeGeometry.prototype.addShape = function( shape, options ) {
}
function f3( a, b, c ) {
a += shapesOffset;
b += shapesOffset;
c += shapesOffset;
scope.faces.push( new THREE.Face3( a, b, c ) );
}
function f4( a, b, c, d ) {
a += shapesOffset;
b += shapesOffset;
c += shapesOffset;
......
......@@ -699,8 +699,9 @@ THREE.Path.prototype.debug = function( canvas ) {
};
// Breaks path into shapes
THREE.Path.prototype.toShapes = function() {
var i, il, item, action, args;
var subPaths = [], lastPath = new THREE.Path();
......@@ -711,79 +712,97 @@ THREE.Path.prototype.toShapes = function() {
args = item.args;
action = item.action;
if (action==THREE.PathActions.MOVE_TO) {
if (lastPath.actions.length!=0) {
subPaths.push(lastPath);
if ( action == THREE.PathActions.MOVE_TO ) {
if ( lastPath.actions.length != 0 ) {
subPaths.push( lastPath );
lastPath = new THREE.Path();
}
}
lastPath[action].apply( lastPath, args);
lastPath[ action ].apply( lastPath, args );
}
if (lastPath.actions.length!=0) {
subPaths.push(lastPath);
if ( lastPath.actions.length != 0 ) {
subPaths.push( lastPath );
}
//console.log(subPaths);
if (subPaths.length ==0) return [];
var holesFirst = !THREE.Shape.Utils.isClockWise(subPaths[0].getPoints());
var tmpShape, shapes = [];
var tmpPath;
if ( subPaths.length ==0 ) return [];
var holesFirst = !THREE.Shape.Utils.isClockWise( subPaths[ 0 ].getPoints() );
var tmpPath, tmpShape, shapes = [];
//console.log("Holes first", holesFirst);
if (holesFirst) {
if ( holesFirst ) {
tmpShape = new THREE.Shape();
for ( i=0, il = subPaths.length; i<il; i++) {
tmpPath = subPaths[i];
if (THREE.Shape.Utils.isClockWise(tmpPath.getPoints())) {
for ( i = 0, il = subPaths.length; i < il; i ++ ) {
tmpPath = subPaths[ i ];
if ( THREE.Shape.Utils.isClockWise( tmpPath.getPoints() ) ) {
tmpShape.actions = tmpPath.actions;
tmpShape.curves = tmpPath.curves;
shapes.push(tmpShape);
shapes.push( tmpShape );
tmpShape = new THREE.Shape();
//console.log('cw', i);
} else {
tmpShape.holes.push(tmpPath);
tmpShape.holes.push( tmpPath );
//console.log('ccw', i);
}
}
} else {
// Shapes first
for ( i=0, il = subPaths.length; i<il; i++) {
tmpPath = subPaths[i];
if (THREE.Shape.Utils.isClockWise(tmpPath.getPoints())) {
if (tmpShape) shapes.push(tmpShape);
for ( i = 0, il = subPaths.length; i < il; i ++ ) {
tmpPath = subPaths[ i ];
if ( THREE.Shape.Utils.isClockWise( tmpPath.getPoints() ) ) {
if ( tmpShape ) shapes.push( tmpShape );
tmpShape = new THREE.Shape();
tmpShape.actions = tmpPath.actions;
tmpShape.curves = tmpPath.curves;
} else {
tmpShape.holes.push(tmpPath);
tmpShape.holes.push( tmpPath );
}
}
shapes.push(tmpShape);
shapes.push( tmpShape );
}
//console.log("shape", shapes);
return shapes;
};
......@@ -30,7 +30,6 @@ THREE.Shape.prototype.extrude = function ( options ) {
// Get points of holes
THREE.Shape.prototype.getPointsHoles = function () {
......@@ -352,7 +351,7 @@ THREE.Shape.Utils = {
}, // end triangulate shapes
/*
/*
triangulate2 : function( pts, holes ) {
// For use with Poly2Tri.js
......@@ -384,7 +383,7 @@ THREE.Shape.Utils = {
}
return -1;
};
// triangulate
js.poly2tri.sweep.Triangulate(swctx);
......@@ -414,7 +413,7 @@ THREE.Shape.Utils = {
return THREE.FontUtils.Triangulate.area( pts ) < 0;
},
// Bezier Curves formulas obtained from
// http://en.wikipedia.org/wiki/B%C3%A9zier_curve
......@@ -479,6 +478,6 @@ THREE.Shape.Utils = {
return this.b3p0( t, p0 ) + this.b3p1( t, p1 ) + this.b3p2( t, p2 ) + this.b3p3( t, p3 );
}
};
......@@ -35,14 +35,22 @@
*
*/
THREE.TextGeometry = function ( text, parameters ) {
var textPath = new THREE.TextPath(text, parameters );
var textPath = new THREE.TextPath( text, parameters );
var textShapes = textPath.toShapes();
THREE.ExtrudeGeometry.call( this, textShapes, parameters);
// translate parameters to ExtrudeGeometry API
parameters.amount = parameters.height !== undefined ? parameters.height : 50;
// defaults
if ( parameters.bevelThickness === undefined ) parameters.bevelThickness = 10;
if ( parameters.bevelSize === undefined ) parameters.bevelSize = 8;
if ( parameters.bevelEnabled === undefined ) parameters.bevelEnabled = false;
THREE.ExtrudeGeometry.call( this, textShapes, parameters );
};
......@@ -50,19 +58,21 @@ THREE.TextGeometry.prototype = new THREE.ExtrudeGeometry();
THREE.TextGeometry.prototype.constructor = THREE.TextGeometry;
/*
// TextGeometry Wrapper
var text3d = new TextGeometry(text, options);
// Complete Manner
var textPath = new TextPath(text, options);
// TextGeometry wrapper
var text3d = new TextGeometry( text, options );
// Complete manner
var textPath = new TextPath( text, options );
var textShapes = textPath.toShapes();
var text3d = new ExtrudeGeometry(textShapes, options);
var text3d = new ExtrudeGeometry( textShapes, options );
// Factory Method
var textShapes = FontUtils.getTextShapes(text, options);
text3d = new ExtrudeGeometry(textShapes, options);
var textShapes = FontUtils.getTextShapes( text, options );
text3d = new ExtrudeGeometry( textShapes, options );
*/
......@@ -84,11 +94,13 @@ THREE.FontUtils = {
return this.faces[ this.face ][ this.weight ][ this.style ];
},
getTextShapes: function(text, options) {
var textPath = new TextPath(text, options);
getTextShapes: function( text, options ) {
var textPath = new TextPath( text, options );
var textShapes = textPath.toShapes();
return textShapes;
},
loadFace : function( data ) {
......@@ -108,7 +120,8 @@ THREE.FontUtils = {
},
/* LAGACY CODE
/* LEGACY CODE
extractPoints : function( allPoints, charactersPoints ) {
// Quick exit
......@@ -479,8 +492,8 @@ THREE.FontUtils = {
var fontPaths = [];
for ( i = 0; i < length; i++ ) {
for ( i = 0; i < length; i ++ ) {
var path = new THREE.Path();
var ret = this.extractGlyphPoints( chars[ i ], face, scale, offset, path );
......@@ -488,26 +501,26 @@ THREE.FontUtils = {
//characterPts.push( ret.points );
//allPts = allPts.concat( ret.points );
fontPaths.push( ret.path );
}
// get the width
var width = offset / 2;
//
//
// for ( p = 0; p < allPts.length; p++ ) {
//
//
// allPts[ p ].x -= width;
//
//
// }
//var extract = this.extractPoints( allPts, characterPts );
//extract.contour = allPts;
//extract.paths = fontPaths;
//extract.offset = width;
return {paths : fontPaths,offset : width };
return { paths : fontPaths, offset : width };
},
......@@ -518,8 +531,6 @@ THREE.FontUtils = {
var pts = [];
var i, i2,
outline, action, length,
scaleX, scaleY,
......@@ -539,8 +550,10 @@ THREE.FontUtils = {
for ( i = 0; i < length; ) {
action = outline[ i++ ];
//console.log(action);
action = outline[ i ++ ];
//console.log( action );
switch( action ) {
case 'm':
......@@ -549,9 +562,10 @@ THREE.FontUtils = {
x = outline[ i++ ] * scaleX + offset;
y = outline[ i++ ] * scaleY;
pts.push( new THREE.Vector2( x, y ) );
path.moveTo(x,y);
path.moveTo( x, y );
break;
case 'l':
......
/**
* @author zz85 / http://www.lab4games.net/zz85/blog
*
* TextPath
*
**/
THREE.TextPath = function ( text, parameters ) {
THREE.Path.call( this );
this.parameters = parameters || {};
this.set( text );
};
THREE.TextPath.prototype.set = function ( text, parameters ) {
this.text = text;
var parameters = parameters || this.parameters;
var size = parameters.size !== undefined ? parameters.size : 100;
var height = parameters.height !== undefined ? parameters.height : 50;
var curveSegments = parameters.curveSegments !== undefined ? parameters.curveSegments: 4;
var font = parameters.font !== undefined ? parameters.font : "helvetiker";
var weight = parameters.weight !== undefined ? parameters.weight : "normal";
var style = parameters.style !== undefined ? parameters.style : "normal";
var bevelThickness = parameters.bevelThickness !== undefined ? parameters.bevelThickness : 10;
var bevelSize = parameters.bevelSize !== undefined ? parameters.bevelSize : 8;
var bevelEnabled = parameters.bevelEnabled !== undefined ? parameters.bevelEnabled : false;
THREE.FontUtils.size = size;
THREE.FontUtils.divisions = curveSegments;
......@@ -33,32 +35,34 @@ THREE.TextPath.prototype.set = function ( text, parameters ) {
THREE.FontUtils.weight = weight;
THREE.FontUtils.style = style;
};
THREE.TextPath.prototype.toShapes = function () {
// Get a Font data json object
var data = THREE.FontUtils.drawText( this.text );
var paths = data.paths;
var shapes = [];
for (var p=0, pl = paths.length; p<pl; p++) {
shapes = shapes.concat(paths[p].toShapes());
for ( var p = 0, pl = paths.length; p < pl; p ++ ) {
shapes = shapes.concat( paths[ p ].toShapes() );
}
return shapes;
//console.log(path);
//console.log(fontShapes);
// Either find actions or curves.
//var text3d = new THREE.ExtrudeGeometry( shapes , { amount: 20, bevelEnabled:true, bevelThickness:3 } );
//return text3d;
};
/**
* @author alteredq / http://alteredqualia.com/
*/
THREE.SpotLight = function ( hex, intensity, distance, castShadow ) {
THREE.Light.call( this, hex );
this.position = new THREE.Vector3( 0, 1, 0 );
this.target = new THREE.Object3D();
this.intensity = intensity || 1;
this.distance = distance || 0;
this.castShadow = castShadow !== undefined ? castShadow : false;
};
THREE.SpotLight.prototype = new THREE.Light();
THREE.SpotLight.prototype.constructor = THREE.SpotLight;
......@@ -92,6 +92,40 @@ THREE.WebGLRenderer = function ( parameters ) {
this.autoClear = true;
this.sortObjects = true;
// shadow map
this.shadowMapBias = 0.0039;
this.shadowMapDarkness = 0.5;
this.shadowMapWidth = 512;
this.shadowMapHeight = 512;
this.shadowCameraNear = 1;
this.shadowCameraFar = 5000;
this.shadowCameraFov = 50;
this.shadowMap = [];
this.shadowMapEnabled = false;
this.shadowMapSoft = true;
var _cameraLight,
_shadowMatrix = [];
var depthShader = THREE.ShaderLib[ "depthRGBA" ];
var depthUniforms = THREE.UniformsUtils.clone( depthShader.uniforms );
var _depthMaterial = new THREE.MeshShaderMaterial( { fragmentShader: depthShader.fragmentShader,
vertexShader: depthShader.vertexShader,
uniforms: depthUniforms } );
var _depthMaterialMorph = new THREE.MeshShaderMaterial( { fragmentShader: depthShader.fragmentShader,
vertexShader: depthShader.vertexShader,
uniforms: depthUniforms,
morphTargets: true
} );
_depthMaterial._shadowPass = true;
_depthMaterialMorph._shadowPass = true;
// Init GL
try {
......@@ -401,18 +435,19 @@ THREE.WebGLRenderer = function ( parameters ) {
this.setStencilShadowDarkness = function( value ) {
_stencilShadow.darkness = value;
};
this.getContext = function() {
return _gl;
}
};
function setupLights ( program, lights ) {
var l, ll, light, r = 0, g = 0, b = 0,
var l, ll, light, n,
r = 0, g = 0, b = 0,
color, position, intensity, distance,
zlights = _lights,
......@@ -449,25 +484,41 @@ THREE.WebGLRenderer = function ( parameters ) {
doffset = dlength * 3;
dcolors[ doffset ] = color.r * intensity;
dcolors[ doffset ] = color.r * intensity;
dcolors[ doffset + 1 ] = color.g * intensity;
dcolors[ doffset + 2 ] = color.b * intensity;
dpositions[ doffset ] = position.x;
dpositions[ doffset ] = position.x;
dpositions[ doffset + 1 ] = position.y;
dpositions[ doffset + 2 ] = position.z;
dlength += 1;
} else if ( light instanceof THREE.SpotLight ) { // hack, not a proper spotlight
doffset = dlength * 3;
dcolors[ doffset ] = color.r * intensity;
dcolors[ doffset + 1 ] = color.g * intensity;
dcolors[ doffset + 2 ] = color.b * intensity;
n = 1 / position.length();
dpositions[ doffset ] = position.x * n;
dpositions[ doffset + 1 ] = position.y * n;
dpositions[ doffset + 2 ] = position.z * n;
dlength += 1;
} else if( light instanceof THREE.PointLight ) {
poffset = plength * 3;
pcolors[ poffset ] = color.r * intensity;
pcolors[ poffset ] = color.r * intensity;
pcolors[ poffset + 1 ] = color.g * intensity;
pcolors[ poffset + 2 ] = color.b * intensity;
ppositions[ poffset ] = position.x;
ppositions[ poffset ] = position.x;
ppositions[ poffset + 1 ] = position.y;
ppositions[ poffset + 2 ] = position.z;
......@@ -923,6 +974,7 @@ THREE.WebGLRenderer = function ( parameters ) {
obj_skinVerticesB = geometry.skinVerticesB,
obj_skinIndices = geometry.skinIndices,
obj_skinWeights = geometry.skinWeights,
obj_edgeFaces = object instanceof THREE.ShadowVolume ? geometry.edgeFaces : undefined,
morphTargets = geometry.morphTargets;
......@@ -1944,6 +1996,7 @@ THREE.WebGLRenderer = function ( parameters ) {
_gl.bufferData( _gl.ARRAY_BUFFER, morphTargetsArrays[ vk ], hint );
}
}
if ( dirtyColors && offset_color > 0 ) {
......@@ -2511,9 +2564,28 @@ THREE.WebGLRenderer = function ( parameters ) {
};
function refreshUniformsShadow( uniforms, material ) {
if ( uniforms.shadowMatrix ) {
for ( var i = 0; i < _shadowMatrix.length; i ++ ) {
uniforms.shadowMatrix.value[ i ] = _shadowMatrix[ i ];
uniforms.shadowMap.texture[ i ] = _this.shadowMap[ i ];
}
uniforms.shadowDarkness.value = _this.shadowMapDarkness;
uniforms.shadowBias.value = _this.shadowMapBias;
}
};
this.initMaterial = function ( material, lights, fog, object ) {
var u, a, identifiers, i, parameters, maxLightCount, maxBones, shaderID;
var u, a, identifiers, i, parameters, maxLightCount, maxBones, maxShadows, shaderID;
if ( material instanceof THREE.MeshDepthMaterial ) {
......@@ -2560,9 +2632,12 @@ THREE.WebGLRenderer = function ( parameters ) {
maxLightCount = allocateLights( lights, 4 );
maxShadows = allocateShadows( lights );
maxBones = allocateBones( object );
parameters = {
map: !!material.map, envMap: !!material.envMap, lightMap: !!material.lightMap,
vertexColors: material.vertexColors,
fog: fog, sizeAttenuation: material.sizeAttenuation,
......@@ -2570,7 +2645,13 @@ THREE.WebGLRenderer = function ( parameters ) {
morphTargets: material.morphTargets,
maxMorphTargets: this.maxMorphTargets,
maxDirLights: maxLightCount.directional, maxPointLights: maxLightCount.point,
maxBones: maxBones
maxBones: maxBones,
shadowMapEnabled: this.shadowMapEnabled && object.receiveShadow,
shadowMapSoft: this.shadowMapSoft,
shadowMapWidth: this.shadowMapWidth,
shadowMapHeight: this.shadowMapHeight,
maxShadows: maxShadows
};
material.program = buildProgram( shaderID, material.fragmentShader, material.vertexShader, material.uniforms, material.attributes, parameters );
......@@ -2607,7 +2688,6 @@ THREE.WebGLRenderer = function ( parameters ) {
material.numSupportedMorphTargets = 0;
if ( attributes.morphTarget0 >= 0 ) {
_gl.enableVertexAttribArray( attributes.morphTarget0 );
......@@ -2664,14 +2744,6 @@ THREE.WebGLRenderer = function ( parameters ) {
}
object.__webglMorphTargetInfluences = new Float32Array( this.maxMorphTargets );
for ( var i = 0, il = this.maxMorphTargets; i < il; i ++ ) {
object.__webglMorphTargetInfluences[ i ] = 0;
}
}
};
......@@ -2684,6 +2756,22 @@ THREE.WebGLRenderer = function ( parameters ) {
}
if ( material.morphTargets ) {
if ( ! object.__webglMorphTargetInfluences ) {
object.__webglMorphTargetInfluences = new Float32Array( _this.maxMorphTargets );
for ( var i = 0, il = this.maxMorphTargets; i < il; i ++ ) {
object.__webglMorphTargetInfluences[ i ] = 0;
}
}
}
var program = material.program,
p_uniforms = program.uniforms,
m_uniforms = material.uniforms;
......@@ -2752,6 +2840,13 @@ THREE.WebGLRenderer = function ( parameters ) {
} else if ( material instanceof THREE.MeshNormalMaterial ) {
m_uniforms.opacity.value = material.opacity;
}
if ( object.receiveShadow && ! material._shadowPass ) {
refreshUniformsShadow( m_uniforms, material );
}
// load common uniforms
......@@ -2776,7 +2871,8 @@ THREE.WebGLRenderer = function ( parameters ) {
if ( material instanceof THREE.MeshShaderMaterial ||
material.envMap ||
material.skinning ) {
material.skinning ||
object.receiveShadow ) {
if ( p_uniforms.objectMatrix !== null ) {
......@@ -3098,6 +3194,7 @@ THREE.WebGLRenderer = function ( parameters ) {
candidateInfluence = influences[ candidate ];
}
}
_gl.bindBuffer( _gl.ARRAY_BUFFER, geometryGroup.__webglMorphTargetsBuffers[ candidate ] );
......@@ -3108,7 +3205,9 @@ THREE.WebGLRenderer = function ( parameters ) {
used[ candidate ] = 1;
candidateInfluence = -1;
m ++;
}
}
// load updated influences uniform
......@@ -3377,13 +3476,184 @@ THREE.WebGLRenderer = function ( parameters ) {
};
function painterSort( a, b ) {
return b.z - a.z;
};
function renderShadowMap( scene, camera ) {
var i, il, light,
j = 0,
shadowMap, shadowMatrix,
oil,
material,
o, ol, webglObject, object,
lights = scene.lights,
fog = null;
if ( ! _cameraLight ) {
_cameraLight = new THREE.Camera( _this.shadowCameraFov, camera.aspect, _this.shadowCameraNear, _this.shadowCameraFar );
}
for ( i = 0, il = lights.length; i < il; i ++ ) {
light = lights[ i ];
if ( light instanceof THREE.SpotLight && light.castShadow ) {
if ( ! _this.shadowMap[ j ] ) {
var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };
_this.shadowMap[ j ] = new THREE.WebGLRenderTarget( _this.shadowMapWidth, _this.shadowMapHeight, pars );
}
if ( ! _shadowMatrix[ j ] ) {
_shadowMatrix[ j ] = new THREE.Matrix4();
}
shadowMap = _this.shadowMap[ j ];
shadowMatrix = _shadowMatrix[ j ];
_cameraLight.position.copy( light.position );
_cameraLight.target.position.copy( light.target.position );
_cameraLight.update( undefined, true );
scene.update( undefined, false, _cameraLight );
// compute shadow matrix
shadowMatrix.set( 0.5, 0.0, 0.0, 0.5,
0.0, 0.5, 0.0, 0.5,
0.0, 0.0, 0.5, 0.5,
0.0, 0.0, 0.0, 1.0 );
shadowMatrix.multiplySelf( _cameraLight.projectionMatrix );
shadowMatrix.multiplySelf( _cameraLight.matrixWorldInverse );
// render shadow map
_cameraLight.matrixWorldInverse.flattenToArray( _viewMatrixArray );
_cameraLight.projectionMatrix.flattenToArray( _projectionMatrixArray );
_projScreenMatrix.multiply( _cameraLight.projectionMatrix, _cameraLight.matrixWorldInverse );
computeFrustum( _projScreenMatrix );
_this.initWebGLObjects( scene );
setRenderTarget( shadowMap );
// using arbitrary clear color in depth pass
// creates variance in shadows
_gl.clearColor( 1, 1, 1, 1 );
//_gl.clearColor( 0, 0, 0, 1 );
_this.clear();
_gl.clearColor( _clearColor.r, _clearColor.g, _clearColor.b, _clearAlpha );
// set matrices & frustum culling
ol = scene.__webglObjects.length;
oil = scene.__webglObjectsImmediate.length;
for ( o = 0; o < ol; o ++ ) {
webglObject = scene.__webglObjects[ o ];
object = webglObject.object;
if ( object.visible && object.castShadow ) {
if ( ! ( object instanceof THREE.Mesh ) || isInFrustum( object ) ) {
object.matrixWorld.flattenToArray( object._objectMatrixArray );
setupMatrices( object, _cameraLight, false );
webglObject.render = true;
} else {
webglObject.render = false;
}
} else {
webglObject.render = false;
}
}
setDepthTest( true );
setBlending( THREE.NormalBlending ); // maybe blending should be just disabled?
//_gl.cullFace( _gl.FRONT );
for ( o = 0; o < ol; o ++ ) {
webglObject = scene.__webglObjects[ o ];
if ( webglObject.render ) {
object = webglObject.object;
buffer = webglObject.buffer;
setObjectFaces( object );
material = object.geometry.morphTargets.length ? _depthMaterialMorph : _depthMaterial;
renderBuffer( _cameraLight, lights, fog, material, buffer, object );
}
}
for ( o = 0; o < oil; o++ ) {
webglObject = scene.__webglObjectsImmediate[ o ];
object = webglObject.object;
if ( object.visible && object.castShadow ) {
if( object.matrixAutoUpdate ) {
object.matrixWorld.flattenToArray( object._objectMatrixArray );
}
setupMatrices( object, _cameraLight, false );
setObjectFaces( object );
program = setProgram( _cameraLight, lights, fog, _depthMaterial, object );
object.render( function( object ) { renderBufferImmediate( object, program, _depthMaterial.shading ); } );
}
}
//_gl.cullFace( _gl.BACK );
j ++;
}
}
};
this.render = function( scene, camera, renderTarget, forceClear ) {
var i, program, opaque, transparent, material,
......@@ -3391,6 +3661,8 @@ THREE.WebGLRenderer = function ( parameters ) {
lights = scene.lights,
fog = scene.fog;
if ( this.shadowMapEnabled ) renderShadowMap( scene, camera );
_this.data.vertices = 0;
_this.data.faces = 0;
_this.data.drawCalls = 0;
......@@ -3430,7 +3702,7 @@ THREE.WebGLRenderer = function ( parameters ) {
object.matrixWorld.flattenToArray( object._objectMatrixArray );
setupMatrices( object, camera );
setupMatrices( object, camera, true );
unrollBufferMaterials( webglObject );
......@@ -3488,7 +3760,7 @@ THREE.WebGLRenderer = function ( parameters ) {
}
setupMatrices( object, camera );
setupMatrices( object, camera, true );
unrollImmediateBufferMaterials( webglObject );
......@@ -4183,10 +4455,15 @@ THREE.WebGLRenderer = function ( parameters ) {
};
function setupMatrices( object, camera ) {
function setupMatrices( object, camera, computeNormalMatrix ) {
object._modelViewMatrix.multiplyToArray( camera.matrixWorldInverse, object.matrixWorld, object._modelViewMatrixArray );
THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
if ( computeNormalMatrix ) {
THREE.Matrix4.makeInvert3x3( object._modelViewMatrix ).transposeIntoArray( object._normalMatrixArray );
}
};
......@@ -4787,6 +5064,8 @@ THREE.WebGLRenderer = function ( parameters ) {
"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
"#define MAX_SHADOWS " + parameters.maxShadows,
"#define MAX_BONES " + parameters.maxBones,
parameters.map ? "#define USE_MAP" : "",
......@@ -4796,6 +5075,9 @@ THREE.WebGLRenderer = function ( parameters ) {
parameters.skinning ? "#define USE_SKINNING" : "",
parameters.morphTargets ? "#define USE_MORPHTARGETS" : "",
parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
parameters.sizeAttenuation ? "#define USE_SIZEATTENUATION" : "",
"uniform mat4 objectMatrix;",
......@@ -4853,6 +5135,8 @@ THREE.WebGLRenderer = function ( parameters ) {
"#define MAX_DIR_LIGHTS " + parameters.maxDirLights,
"#define MAX_POINT_LIGHTS " + parameters.maxPointLights,
"#define MAX_SHADOWS " + parameters.maxShadows,
parameters.fog ? "#define USE_FOG" : "",
parameters.fog instanceof THREE.FogExp2 ? "#define FOG_EXP2" : "",
......@@ -4861,6 +5145,11 @@ THREE.WebGLRenderer = function ( parameters ) {
parameters.lightMap ? "#define USE_LIGHTMAP" : "",
parameters.vertexColors ? "#define USE_COLOR" : "",
parameters.shadowMapEnabled ? "#define USE_SHADOWMAP" : "",
parameters.shadowMapSoft ? "#define SHADOWMAP_SOFT" : "",
parameters.shadowMapSoft ? "#define SHADOWMAP_WIDTH " + parameters.shadowMapWidth.toFixed( 1 ) : "",
parameters.shadowMapSoft ? "#define SHADOWMAP_HEIGHT " + parameters.shadowMapHeight.toFixed( 1 ) : "",
"uniform mat4 viewMatrix;",
"uniform vec3 cameraPosition;",
""
......@@ -4949,14 +5238,14 @@ THREE.WebGLRenderer = function ( parameters ) {
function loadUniformsGeneric( program, uniforms ) {
var u, uniform, value, type, location, texture;
var u, uniform, value, type, location, texture, i, il;
for( u in uniforms ) {
location = program.uniforms[u];
location = program.uniforms[ u ];
if ( !location ) continue;
uniform = uniforms[u];
uniform = uniforms[ u ];
type = uniform.type;
value = uniform.value;
......@@ -5000,6 +5289,22 @@ THREE.WebGLRenderer = function ( parameters ) {
value.flattenToArray( uniform._array );
_gl.uniformMatrix4fv( location, false, uniform._array );
} else if( type == "m4v" ) {
if ( ! uniform._array ) {
uniform._array = new Float32Array( 16 * value.length );
}
for ( i = 0, il = value.length; i < il; i ++ ) {
value[ i ].flattenToArrayOffset( uniform._array, i * 16 );
}
_gl.uniformMatrix4fv( location, false, uniform._array );
} else if( type == "c" ) {
_gl.uniform3f( location, value.r, value.g, value.b );
......@@ -5022,6 +5327,32 @@ THREE.WebGLRenderer = function ( parameters ) {
}
} else if( type == "tv" ) {
if ( ! uniform._array ) {
uniform._array = [];
for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
uniform._array[ i ] = value + i;
}
}
_gl.uniform1iv( location, uniform._array );
for( i = 0, il = uniform.texture.length; i < il; i ++ ) {
texture = uniform.texture[ i ];
if ( !texture ) continue;
setTexture( texture, uniform._array[ i ] );
}
}
}
......@@ -5608,8 +5939,9 @@ THREE.WebGLRenderer = function ( parameters ) {
light = lights[ l ];
if ( light instanceof THREE.DirectionalLight ) dirLights++;
if ( light instanceof THREE.PointLight ) pointLights++;
if ( light instanceof THREE.SpotLight ) dirLights ++; // hack, not a proper spotlight
if ( light instanceof THREE.DirectionalLight ) dirLights ++;
if ( light instanceof THREE.PointLight ) pointLights ++;
}
......@@ -5629,6 +5961,24 @@ THREE.WebGLRenderer = function ( parameters ) {
};
function allocateShadows( lights ) {
var l, ll, light,
maxShadows = 0;
for ( l = 0, ll = lights.length; l < ll; l++ ) {
light = lights[ l ];
if ( light instanceof THREE.SpotLight && light.castShadow ) maxShadows ++;
}
return maxShadows;
};
/* DEBUG
function getGLParams() {
......
......@@ -6,7 +6,6 @@
THREE.ShaderChunk = {
// FOG
fog_pars_fragment: [
......@@ -16,10 +15,14 @@ THREE.ShaderChunk = {
"uniform vec3 fogColor;",
"#ifdef FOG_EXP2",
"uniform float fogDensity;",
"#else",
"uniform float fogNear;",
"uniform float fogFar;",
"#endif",
"#endif"
......@@ -33,11 +36,15 @@ THREE.ShaderChunk = {
"float depth = gl_FragCoord.z / gl_FragCoord.w;",
"#ifdef FOG_EXP2",
"const float LOG2 = 1.442695;",
"float fogFactor = exp2( - fogDensity * fogDensity * depth * depth * LOG2 );",
"fogFactor = 1.0 - clamp( fogFactor, 0.0, 1.0 );",
"#else",
"float fogFactor = smoothstep( fogNear, fogFar, depth );",
"#endif",
"gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );",
......@@ -53,6 +60,7 @@ THREE.ShaderChunk = {
"#ifdef USE_ENVMAP",
"varying vec3 vReflect;",
"uniform float reflectivity;",
"uniform samplerCube envMap;",
"uniform int combine;",
......@@ -69,7 +77,6 @@ THREE.ShaderChunk = {
"if ( combine == 1 ) {",
//"gl_FragColor = mix( gl_FragColor, cubeColor, reflectivity );",
"gl_FragColor = vec4( mix( gl_FragColor.xyz, cubeColor.xyz, reflectivity ), opacity );",
"} else {",
......@@ -87,6 +94,7 @@ THREE.ShaderChunk = {
"#ifdef USE_ENVMAP",
"varying vec3 vReflect;",
"uniform float refractionRatio;",
"uniform bool useRefract;",
......@@ -99,7 +107,7 @@ THREE.ShaderChunk = {
"#ifdef USE_ENVMAP",
"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
"vec3 nWorld = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;",
"vec3 nWorld = mat3( objectMatrix[ 0 ].xyz, objectMatrix[ 1 ].xyz, objectMatrix[ 2 ].xyz ) * normal;",
"if ( useRefract ) {",
......@@ -244,7 +252,9 @@ THREE.ShaderChunk = {
"uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
"#ifdef PHONG",
"varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
"#endif",
"#endif"
......@@ -265,7 +275,7 @@ THREE.ShaderChunk = {
"#if MAX_DIR_LIGHTS > 0",
"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
"for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
"float directionalLightWeighting = max( dot( transformedNormal, normalize( lDirection.xyz ) ), 0.0 );",
......@@ -277,7 +287,7 @@ THREE.ShaderChunk = {
"#if MAX_POINT_LIGHTS > 0",
"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
"for( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
......@@ -359,7 +369,7 @@ THREE.ShaderChunk = {
"vec4 dirDiffuse = vec4( 0.0 );",
"vec4 dirSpecular = vec4( 0.0 );" ,
"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
"for( int i = 0; i < MAX_DIR_LIGHTS; i ++ ) {",
"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ i ], 0.0 );",
......@@ -384,11 +394,15 @@ THREE.ShaderChunk = {
"vec4 totalLight = vec4( ambient, opacity );",
"#if MAX_DIR_LIGHTS > 0",
"totalLight += dirDiffuse + dirSpecular;",
"#endif",
"#if MAX_POINT_LIGHTS > 0",
"totalLight += pointDiffuse + pointSpecular;",
"#endif",
"gl_FragColor = gl_FragColor * totalLight;"
......@@ -439,7 +453,7 @@ THREE.ShaderChunk = {
].join("\n"),
// skinning
// SKINNING
skinning_pars_vertex: [
......@@ -467,7 +481,7 @@ THREE.ShaderChunk = {
].join("\n"),
// morphing
// MORPHING
morphtarget_pars_vertex: [
......@@ -510,7 +524,139 @@ THREE.ShaderChunk = {
"#endif",
"#endif"
].join("\n")
].join("\n"),
// SHADOW MAP
// based on SpiderGL shadow map and Fabien Sanglard's GLSL shadow mapping examples
// http://spidergl.org/example.php?id=6
// http://fabiensanglard.net/shadowmapping
shadowmap_pars_fragment: [
"#ifdef USE_SHADOWMAP",
"uniform sampler2D shadowMap[ MAX_SHADOWS ];",
"uniform float shadowDarkness;",
"uniform float shadowBias;",
"varying vec4 vShadowCoord[ MAX_SHADOWS ];",
"float unpackDepth( const in vec4 rgba_depth ) {",
"const vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );",
"float depth = dot( rgba_depth, bit_shift );",
"return depth;",
"}",
"#endif"
].join("\n"),
shadowmap_fragment: [
"#ifdef USE_SHADOWMAP",
"#ifdef SHADOWMAP_SOFT",
"const float xPixelOffset = 1.0 / SHADOWMAP_WIDTH;",
"const float yPixelOffset = 1.0 / SHADOWMAP_HEIGHT;",
"#endif",
"vec4 shadowColor = vec4( 1.0 );",
"for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
"vec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;",
"if ( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) {",
"#ifdef SHADOWMAP_SOFT",
// Percentage-close filtering
// (9 pixel kernel)
// http://fabiensanglard.net/shadowmappingPCF/
"float shadow = 0.0;",
"for ( float y = -1.25; y <= 1.25; y += 1.25 )",
"for ( float x = -1.25; x <= 1.25; x += 1.25 ) {",
"vec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );",
// doesn't seem to produce any noticeable visual difference compared to simple "texture2D" lookup
//"vec4 rgbaDepth = texture2DProj( shadowMap[ i ], vec4( vShadowCoord[ i ].w * ( vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy ), 0.05, vShadowCoord[ i ].w ) );",
"float fDepth = unpackDepth( rgbaDepth );",
"if ( fDepth < ( shadowCoord.z + shadowBias ) )",
"shadow += 1.0;",
"}",
"shadow /= 9.0;",
"shadowColor = shadowColor * vec4( vec3( ( 1.0 - shadowDarkness * shadow ) ), 1.0 );",
"#else",
"vec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );",
"float fDepth = unpackDepth( rgbaDepth );",
"if ( fDepth < ( shadowCoord.z + shadowBias ) )",
// spot with multiple shadows is darker
"shadowColor = shadowColor * vec4( vec3( shadowDarkness ), 1.0 );",
// spot with multiple shadows has the same color as single shadow spot
//"shadowColor = min( shadowColor, vec4( vec3( shadowDarkness ), 1.0 ) );",
"#endif",
"}",
// uncomment to see light frustum boundaries
//"if ( !( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) )",
// "gl_FragColor = gl_FragColor * vec4( 1.0, 0.0, 0.0, 1.0 );",
"}",
"gl_FragColor = gl_FragColor * shadowColor;",
"#endif"
].join("\n"),
shadowmap_pars_vertex: [
"#ifdef USE_SHADOWMAP",
"varying vec4 vShadowCoord[ MAX_SHADOWS ];",
"uniform mat4 shadowMatrix[ MAX_SHADOWS ];",
"#endif"
].join("\n"),
shadowmap_vertex: [
"#ifdef USE_SHADOWMAP",
"for( int i = 0; i < MAX_SHADOWS; i ++ ) {",
"vShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( position, 1.0 );",
"}",
"#endif"
].join("\n"),
};
......@@ -633,6 +779,16 @@ THREE.UniformsLib = {
"fogFar" : { type: "f", value: 2000 },
"fogColor" : { type: "c", value: new THREE.Color( 0xffffff ) }
},
shadowmap: {
"shadowMap": { type: "tv", value: 3, texture: [] },
"shadowMatrix" : { type: "m4v", value: [] },
"shadowBias" : { type: "f", value: 0.0039 },
"shadowDarkness": { type: "f", value: 0.2 }
}
};
......@@ -934,7 +1090,7 @@ THREE.ShaderLib = {
"void main() {",
"vec4 pos = objectMatrix * vec4( position, 1.0 );",
"vec3 norm = mat3( objectMatrix[0].xyz, objectMatrix[1].xyz, objectMatrix[2].xyz ) * normal;",
"vec3 norm = mat3( objectMatrix[ 0 ].xyz, objectMatrix[ 1 ].xyz, objectMatrix[ 2 ].xyz ) * normal;",
"vec4 extruded = vec4( directionalLightDirection * 5000.0 * step( 0.0, dot( directionalLightDirection, norm ) ), 0.0 );",
"gl_Position = projectionMatrix * viewMatrix * ( pos + extruded );",
......@@ -1030,7 +1186,8 @@ THREE.ShaderLib = {
uniforms: THREE.UniformsUtils.merge( [
THREE.UniformsLib[ "common" ],
THREE.UniformsLib[ "fog" ]
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "shadowmap" ]
] ),
......@@ -1044,6 +1201,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "lightmap_pars_fragment" ],
THREE.ShaderChunk[ "envmap_pars_fragment" ],
THREE.ShaderChunk[ "fog_pars_fragment" ],
THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
"void main() {",
......@@ -1053,6 +1211,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "lightmap_fragment" ],
THREE.ShaderChunk[ "color_fragment" ],
THREE.ShaderChunk[ "envmap_fragment" ],
THREE.ShaderChunk[ "shadowmap_fragment" ],
THREE.ShaderChunk[ "fog_fragment" ],
"}"
......@@ -1067,6 +1226,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "color_pars_vertex" ],
THREE.ShaderChunk[ "skinning_pars_vertex" ],
THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
"void main() {",
......@@ -1079,6 +1239,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "skinning_vertex" ],
THREE.ShaderChunk[ "morphtarget_vertex" ],
THREE.ShaderChunk[ "default_vertex" ],
THREE.ShaderChunk[ "shadowmap_vertex" ],
"}"
......@@ -1092,7 +1253,8 @@ THREE.ShaderLib = {
THREE.UniformsLib[ "common" ],
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "lights" ]
THREE.UniformsLib[ "lights" ],
THREE.UniformsLib[ "shadowmap" ]
] ),
......@@ -1108,6 +1270,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "lightmap_pars_fragment" ],
THREE.ShaderChunk[ "envmap_pars_fragment" ],
THREE.ShaderChunk[ "fog_pars_fragment" ],
THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
"void main() {",
......@@ -1118,6 +1281,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "lightmap_fragment" ],
THREE.ShaderChunk[ "color_fragment" ],
THREE.ShaderChunk[ "envmap_fragment" ],
THREE.ShaderChunk[ "shadowmap_fragment" ],
THREE.ShaderChunk[ "fog_fragment" ],
"}"
......@@ -1135,6 +1299,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "color_pars_vertex" ],
THREE.ShaderChunk[ "skinning_pars_vertex" ],
THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
"void main() {",
......@@ -1151,6 +1316,8 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "skinning_vertex" ],
THREE.ShaderChunk[ "morphtarget_vertex" ],
THREE.ShaderChunk[ "default_vertex" ],
THREE.ShaderChunk[ "shadowmap_vertex" ],
"}"
......@@ -1165,6 +1332,7 @@ THREE.ShaderLib = {
THREE.UniformsLib[ "common" ],
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "lights" ],
THREE.UniformsLib[ "shadowmap" ],
{
"ambient" : { type: "c", value: new THREE.Color( 0x050505 ) },
......@@ -1191,6 +1359,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "envmap_pars_fragment" ],
THREE.ShaderChunk[ "fog_pars_fragment" ],
THREE.ShaderChunk[ "lights_pars_fragment" ],
THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
"void main() {",
......@@ -1201,6 +1370,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "lightmap_fragment" ],
THREE.ShaderChunk[ "color_fragment" ],
THREE.ShaderChunk[ "envmap_fragment" ],
THREE.ShaderChunk[ "shadowmap_fragment" ],
THREE.ShaderChunk[ "fog_fragment" ],
"}"
......@@ -1222,6 +1392,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "color_pars_vertex" ],
THREE.ShaderChunk[ "skinning_pars_vertex" ],
THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
THREE.ShaderChunk[ "shadowmap_pars_vertex" ],
"void main() {",
......@@ -1233,7 +1404,9 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "color_vertex" ],
"#ifndef USE_ENVMAP",
"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
"#endif",
"vViewPosition = cameraPosition - mPosition.xyz;",
......@@ -1245,6 +1418,7 @@ THREE.ShaderLib = {
THREE.ShaderChunk[ "skinning_vertex" ],
THREE.ShaderChunk[ "morphtarget_vertex" ],
THREE.ShaderChunk[ "default_vertex" ],
THREE.ShaderChunk[ "shadowmap_vertex" ],
"}"
......@@ -1302,6 +1476,60 @@ THREE.ShaderLib = {
].join("\n")
},
// Depth encoding into RGBA texture
// based on SpiderGL shadow map example
// http://spidergl.org/example.php?id=6
// originally from
// http://www.gamedev.net/topic/442138-packing-a-float-into-a-a8r8g8b8-texture-shader/page__whichpage__1%25EF%25BF%25BD
// see also here:
// http://aras-p.info/blog/2009/07/30/encoding-floats-to-rgba-the-final/
'depthRGBA': {
uniforms: {},
fragmentShader: [
"vec4 pack_depth( const in float depth ) {",
"const vec4 bit_shift = vec4( 256.0 * 256.0 * 256.0, 256.0 * 256.0, 256.0, 1.0 );",
"const vec4 bit_mask = vec4( 0.0, 1.0 / 256.0, 1.0 / 256.0, 1.0 / 256.0 );",
"vec4 res = fract( depth * bit_shift );",
"res -= res.xxyz * bit_mask;",
"return res;",
"}",
"void main() {",
"gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z );",
//"gl_FragData[ 0 ] = pack_depth( gl_FragCoord.z / gl_FragCoord.w );",
//"float z = ( ( gl_FragCoord.z / gl_FragCoord.w ) - 3.0 ) / ( 4000.0 - 3.0 );",
//"gl_FragData[ 0 ] = pack_depth( z );",
//"gl_FragData[ 0 ] = vec4( z, z, z, 1.0 );",
"}"
].join("\n"),
vertexShader: [
THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
"void main() {",
"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
THREE.ShaderChunk[ "morphtarget_vertex" ],
THREE.ShaderChunk[ "default_vertex" ],
"}"
].join("\n")
}
};
......@@ -35,6 +35,7 @@ COMMON_FILES = [
'lights/AmbientLight.js',
'lights/DirectionalLight.js',
'lights/PointLight.js',
'lights/SpotLight.js',
'lights/LensFlare.js',
'materials/Material.js',
'materials/Mappings.js',
......@@ -264,6 +265,7 @@ WEBGL_FILES = [
'lights/AmbientLight.js',
'lights/DirectionalLight.js',
'lights/PointLight.js',
'lights/SpotLight.js',
'lights/LensFlare.js',
'materials/Material.js',
'materials/Mappings.js',
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册