瀏覽代碼

Merge remote-tracking branch 'upstream/dev' into webglrendertarget-texture

Marius Kintel 9 年之前
父節點
當前提交
89b6c6bb70

文件差異過大導致無法顯示
+ 3 - 3
build/three.js


文件差異過大導致無法顯示
+ 0 - 0
build/three.min.js


+ 2 - 2
docs/api/extras/geometries/TextGeometry.html

@@ -93,13 +93,13 @@
 				<td>/examples/fonts/gentilis_bold.typeface.js</td>
 				<td>/examples/fonts/gentilis_bold.typeface.js</td>
 			</tr>
 			</tr>
 			<tr>
 			<tr>
-				<td>driod sans</td>
+				<td>droid sans</td>
 				<td>normal</td>
 				<td>normal</td>
 				<td>normal</td>
 				<td>normal</td>
 				<td>/examples/fonts/droid/droid_sans_regular.typeface.js</td>
 				<td>/examples/fonts/droid/droid_sans_regular.typeface.js</td>
 			</tr>
 			</tr>
 			<tr>
 			<tr>
-				<td>driod sans</td>
+				<td>droid sans</td>
 				<td>bold</td>
 				<td>bold</td>
 				<td>normal</td>
 				<td>normal</td>
 				<td>/examples/fonts/droid/droid_sans_bold.typeface.js</td>
 				<td>/examples/fonts/droid/droid_sans_bold.typeface.js</td>

+ 161 - 161
docs/api/renderers/CanvasRenderer.html

@@ -1,162 +1,162 @@
-<!DOCTYPE html>
-<html lang="en">
-	<head>
+<!DOCTYPE html>
+<html lang="en">
+	<head>
 		<meta charset="utf-8" />
 		<meta charset="utf-8" />
-		<base href="../../" />
-		<script src="list.js"></script>
-		<script src="page.js"></script>
-		<link type="text/css" rel="stylesheet" href="page.css" />
-	</head>
-	<body>
-		<h1>[name]</h1>
-
-		<div class="desc">
-			The Canvas renderer displays your beautifully crafted scenes <em>not</em> using WebGL, but draws it using the (slower) <a href="http://www.w3.org/html/wg/drafts/2dcontext/html5_canvas/">Canvas 2D Context</a> API.<br /><br />
-			This renderer can be a nice fallback from [page:WebGLRenderer] for simple scenes:
-
-			<code>
-			function webglAvailable() {
-				try {
-					var canvas = document.createElement( 'canvas' );
-					return !!( window.WebGLRenderingContext && (
-						canvas.getContext( 'webgl' ) ||
-						canvas.getContext( 'experimental-webgl' ) )
-					);
-				} catch ( e ) {
-					return false;
-				}
-			}
-
-			if ( webglAvailable() ) {
-				renderer = new THREE.WebGLRenderer();
-			} else {
-				renderer = new THREE.CanvasRenderer();
-			}
-			</code>
-
-			Note: both WebGLRenderer and CanvasRenderer are embedded in the web page using an HTML5 &lt;canvas&gt; tag.
-			The "Canvas" in CanvasRenderer means it uses Canvas 2D instead of WebGL.<br /><br />
-
-			Don't confuse either CanvasRenderer with the SoftwareRenderer example, which simulates a screen buffer in a Javascript array.
-		</div>
-
-		<h2>Constructor</h2>
-
-
-		<h3>[name]([page:object parameters])</h3>
-        <div>parameters is an optional object with properties defining the renderer's behaviour. The constructor also accepts no parameters at all. In all cases, it will assume sane defaults when parameters are missing.</div>
-
-		<div>
-		canvas — A [page:Canvas] where the renderer draws its output.
-		</div>
-
-
-		<h2>Properties</h2>
-
-    <h3>[property:Object info]</h3>
-
-		<div>
-			An object with a series of statistical information about the graphics board memory and the rendering process. Useful for debugging or just for the sake of curiosity. The object contains the following fields:</div>
-			<ul>
-				<li>render:
-					<ul>
-						<li>vertices</li>
-						<li>faces</li>
-					</ul>
-				</li>
-			</ul>
-		</div>
-
-    <h3>[property:DOMElement domElement]</h3>
-
-		<div>
-			A [page:Canvas] where the renderer draws its output.<br />
-			This is automatically created by the renderer in the constructor (if not provided already); you just need to add it to your page.
-		</div>
-
-		<h3>[property:Boolean autoClear]</h3>
-		<div>
-      Defines whether the renderer should automatically clear its output before rendering.
-    </div>
-
-		<h3>[property:Boolean sortObjects]</h3>
-		<div>
-      Defines whether the renderer should sort objects. Default is true.<br />
-      Note: Sorting is used to attempt to properly render objects that have some degree of transparency.  By definition, sorting objects may not work in all cases.  Depending on the needs of application, it may be neccessary to turn off sorting and use other methods to deal with transparency rendering e.g. manually determining the object rendering order.
-    </div>
-
-		<h3>[property:boolean sortElements]</h3>
-		<div>
-			Defines whether the renderer should sort the face of each object. Default is true.
-		</div>
-
-
-		<h2>Methods</h2>
-
-		<h3>[method:null render]([page:Scene scene], [page:Camera camera])</h3>
-		<div>
-			scene -- The scene to render. <br />
-			camera -- the camera to view the scene.
-		</div>
-		<div>
-        Render a scene using a camera.
-		</div>
-
-		<h3>[method:null clear]()</h3>
-		<div>
-			Tells the renderer to clear its color drawing buffer with the clearcolor.
-		</div>
-
-		<h3>[method:null setClearColor]([page:Color color], [page:number alpha])</h3>
-		<div>
-			color -- The color to clear the canvas with. <br />
-			alpha -- The alpha channel to clear the canvas with.
-		</div>
-		<div>
-			This set the clearColor and the clearAlpha.
-		</div>
-
-
-		<h3>[method:null setSize]([page:Number width], [page:Number height])</h3>
-		<div>
-			width -- The width of the drawing canvas. <br />
-			height -- The height of the drawing canvas.
-		</div>
-		<div>
-			This set the size of the drawing canvas and if updateStyle is set, then the css of the canvas is updated too.
-		</div>
-
-		<h3>[method:null setClearColorHex]([page:number hex], [page:number alpha])</h3>
-		<div>
-			hex -- The the hexadecimal value of the color to clear the canvas with. <br />
-	    alpha -- The alpha channel to clear the canvas with.
-		</div>
-		<div>
-			This set the clearColor and the clearAlpha.
-		</div>
-
-		<h3>[method:number getClearColorHex]()</h3>
-		<div>
-			Returns the [page:number hex] color.
-		</div>
-
-		<h3>[method:number getClearAlpha]()</h3>
-		<div>
-			Returns the alpha value.
-		</div>
-
-		<h2>Empty Methods to Maintain Compatibility with [page:WebglRenderer]</h2>
-		<div>
-			[method:null clearColor]()<br/>
-			[method:null clearDepth]()<br/>
-			[method:null clearStencil]()<br/>
-			[method:null setFaceCulling]()<br/>
-			[method:null supportsVertexTextures]()<br/>
-			[method:number getMaxAnisotropy]() - returns 1 <br/>
-		</div>
-
-		<h2>Source</h2>
-
-		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
-	</body>
-</html>
+		<base href="../../" />
+		<script src="list.js"></script>
+		<script src="page.js"></script>
+		<link type="text/css" rel="stylesheet" href="page.css" />
+	</head>
+	<body>
+		<h1>[name]</h1>
+
+		<div class="desc">
+			The Canvas renderer displays your beautifully crafted scenes <em>not</em> using WebGL, but draws it using the (slower) <a href="http://drafts.htmlwg.org/2dcontext/html5_canvas_CR/Overview.html">Canvas 2D Context</a> API.<br /><br />
+			This renderer can be a nice fallback from [page:WebGLRenderer] for simple scenes:
+
+			<code>
+			function webglAvailable() {
+				try {
+					var canvas = document.createElement( 'canvas' );
+					return !!( window.WebGLRenderingContext && (
+						canvas.getContext( 'webgl' ) ||
+						canvas.getContext( 'experimental-webgl' ) )
+					);
+				} catch ( e ) {
+					return false;
+				}
+			}
+
+			if ( webglAvailable() ) {
+				renderer = new THREE.WebGLRenderer();
+			} else {
+				renderer = new THREE.CanvasRenderer();
+			}
+			</code>
+
+			Note: both WebGLRenderer and CanvasRenderer are embedded in the web page using an HTML5 &lt;canvas&gt; tag.
+			The "Canvas" in CanvasRenderer means it uses Canvas 2D instead of WebGL.<br /><br />
+
+			Don't confuse either CanvasRenderer with the SoftwareRenderer example, which simulates a screen buffer in a Javascript array.
+		</div>
+
+		<h2>Constructor</h2>
+
+
+		<h3>[name]([page:object parameters])</h3>
+        <div>parameters is an optional object with properties defining the renderer's behaviour. The constructor also accepts no parameters at all. In all cases, it will assume sane defaults when parameters are missing.</div>
+
+		<div>
+		canvas — A [page:Canvas] where the renderer draws its output.
+		</div>
+
+
+		<h2>Properties</h2>
+
+    <h3>[property:Object info]</h3>
+
+		<div>
+			An object with a series of statistical information about the graphics board memory and the rendering process. Useful for debugging or just for the sake of curiosity. The object contains the following fields:</div>
+			<ul>
+				<li>render:
+					<ul>
+						<li>vertices</li>
+						<li>faces</li>
+					</ul>
+				</li>
+			</ul>
+		</div>
+
+    <h3>[property:DOMElement domElement]</h3>
+
+		<div>
+			A [page:Canvas] where the renderer draws its output.<br />
+			This is automatically created by the renderer in the constructor (if not provided already); you just need to add it to your page.
+		</div>
+
+		<h3>[property:Boolean autoClear]</h3>
+		<div>
+      Defines whether the renderer should automatically clear its output before rendering.
+    </div>
+
+		<h3>[property:Boolean sortObjects]</h3>
+		<div>
+      Defines whether the renderer should sort objects. Default is true.<br />
+      Note: Sorting is used to attempt to properly render objects that have some degree of transparency.  By definition, sorting objects may not work in all cases.  Depending on the needs of application, it may be neccessary to turn off sorting and use other methods to deal with transparency rendering e.g. manually determining the object rendering order.
+    </div>
+
+		<h3>[property:boolean sortElements]</h3>
+		<div>
+			Defines whether the renderer should sort the face of each object. Default is true.
+		</div>
+
+
+		<h2>Methods</h2>
+
+		<h3>[method:null render]([page:Scene scene], [page:Camera camera])</h3>
+		<div>
+			scene -- The scene to render. <br />
+			camera -- the camera to view the scene.
+		</div>
+		<div>
+        Render a scene using a camera.
+		</div>
+
+		<h3>[method:null clear]()</h3>
+		<div>
+			Tells the renderer to clear its color drawing buffer with the clearcolor.
+		</div>
+
+		<h3>[method:null setClearColor]([page:Color color], [page:number alpha])</h3>
+		<div>
+			color -- The color to clear the canvas with. <br />
+			alpha -- The alpha channel to clear the canvas with.
+		</div>
+		<div>
+			This set the clearColor and the clearAlpha.
+		</div>
+
+
+		<h3>[method:null setSize]([page:Number width], [page:Number height])</h3>
+		<div>
+			width -- The width of the drawing canvas. <br />
+			height -- The height of the drawing canvas.
+		</div>
+		<div>
+			This set the size of the drawing canvas and if updateStyle is set, then the css of the canvas is updated too.
+		</div>
+
+		<h3>[method:null setClearColorHex]([page:number hex], [page:number alpha])</h3>
+		<div>
+			hex -- The the hexadecimal value of the color to clear the canvas with. <br />
+	    alpha -- The alpha channel to clear the canvas with.
+		</div>
+		<div>
+			This set the clearColor and the clearAlpha.
+		</div>
+
+		<h3>[method:number getClearColorHex]()</h3>
+		<div>
+			Returns the [page:number hex] color.
+		</div>
+
+		<h3>[method:number getClearAlpha]()</h3>
+		<div>
+			Returns the alpha value.
+		</div>
+
+		<h2>Empty Methods to Maintain Compatibility with [page:WebglRenderer]</h2>
+		<div>
+			[method:null clearColor]()<br/>
+			[method:null clearDepth]()<br/>
+			[method:null clearStencil]()<br/>
+			[method:null setFaceCulling]()<br/>
+			[method:null supportsVertexTextures]()<br/>
+			[method:number getMaxAnisotropy]() - returns 1 <br/>
+		</div>
+
+		<h2>Source</h2>
+
+		[link:https://github.com/mrdoob/three.js/blob/master/src/[path].js src/[path].js]
+	</body>
+</html>

+ 43 - 30
examples/js/loaders/AMFLoader.js

@@ -246,21 +246,13 @@ THREE.AMFLoader.prototype = {
 
 
 				} else if ( currVolumeNode.nodeName === "triangle" ) {
 				} else if ( currVolumeNode.nodeName === "triangle" ) {
 
 
-					var triangleNode = currVolumeNode.firstElementChild;
+					var v1 = currVolumeNode.getElementsByTagName("v1")[0].textContent;
+					var v2 = currVolumeNode.getElementsByTagName("v2")[0].textContent;
+					var v3 = currVolumeNode.getElementsByTagName("v3")[0].textContent;
 
 
-					while ( triangleNode ) {
-
-						if ( triangleNode.nodeName === "v1" ||
-								triangleNode.nodeName === "v2" ||
-								triangleNode.nodeName === "v3" ) {
-
-							volume.triangles.push( triangleNode.textContent );
-
-						}
-
-						triangleNode = triangleNode.nextElementSibling;
-
-					}
+					volume.triangles.push( v1 );
+					volume.triangles.push( v2 );
+					volume.triangles.push( v3 );
 
 
 				}
 				}
 
 
@@ -275,6 +267,7 @@ THREE.AMFLoader.prototype = {
 		function loadMeshVertices( node ) {
 		function loadMeshVertices( node ) {
 
 
 			var vertArray = [];
 			var vertArray = [];
+			var normalArray = [];
 			var currVerticesNode = node.firstElementChild;
 			var currVerticesNode = node.firstElementChild;
 
 
 			while ( currVerticesNode ) {
 			while ( currVerticesNode ) {
@@ -287,23 +280,26 @@ THREE.AMFLoader.prototype = {
 
 
 						if ( vNode.nodeName === "coordinates" ) {
 						if ( vNode.nodeName === "coordinates" ) {
 
 
-							var coordNode = vNode.firstElementChild;
-
-							while ( coordNode ) {
+							var x = vNode.getElementsByTagName("x")[0].textContent;
+							var y = vNode.getElementsByTagName("y")[0].textContent;
+							var z = vNode.getElementsByTagName("z")[0].textContent;
 
 
-								if ( coordNode.nodeName === "x" ||
-										 coordNode.nodeName === "y" ||
-										 coordNode.nodeName === "z" ) {
+							vertArray.push(x);
+							vertArray.push(y);
+							vertArray.push(z);
 
 
-									vertArray.push( coordNode.textContent );
+						} else if ( vNode.nodeName === "normal" ) {
 
 
-								}
+							var nx = vNode.getElementsByTagName("nx")[0].textContent;
+							var ny = vNode.getElementsByTagName("ny")[0].textContent;
+							var nz = vNode.getElementsByTagName("nz")[0].textContent;
 
 
-								coordNode = coordNode.nextElementSibling;
-
-							}
+							normalArray.push(nx);
+							normalArray.push(ny);
+							normalArray.push(nz);
 
 
 						}
 						}
+						
 						vNode = vNode.nextElementSibling;
 						vNode = vNode.nextElementSibling;
 
 
 					}
 					}
@@ -313,7 +309,7 @@ THREE.AMFLoader.prototype = {
 
 
 			}
 			}
 
 
-			return vertArray;
+			return { "vertices": vertArray, "normals": normalArray };
 
 
 		}
 		}
 
 
@@ -345,13 +341,16 @@ THREE.AMFLoader.prototype = {
 				} else if ( currObjNode.nodeName === "mesh" ) {
 				} else if ( currObjNode.nodeName === "mesh" ) {
 
 
 					var currMeshNode = currObjNode.firstElementChild;
 					var currMeshNode = currObjNode.firstElementChild;
-					var mesh = { "vertices": [], "volumes": [], "color": currColor };
+					var mesh = { "vertices": [], "normals": [], "volumes": [], "color": currColor };
 
 
 					while ( currMeshNode ) {
 					while ( currMeshNode ) {
 
 
 						if ( currMeshNode.nodeName === "vertices" ) {
 						if ( currMeshNode.nodeName === "vertices" ) {
 
 
-							mesh.vertices = mesh.vertices.concat( loadMeshVertices( currMeshNode ) );
+							var loadedVertices = loadMeshVertices( currMeshNode );
+
+							mesh.normals = mesh.normals.concat( loadedVertices.normals );
+							mesh.vertices = mesh.vertices.concat( loadedVertices.vertices );
 
 
 						} else if ( currMeshNode.nodeName === "volume" ) {
 						} else if ( currMeshNode.nodeName === "volume" ) {
 
 
@@ -433,10 +432,19 @@ THREE.AMFLoader.prototype = {
 
 
 			for ( var i = 0; i < meshes.length; i ++ ) {
 			for ( var i = 0; i < meshes.length; i ++ ) {
 
 
+				var objDefaultMaterial = defaultMaterial;
 				var mesh = meshes[ i ];
 				var mesh = meshes[ i ];
 				var meshVertices = Float32Array.from( mesh.vertices );
 				var meshVertices = Float32Array.from( mesh.vertices );
 				var vertices = new THREE.BufferAttribute( Float32Array.from( meshVertices ), 3 );
 				var vertices = new THREE.BufferAttribute( Float32Array.from( meshVertices ), 3 );
-				var objDefaultMaterial = defaultMaterial;
+				var meshNormals = null;
+				var normals = null;
+
+				if ( mesh.normals.length ) {
+
+					meshNormals = Float32Array.from( mesh.normals );
+					normals = new THREE.BufferAttribute( Float32Array.from( meshNormals ), 3 );
+
+				}
 
 
 				if ( mesh.color ) {
 				if ( mesh.color ) {
 
 
@@ -461,12 +469,17 @@ THREE.AMFLoader.prototype = {
 					var volume = volumes[ j ];
 					var volume = volumes[ j ];
 					var newGeometry = new THREE.BufferGeometry();
 					var newGeometry = new THREE.BufferGeometry();
 					var indexes = Uint32Array.from( volume.triangles );
 					var indexes = Uint32Array.from( volume.triangles );
-					var normals = new Uint32Array( vertices.array.length );
 					var material = objDefaultMaterial;
 					var material = objDefaultMaterial;
 
 
 					newGeometry.setIndex( new THREE.BufferAttribute( indexes, 1 ) );
 					newGeometry.setIndex( new THREE.BufferAttribute( indexes, 1 ) );
 					newGeometry.addAttribute( 'position', vertices.clone() );
 					newGeometry.addAttribute( 'position', vertices.clone() );
 
 
+					if( normals ) {
+
+						newGeometry.addAttribute( 'normal', normals.clone() );
+
+					}
+
 					if ( amfMaterials[ volume.materialid ] !== undefined ) {
 					if ( amfMaterials[ volume.materialid ] !== undefined ) {
 
 
 						material = amfMaterials[ volume.materialid ];
 						material = amfMaterials[ volume.materialid ];

+ 2 - 2
src/core/Geometry.js

@@ -865,11 +865,11 @@ THREE.Geometry.prototype = {
 
 
 	sortFacesByMaterialIndex: function () {
 	sortFacesByMaterialIndex: function () {
 
 
-		// tag faces
-
 		var faces = this.faces;
 		var faces = this.faces;
 		var length = faces.length;
 		var length = faces.length;
 
 
+		// tag faces
+
 		for ( var i = 0; i < length; i ++ ) {
 		for ( var i = 0; i < length; i ++ ) {
 
 
 			faces[ i ]._id = i;
 			faces[ i ]._id = i;

+ 1 - 1
src/extras/geometries/CircleBufferGeometry.js

@@ -28,7 +28,7 @@ THREE.CircleBufferGeometry = function ( radius, segments, thetaStart, thetaLengt
 	var uvs = new Float32Array( vertices * 2 );
 	var uvs = new Float32Array( vertices * 2 );
 
 
 	// center data is already zero, but need to set a few extras
 	// center data is already zero, but need to set a few extras
-	normals[ 3 ] = 1.0;
+	normals[ 2 ] = 1.0;
 	uvs[ 0 ] = 0.5;
 	uvs[ 0 ] = 0.5;
 	uvs[ 1 ] = 0.5;
 	uvs[ 1 ] = 0.5;
 
 

+ 4 - 4
src/renderers/WebGLRenderer.js

@@ -376,11 +376,11 @@ THREE.WebGLRenderer = function ( parameters ) {
 
 
 	this.getViewport = function ( dimensions ) {
 	this.getViewport = function ( dimensions ) {
 
 
-		dimensions.x = _viewportX;
-		dimensions.y = _viewportY;
+		dimensions.x = _viewportX / pixelRatio;
+		dimensions.y = _viewportY / pixelRatio;
 
 
-		dimensions.z = _viewportWidth;
-		dimensions.w = _viewportHeight;
+		dimensions.z = _viewportWidth / pixelRatio;
+		dimensions.w = _viewportHeight / pixelRatio;
 
 
 	};
 	};
 
 

+ 2 - 2
src/renderers/shaders/ShaderChunk/envmap_vertex.glsl

@@ -1,9 +1,9 @@
 #if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )
 #if defined( USE_ENVMAP ) && ! defined( USE_BUMPMAP ) && ! defined( USE_NORMALMAP ) && ! defined( PHONG )
 
 
-	vec3 worldNormal = transformDirection( objectNormal, modelMatrix );
-
 	vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );
 	vec3 cameraToVertex = normalize( worldPosition.xyz - cameraPosition );
 
 
+	vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );
+
 	#ifdef ENVMAP_MODE_REFLECTION
 	#ifdef ENVMAP_MODE_REFLECTION
 
 
 		vReflect = reflect( cameraToVertex, worldNormal );
 		vReflect = reflect( cameraToVertex, worldNormal );

+ 84 - 68
src/renderers/shaders/ShaderChunk/shadowmap_fragment.glsl

@@ -49,37 +49,44 @@
 
 
 					if( isPointLight ) {
 					if( isPointLight ) {
 
 
-						float cubeTexelSize = 1.0 / ( shadowMapSize[ i ].x * 0.25 );
-						vec3 baseDirection3D = normalize( lightToPosition );
-						vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeY );
-
-						initGridSamplingDisk();
-
-						float diskRadius = 1.25;
-						float numSamples = 1.0;
-						shadow = 0.0;
-
-						vec3 baseDirection = normalize( lightToPosition );
-						float curDistance = length( lightToPosition );
-
-						float dist = unpack1K( texture2D( shadowMap[ i ],  baseDirection2D ) ) + 0.1;
-						if ( curDistance >= dist )
-							shadow += 1.0;
-						
-						// evaluate each sampling direction
-						for( int s = 0; s < 20; s++ ) {
-						 
-							vec3 offset = gridSamplingDisk[ s ] * diskRadius * cubeTexelSize;
-							vec3 adjustedBaseDirection3D = baseDirection3D + offset;
-							vec2 adjustedBaseDirection2D = cubeToUV( adjustedBaseDirection3D, texelSizeY );
-							dist = unpack1K( texture2D( shadowMap[ i ],  adjustedBaseDirection2D ) ) + shadowBias[ i ];
-							if ( curDistance >= dist )
-								shadow += 1.0;
-							numSamples += 1.0;
-
-						}
-
-						shadow /= numSamples;
+						// bd3D = base direction 3D
+						vec3 bd3D = normalize( lightToPosition );
+						// dp = distance from light to fragment position
+						float dp = length( lightToPosition );
+
+						shadow = 0.0;						
+
+						// base measurement
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						// dr = disk radius
+						const float dr = 1.25;
+						// os = offset scale
+						float os = dr *  2.0 * texelSizeY;
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd0 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd1 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd2 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd3 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd4 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd5 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd6 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd7 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd8 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd9 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd10 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd11 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd12 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd13 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd14 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd15 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd16 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd17 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd18 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd19 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						shadow /= 21.0;
 
 
 					} else {
 					} else {
 
 
@@ -157,37 +164,44 @@
 
 
 					if( isPointLight ) {
 					if( isPointLight ) {
 
 
-						float cubeTexelSize = 1.0 / ( shadowMapSize[ i ].x * 0.25 );
-						vec3 baseDirection3D = normalize( lightToPosition );
-						vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeY );
-
-						initGridSamplingDisk();
-
-						float diskRadius = 2.25;
-						float numSamples = 1.0;
-						shadow = 0.0;
-
-						vec3 baseDirection = normalize( lightToPosition );
-						float curDistance = length( lightToPosition );
-
-						float dist = unpack1K( texture2D( shadowMap[ i ],  baseDirection2D ) ) + 0.1;
-						if ( curDistance >= dist )
-							shadow += 1.0;
-
-						// evaluate each sampling direction
-						for( int s = 0; s < 20; s++ ) {
-
-							vec3 offset = gridSamplingDisk[ s ] * diskRadius * cubeTexelSize;
-							vec3 adjustedBaseDirection3D = baseDirection3D + offset;
-							vec2 adjustedBaseDirection2D = cubeToUV( adjustedBaseDirection3D, texelSizeY );
-							dist = unpack1K( texture2D( shadowMap[ i ],  adjustedBaseDirection2D ) ) + shadowBias[ i ];
-							if ( curDistance >= dist )
-								shadow += 1.0;
-							numSamples += 1.0;
-
-						}
-
-						shadow /= numSamples;
+						// bd3D = base direction 3D
+						vec3 bd3D = normalize( lightToPosition );
+						// dp = distance from light to fragment position
+						float dp = length( lightToPosition );
+
+						shadow = 0.0;						
+
+						// base measurement
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						// dr = disk radius
+						const float dr = 2.25;
+						// os = offset scale
+						float os = dr *  2.0 * texelSizeY;
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd0 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd1 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd2 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd3 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd4 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd5 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd6 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd7 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd8 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd9 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd10 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd11 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd12 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd13 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd14 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd15 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd16 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd17 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd18 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D + gsd19 * os, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						shadow /= 21.0;
 
 
 					} else {
 					} else {
 
 
@@ -257,12 +271,14 @@
 
 
 					if( isPointLight ) {
 					if( isPointLight ) {
 
 
-						vec3 baseDirection3D = normalize( lightToPosition );
-						vec2 baseDirection2D = cubeToUV( baseDirection3D, texelSizeY );
-						vec4 data = texture2D( shadowMap[ i ],  baseDirection2D );
-						float dist = unpack1K( data ) + shadowBias[ i ];
-						if ( length( lightToPosition ) >= dist)
-							shadowColor = shadowColor * vec3( 1.0 - realShadowDarkness );
+						vec3 bd3D = normalize( lightToPosition );
+						float dp = length( lightToPosition );
+
+						float shadow = 0.0;
+
+						adjustShadowValue1K( dp, texture2D( shadowMap[ i ], cubeToUV( bd3D, texelSizeY ) ), shadowBias[ i ], shadow );
+
+						shadowColor = shadowColor * vec3( 1.0 - realShadowDarkness * shadow );
 
 
 					} else {
 					} else {
 
 

+ 32 - 39
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl

@@ -18,10 +18,15 @@
 
 
 	#if defined(POINT_LIGHT_SHADOWS)
 	#if defined(POINT_LIGHT_SHADOWS)
 
 
-		float unpack1K ( vec4 color ) {
+		// adjustShadowValue1K() upacks the depth value stored in @textureData, adds @bias to it, and then
+		// comapres the result with @testDepth. If @testDepth is larger than or equal to that result, then
+		// @shadowValue is incremented by 1.0.
 
 
-			const vec4 bitSh = vec4( 1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0 );
-			return dot( color, bitSh ) * 1000.0;
+		void adjustShadowValue1K( const float testDepth, const vec4 textureData, const float bias, inout float shadowValue ) {
+
+			const vec4 bitSh = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );
+			if( testDepth >= dot( textureData, bitSh ) * 1000.0 + bias )
+				shadowValue += 1.0;
 
 
 		}
 		}
 
 
@@ -56,7 +61,7 @@
 			// Apply scale to avoid seams
 			// Apply scale to avoid seams
 
 
 			// two texels less per square (one texel will do for NEAREST)
 			// two texels less per square (one texel will do for NEAREST)
-			v *= scaleToCube * ( 1.0 - 4.0 * texelSizeY );
+			v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY );
 
 
 			// Unwrap
 			// Unwrap
 
 
@@ -96,41 +101,29 @@
 
 
 		}
 		}
 
 
-		vec3 gridSamplingDisk[ 20 ];
-		bool gridSamplingInitialized = false;
-
-		void initGridSamplingDisk() {
-
-			if( gridSamplingInitialized ) {
-
-				return;
-
-			}
-
-			gridSamplingDisk[0] = vec3(1, 1, 1);
-			gridSamplingDisk[1] = vec3(1, -1, 1);
-			gridSamplingDisk[2] = vec3(-1, -1, 1);
-			gridSamplingDisk[3] = vec3(-1, 1, 1);
-			gridSamplingDisk[4] = vec3(1, 1, -1);
-			gridSamplingDisk[5] = vec3(1, -1, -1);
-			gridSamplingDisk[6] = vec3(-1, -1, -1);
-			gridSamplingDisk[7] = vec3(-1, 1, -1);
-			gridSamplingDisk[8] = vec3(1, 1, 0);
-			gridSamplingDisk[9] = vec3(1, -1, 0);
-			gridSamplingDisk[10] = vec3(-1, -1, 0);
-			gridSamplingDisk[11] = vec3(-1, 1, 0);
-			gridSamplingDisk[12] = vec3(1, 0, 1);
-			gridSamplingDisk[13] = vec3(-1, 0, 1);
-			gridSamplingDisk[14] = vec3(1, 0, -1);
-			gridSamplingDisk[15] = vec3(-1, 0, -1);
-			gridSamplingDisk[16] = vec3(0, 1, 1);
-			gridSamplingDisk[17] = vec3(0, -1, 1);
-			gridSamplingDisk[18] = vec3(0, -1, -1);
-			gridSamplingDisk[19] = vec3(0, 1, -1);
-
-			gridSamplingInitialized = true;
-
-		}
+		// gsdXX = grid sampling disk XX
+		// these values are used when rendering PCF shadow maps for point lights
+		
+		const vec3 gsd0 = vec3( 1, 1, 1 );
+		const vec3 gsd1 = vec3( 1, - 1, 1 );
+		const vec3 gsd2 = vec3( - 1, - 1, 1 );
+		const vec3 gsd3 = vec3( - 1, 1, 1 );
+		const vec3 gsd4 = vec3( 1, 1, - 1 );
+		const vec3 gsd5 = vec3( 1, - 1, - 1 );
+		const vec3 gsd6 = vec3( - 1, - 1, - 1 );
+		const vec3 gsd7 = vec3( -1, 1, - 1 );
+		const vec3 gsd8 = vec3( 1, 1, 0 );
+		const vec3 gsd9 = vec3( 1, - 1, 0 );
+		const vec3 gsd10 = vec3( - 1, - 1, 0 );
+		const vec3 gsd11 = vec3( - 1, 1, 0 );
+		const vec3 gsd12 = vec3( 1, 0, 1 );
+		const vec3 gsd13 = vec3( - 1, 0, 1 );
+		const vec3 gsd14 = vec3( 1, 0, - 1 );
+		const vec3 gsd15 = vec3( - 1, 0, - 1 );
+		const vec3 gsd16 = vec3( 0, 1, 1 );
+		const vec3 gsd17 = vec3( 0, - 1, 1 );
+		const vec3 gsd18 = vec3( 0, - 1, - 1 );
+		const vec3 gsd19 = vec3( 0, 1, - 1 );
 
 
 	#endif
 	#endif
 
 

+ 5 - 5
src/renderers/webgl/WebGLShadowMap.js

@@ -122,6 +122,9 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 
 		_state.setDepthTest( true );
 		_state.setDepthTest( true );
 
 
+		// save the existing viewport so it can be restored later
+		_renderer.getViewport( _vector4 );
+
 		// render depth map
 		// render depth map
 
 
 		for ( var i = 0, il = _lights.length; i < il; i ++ ) {
 		for ( var i = 0, il = _lights.length; i < il; i ++ ) {
@@ -226,9 +229,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 			_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
 			_lightPositionWorld.setFromMatrixPosition( light.matrixWorld );
 			shadowCamera.position.copy( _lightPositionWorld );
 			shadowCamera.position.copy( _lightPositionWorld );
 
 
-			// save the existing viewport so it can be restored later
-			_renderer.getViewport( _vector4 );
-
 			_renderer.setRenderTarget( shadowMap );
 			_renderer.setRenderTarget( shadowMap );
 			_renderer.clear();
 			_renderer.clear();
 
 
@@ -321,6 +321,8 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 
 			}
 			}
 
 
+			_renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w );
+
 		}
 		}
 
 
 		// restore GL state
 		// restore GL state
@@ -337,8 +339,6 @@ THREE.WebGLShadowMap = function ( _renderer, _lights, _objects ) {
 
 
 		}
 		}
 
 
-		_renderer.setViewport( _vector4.x, _vector4.y, _vector4.z, _vector4.w );
-
 		_renderer.resetGLState();
 		_renderer.resetGLState();
 
 
 		scope.needsUpdate = false;
 		scope.needsUpdate = false;

+ 20 - 6
utils/exporters/blender/addons/io_three/exporter/api/animation.py

@@ -4,7 +4,7 @@ Module for handling the parsing of skeletal animation data.
 
 
 import math
 import math
 import mathutils
 import mathutils
-from bpy import data, context
+from bpy import data, context, ops
 from .. import constants, logger
 from .. import constants, logger
 
 
 
 
@@ -171,11 +171,25 @@ def _parse_pose_action(action, armature, options):
     :param options:
     :param options:
 
 
     """
     """
-    # @TODO: this seems to fail in batch mode meaning the
-    #        user has to have th GUI open. need to improve
-    #        this logic to allow batch processing, if Blender
-    #        chooses to behave....
-    current_context = context.area.type
+    try:
+        current_context = context.area.type
+    except AttributeError:
+        for window in context.window_manager.windows:
+            screen = window.screen
+            for area in screen.areas:
+                if area.type != 'VIEW_3D':
+                    continue
+
+                override = {
+                    'window': window,
+                    'screen': screen,
+                    'area': area
+                }
+                ops.screen.screen_full_area(override)
+                break
+        current_context = context.area.type
+
+    context.scene.objects.active = armature
     context.area.type = 'DOPESHEET_EDITOR'
     context.area.type = 'DOPESHEET_EDITOR'
     context.space_data.mode = 'ACTION'
     context.space_data.mode = 'ACTION'
     context.area.spaces.active.action = action
     context.area.spaces.active.action = action

+ 1 - 1
utils/exporters/blender/tests/scripts/js/review.js

@@ -122,7 +122,7 @@ function loadObject( data ) {
 function loadGeometry( data, url ) {
 function loadGeometry( data, url ) {
 
 
     var loader = new THREE.JSONLoader();
     var loader = new THREE.JSONLoader();
-    var texturePath = loader.extractUrlBase( url );
+    var texturePath = THREE.Loader.prototype.extractUrlBase( url );
     data = loader.parse( data, texturePath );
     data = loader.parse( data, texturePath );
 
 
     if ( data.materials === undefined ) {
     if ( data.materials === undefined ) {

+ 1 - 1
utils/exporters/blender/tests/scripts/test_geometry_animation.bash

@@ -4,6 +4,6 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 source "$DIR/setup_test_env.bash"
 source "$DIR/setup_test_env.bash"
 
 
 blender --background $BLEND/anim.blend --python $PYSCRIPT -- \
 blender --background $BLEND/anim.blend --python $PYSCRIPT -- \
-    $JSON --vertices --faces --animation --bones --skinning \
+    $JSON --vertices --faces --animation rest --bones --skinning \
     --embedAnimation
     --embedAnimation
 makereview $@ --tag $(tagname)
 makereview $@ --tag $(tagname)

部分文件因文件數量過多而無法顯示