浏览代码

Updated builds.

Mr.doob 4 年之前
父节点
当前提交
1e05a0d28f
共有 3 个文件被更改,包括 127 次插入825 次删除
  1. 55 775
      build/three.js
  2. 0 0
      build/three.min.js
  3. 72 50
      build/three.module.js

+ 55 - 775
build/three.js

@@ -9,728 +9,6 @@
 	(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.THREE = {}));
 }(this, (function (exports) { 'use strict';
 
-	/**
-	 * Copyright (c) 2014-present, Facebook, Inc.
-	 *
-	 * This source code is licensed under the MIT license found in the
-	 * LICENSE file in the root directory of this source tree.
-	 */
-	var runtime = function (exports) {
-
-		var Op = Object.prototype;
-		var hasOwn = Op.hasOwnProperty;
-		var undefined$1; // More compressible than void 0.
-
-		var $Symbol = typeof Symbol === "function" ? Symbol : {};
-		var iteratorSymbol = $Symbol.iterator || "@@iterator";
-		var asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator";
-		var toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
-
-		function define(obj, key, value) {
-			Object.defineProperty(obj, key, {
-				value: value,
-				enumerable: true,
-				configurable: true,
-				writable: true
-			});
-			return obj[key];
-		}
-
-		try {
-			// IE 8 has a broken Object.defineProperty that only works on DOM objects.
-			define({}, "");
-		} catch (err) {
-			define = function (obj, key, value) {
-				return obj[key] = value;
-			};
-		}
-
-		function wrap(innerFn, outerFn, self, tryLocsList) {
-			// If outerFn provided and outerFn.prototype is a Generator, then outerFn.prototype instanceof Generator.
-			var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator;
-			var generator = Object.create(protoGenerator.prototype);
-			var context = new Context(tryLocsList || []); // The ._invoke method unifies the implementations of the .next,
-			// .throw, and .return methods.
-
-			generator._invoke = makeInvokeMethod(innerFn, self, context);
-			return generator;
-		}
-
-		exports.wrap = wrap; // Try/catch helper to minimize deoptimizations. Returns a completion
-		// record like context.tryEntries[i].completion. This interface could
-		// have been (and was previously) designed to take a closure to be
-		// invoked without arguments, but in all the cases we care about we
-		// already have an existing method we want to call, so there's no need
-		// to create a new function object. We can even get away with assuming
-		// the method takes exactly one argument, since that happens to be true
-		// in every case, so we don't have to touch the arguments object. The
-		// only additional allocation required is the completion record, which
-		// has a stable shape and so hopefully should be cheap to allocate.
-
-		function tryCatch(fn, obj, arg) {
-			try {
-				return {
-					type: "normal",
-					arg: fn.call(obj, arg)
-				};
-			} catch (err) {
-				return {
-					type: "throw",
-					arg: err
-				};
-			}
-		}
-
-		var GenStateSuspendedStart = "suspendedStart";
-		var GenStateSuspendedYield = "suspendedYield";
-		var GenStateExecuting = "executing";
-		var GenStateCompleted = "completed"; // Returning this object from the innerFn has the same effect as
-		// breaking out of the dispatch switch statement.
-
-		var ContinueSentinel = {}; // Dummy constructor functions that we use as the .constructor and
-		// .constructor.prototype properties for functions that return Generator
-		// objects. For full spec compliance, you may wish to configure your
-		// minifier not to mangle the names of these two functions.
-
-		function Generator() {}
-
-		function GeneratorFunction() {}
-
-		function GeneratorFunctionPrototype() {} // This is a polyfill for %IteratorPrototype% for environments that
-		// don't natively support it.
-
-
-		var IteratorPrototype = {};
-
-		IteratorPrototype[iteratorSymbol] = function () {
-			return this;
-		};
-
-		var getProto = Object.getPrototypeOf;
-		var NativeIteratorPrototype = getProto && getProto(getProto(values([])));
-
-		if (NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol)) {
-			// This environment has a native %IteratorPrototype%; use it instead
-			// of the polyfill.
-			IteratorPrototype = NativeIteratorPrototype;
-		}
-
-		var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
-		GeneratorFunction.prototype = Gp.constructor = GeneratorFunctionPrototype;
-		GeneratorFunctionPrototype.constructor = GeneratorFunction;
-		GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"); // Helper for defining the .next, .throw, and .return methods of the
-		// Iterator interface in terms of a single ._invoke method.
-
-		function defineIteratorMethods(prototype) {
-			["next", "throw", "return"].forEach(function (method) {
-				define(prototype, method, function (arg) {
-					return this._invoke(method, arg);
-				});
-			});
-		}
-
-		exports.isGeneratorFunction = function (genFun) {
-			var ctor = typeof genFun === "function" && genFun.constructor;
-			return ctor ? ctor === GeneratorFunction || // For the native GeneratorFunction constructor, the best we can
-			// do is to check its .name property.
-			(ctor.displayName || ctor.name) === "GeneratorFunction" : false;
-		};
-
-		exports.mark = function (genFun) {
-			if (Object.setPrototypeOf) {
-				Object.setPrototypeOf(genFun, GeneratorFunctionPrototype);
-			} else {
-				genFun.__proto__ = GeneratorFunctionPrototype;
-				define(genFun, toStringTagSymbol, "GeneratorFunction");
-			}
-
-			genFun.prototype = Object.create(Gp);
-			return genFun;
-		}; // Within the body of any async function, `await x` is transformed to
-		// `yield regeneratorRuntime.awrap(x)`, so that the runtime can test
-		// `hasOwn.call(value, "__await")` to determine if the yielded value is
-		// meant to be awaited.
-
-
-		exports.awrap = function (arg) {
-			return {
-				__await: arg
-			};
-		};
-
-		function AsyncIterator(generator, PromiseImpl) {
-			function invoke(method, arg, resolve, reject) {
-				var record = tryCatch(generator[method], generator, arg);
-
-				if (record.type === "throw") {
-					reject(record.arg);
-				} else {
-					var result = record.arg;
-					var value = result.value;
-
-					if (value && typeof value === "object" && hasOwn.call(value, "__await")) {
-						return PromiseImpl.resolve(value.__await).then(function (value) {
-							invoke("next", value, resolve, reject);
-						}, function (err) {
-							invoke("throw", err, resolve, reject);
-						});
-					}
-
-					return PromiseImpl.resolve(value).then(function (unwrapped) {
-						// When a yielded Promise is resolved, its final value becomes
-						// the .value of the Promise<{value,done}> result for the
-						// current iteration.
-						result.value = unwrapped;
-						resolve(result);
-					}, function (error) {
-						// If a rejected Promise was yielded, throw the rejection back
-						// into the async generator function so it can be handled there.
-						return invoke("throw", error, resolve, reject);
-					});
-				}
-			}
-
-			var previousPromise;
-
-			function enqueue(method, arg) {
-				function callInvokeWithMethodAndArg() {
-					return new PromiseImpl(function (resolve, reject) {
-						invoke(method, arg, resolve, reject);
-					});
-				}
-
-				return previousPromise = // If enqueue has been called before, then we want to wait until
-				// all previous Promises have been resolved before calling invoke,
-				// so that results are always delivered in the correct order. If
-				// enqueue has not been called before, then it is important to
-				// call invoke immediately, without waiting on a callback to fire,
-				// so that the async generator function has the opportunity to do
-				// any necessary setup in a predictable way. This predictability
-				// is why the Promise constructor synchronously invokes its
-				// executor callback, and why async functions synchronously
-				// execute code before the first await. Since we implement simple
-				// async functions in terms of async generators, it is especially
-				// important to get this right, even though it requires care.
-				previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, // Avoid propagating failures to Promises returned by later
-				// invocations of the iterator.
-				callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
-			} // Define the unified helper method that is used to implement .next,
-			// .throw, and .return (see defineIteratorMethods).
-
-
-			this._invoke = enqueue;
-		}
-
-		defineIteratorMethods(AsyncIterator.prototype);
-
-		AsyncIterator.prototype[asyncIteratorSymbol] = function () {
-			return this;
-		};
-
-		exports.AsyncIterator = AsyncIterator; // Note that simple async functions are implemented on top of
-		// AsyncIterator objects; they just return a Promise for the value of
-		// the final result produced by the iterator.
-
-		exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
-			if (PromiseImpl === void 0) PromiseImpl = Promise;
-			var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
-			return exports.isGeneratorFunction(outerFn) ? iter // If outerFn is a generator, return the full iterator.
-			: iter.next().then(function (result) {
-				return result.done ? result.value : iter.next();
-			});
-		};
-
-		function makeInvokeMethod(innerFn, self, context) {
-			var state = GenStateSuspendedStart;
-			return function invoke(method, arg) {
-				if (state === GenStateExecuting) {
-					throw new Error("Generator is already running");
-				}
-
-				if (state === GenStateCompleted) {
-					if (method === "throw") {
-						throw arg;
-					} // Be forgiving, per 25.3.3.3.3 of the spec:
-					// https://people.mozilla.org/~jorendorff/es6-draft.html#sec-generatorresume
-
-
-					return doneResult();
-				}
-
-				context.method = method;
-				context.arg = arg;
-
-				while (true) {
-					var delegate = context.delegate;
-
-					if (delegate) {
-						var delegateResult = maybeInvokeDelegate(delegate, context);
-
-						if (delegateResult) {
-							if (delegateResult === ContinueSentinel) continue;
-							return delegateResult;
-						}
-					}
-
-					if (context.method === "next") {
-						// Setting context._sent for legacy support of Babel's
-						// function.sent implementation.
-						context.sent = context._sent = context.arg;
-					} else if (context.method === "throw") {
-						if (state === GenStateSuspendedStart) {
-							state = GenStateCompleted;
-							throw context.arg;
-						}
-
-						context.dispatchException(context.arg);
-					} else if (context.method === "return") {
-						context.abrupt("return", context.arg);
-					}
-
-					state = GenStateExecuting;
-					var record = tryCatch(innerFn, self, context);
-
-					if (record.type === "normal") {
-						// If an exception is thrown from innerFn, we leave state ===
-						// GenStateExecuting and loop back for another invocation.
-						state = context.done ? GenStateCompleted : GenStateSuspendedYield;
-
-						if (record.arg === ContinueSentinel) {
-							continue;
-						}
-
-						return {
-							value: record.arg,
-							done: context.done
-						};
-					} else if (record.type === "throw") {
-						state = GenStateCompleted; // Dispatch the exception by looping back around to the
-						// context.dispatchException(context.arg) call above.
-
-						context.method = "throw";
-						context.arg = record.arg;
-					}
-				}
-			};
-		} // Call delegate.iterator[context.method](context.arg) and handle the
-		// result, either by returning a { value, done } result from the
-		// delegate iterator, or by modifying context.method and context.arg,
-		// setting context.delegate to null, and returning the ContinueSentinel.
-
-
-		function maybeInvokeDelegate(delegate, context) {
-			var method = delegate.iterator[context.method];
-
-			if (method === undefined$1) {
-				// A .throw or .return when the delegate iterator has no .throw
-				// method always terminates the yield* loop.
-				context.delegate = null;
-
-				if (context.method === "throw") {
-					// Note: ["return"] must be used for ES3 parsing compatibility.
-					if (delegate.iterator["return"]) {
-						// If the delegate iterator has a return method, give it a
-						// chance to clean up.
-						context.method = "return";
-						context.arg = undefined$1;
-						maybeInvokeDelegate(delegate, context);
-
-						if (context.method === "throw") {
-							// If maybeInvokeDelegate(context) changed context.method from
-							// "return" to "throw", let that override the TypeError below.
-							return ContinueSentinel;
-						}
-					}
-
-					context.method = "throw";
-					context.arg = new TypeError("The iterator does not provide a 'throw' method");
-				}
-
-				return ContinueSentinel;
-			}
-
-			var record = tryCatch(method, delegate.iterator, context.arg);
-
-			if (record.type === "throw") {
-				context.method = "throw";
-				context.arg = record.arg;
-				context.delegate = null;
-				return ContinueSentinel;
-			}
-
-			var info = record.arg;
-
-			if (!info) {
-				context.method = "throw";
-				context.arg = new TypeError("iterator result is not an object");
-				context.delegate = null;
-				return ContinueSentinel;
-			}
-
-			if (info.done) {
-				// Assign the result of the finished delegate to the temporary
-				// variable specified by delegate.resultName (see delegateYield).
-				context[delegate.resultName] = info.value; // Resume execution at the desired location (see delegateYield).
-
-				context.next = delegate.nextLoc; // If context.method was "throw" but the delegate handled the
-				// exception, let the outer generator proceed normally. If
-				// context.method was "next", forget context.arg since it has been
-				// "consumed" by the delegate iterator. If context.method was
-				// "return", allow the original .return call to continue in the
-				// outer generator.
-
-				if (context.method !== "return") {
-					context.method = "next";
-					context.arg = undefined$1;
-				}
-			} else {
-				// Re-yield the result returned by the delegate method.
-				return info;
-			} // The delegate iterator is finished, so forget it and continue with
-			// the outer generator.
-
-
-			context.delegate = null;
-			return ContinueSentinel;
-		} // Define Generator.prototype.{next,throw,return} in terms of the
-		// unified ._invoke helper method.
-
-
-		defineIteratorMethods(Gp);
-		define(Gp, toStringTagSymbol, "Generator"); // A Generator should always return itself as the iterator object when the
-		// @@iterator function is called on it. Some browsers' implementations of the
-		// iterator prototype chain incorrectly implement this, causing the Generator
-		// object to not be returned from this call. This ensures that doesn't happen.
-		// See https://github.com/facebook/regenerator/issues/274 for more details.
-
-		Gp[iteratorSymbol] = function () {
-			return this;
-		};
-
-		Gp.toString = function () {
-			return "[object Generator]";
-		};
-
-		function pushTryEntry(locs) {
-			var entry = {
-				tryLoc: locs[0]
-			};
-
-			if (1 in locs) {
-				entry.catchLoc = locs[1];
-			}
-
-			if (2 in locs) {
-				entry.finallyLoc = locs[2];
-				entry.afterLoc = locs[3];
-			}
-
-			this.tryEntries.push(entry);
-		}
-
-		function resetTryEntry(entry) {
-			var record = entry.completion || {};
-			record.type = "normal";
-			delete record.arg;
-			entry.completion = record;
-		}
-
-		function Context(tryLocsList) {
-			// The root entry object (effectively a try statement without a catch
-			// or a finally block) gives us a place to store values thrown from
-			// locations where there is no enclosing try statement.
-			this.tryEntries = [{
-				tryLoc: "root"
-			}];
-			tryLocsList.forEach(pushTryEntry, this);
-			this.reset(true);
-		}
-
-		exports.keys = function (object) {
-			var keys = [];
-
-			for (var key in object) {
-				keys.push(key);
-			}
-
-			keys.reverse(); // Rather than returning an object with a next method, we keep
-			// things simple and return the next function itself.
-
-			return function next() {
-				while (keys.length) {
-					var key = keys.pop();
-
-					if (key in object) {
-						next.value = key;
-						next.done = false;
-						return next;
-					}
-				} // To avoid creating an additional object, we just hang the .value
-				// and .done properties off the next function object itself. This
-				// also ensures that the minifier will not anonymize the function.
-
-
-				next.done = true;
-				return next;
-			};
-		};
-
-		function values(iterable) {
-			if (iterable) {
-				var iteratorMethod = iterable[iteratorSymbol];
-
-				if (iteratorMethod) {
-					return iteratorMethod.call(iterable);
-				}
-
-				if (typeof iterable.next === "function") {
-					return iterable;
-				}
-
-				if (!isNaN(iterable.length)) {
-					var i = -1,
-							next = function next() {
-						while (++i < iterable.length) {
-							if (hasOwn.call(iterable, i)) {
-								next.value = iterable[i];
-								next.done = false;
-								return next;
-							}
-						}
-
-						next.value = undefined$1;
-						next.done = true;
-						return next;
-					};
-
-					return next.next = next;
-				}
-			} // Return an iterator with no values.
-
-
-			return {
-				next: doneResult
-			};
-		}
-
-		exports.values = values;
-
-		function doneResult() {
-			return {
-				value: undefined$1,
-				done: true
-			};
-		}
-
-		Context.prototype = {
-			constructor: Context,
-			reset: function (skipTempReset) {
-				this.prev = 0;
-				this.next = 0; // Resetting context._sent for legacy support of Babel's
-				// function.sent implementation.
-
-				this.sent = this._sent = undefined$1;
-				this.done = false;
-				this.delegate = null;
-				this.method = "next";
-				this.arg = undefined$1;
-				this.tryEntries.forEach(resetTryEntry);
-
-				if (!skipTempReset) {
-					for (var name in this) {
-						// Not sure about the optimal order of these conditions:
-						if (name.charAt(0) === "t" && hasOwn.call(this, name) && !isNaN(+name.slice(1))) {
-							this[name] = undefined$1;
-						}
-					}
-				}
-			},
-			stop: function () {
-				this.done = true;
-				var rootEntry = this.tryEntries[0];
-				var rootRecord = rootEntry.completion;
-
-				if (rootRecord.type === "throw") {
-					throw rootRecord.arg;
-				}
-
-				return this.rval;
-			},
-			dispatchException: function (exception) {
-				if (this.done) {
-					throw exception;
-				}
-
-				var context = this;
-
-				function handle(loc, caught) {
-					record.type = "throw";
-					record.arg = exception;
-					context.next = loc;
-
-					if (caught) {
-						// If the dispatched exception was caught by a catch block,
-						// then let that catch block handle the exception normally.
-						context.method = "next";
-						context.arg = undefined$1;
-					}
-
-					return !!caught;
-				}
-
-				for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-					var entry = this.tryEntries[i];
-					var record = entry.completion;
-
-					if (entry.tryLoc === "root") {
-						// Exception thrown outside of any try block that could handle
-						// it, so set the completion value of the entire function to
-						// throw the exception.
-						return handle("end");
-					}
-
-					if (entry.tryLoc <= this.prev) {
-						var hasCatch = hasOwn.call(entry, "catchLoc");
-						var hasFinally = hasOwn.call(entry, "finallyLoc");
-
-						if (hasCatch && hasFinally) {
-							if (this.prev < entry.catchLoc) {
-								return handle(entry.catchLoc, true);
-							} else if (this.prev < entry.finallyLoc) {
-								return handle(entry.finallyLoc);
-							}
-						} else if (hasCatch) {
-							if (this.prev < entry.catchLoc) {
-								return handle(entry.catchLoc, true);
-							}
-						} else if (hasFinally) {
-							if (this.prev < entry.finallyLoc) {
-								return handle(entry.finallyLoc);
-							}
-						} else {
-							throw new Error("try statement without catch or finally");
-						}
-					}
-				}
-			},
-			abrupt: function (type, arg) {
-				for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-					var entry = this.tryEntries[i];
-
-					if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
-						var finallyEntry = entry;
-						break;
-					}
-				}
-
-				if (finallyEntry && (type === "break" || type === "continue") && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc) {
-					// Ignore the finally entry if control is not jumping to a
-					// location outside the try/catch block.
-					finallyEntry = null;
-				}
-
-				var record = finallyEntry ? finallyEntry.completion : {};
-				record.type = type;
-				record.arg = arg;
-
-				if (finallyEntry) {
-					this.method = "next";
-					this.next = finallyEntry.finallyLoc;
-					return ContinueSentinel;
-				}
-
-				return this.complete(record);
-			},
-			complete: function (record, afterLoc) {
-				if (record.type === "throw") {
-					throw record.arg;
-				}
-
-				if (record.type === "break" || record.type === "continue") {
-					this.next = record.arg;
-				} else if (record.type === "return") {
-					this.rval = this.arg = record.arg;
-					this.method = "return";
-					this.next = "end";
-				} else if (record.type === "normal" && afterLoc) {
-					this.next = afterLoc;
-				}
-
-				return ContinueSentinel;
-			},
-			finish: function (finallyLoc) {
-				for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-					var entry = this.tryEntries[i];
-
-					if (entry.finallyLoc === finallyLoc) {
-						this.complete(entry.completion, entry.afterLoc);
-						resetTryEntry(entry);
-						return ContinueSentinel;
-					}
-				}
-			},
-			"catch": function (tryLoc) {
-				for (var i = this.tryEntries.length - 1; i >= 0; --i) {
-					var entry = this.tryEntries[i];
-
-					if (entry.tryLoc === tryLoc) {
-						var record = entry.completion;
-
-						if (record.type === "throw") {
-							var thrown = record.arg;
-							resetTryEntry(entry);
-						}
-
-						return thrown;
-					}
-				} // The context.catch method must only be called with a location
-				// argument that corresponds to a known catch block.
-
-
-				throw new Error("illegal catch attempt");
-			},
-			delegateYield: function (iterable, resultName, nextLoc) {
-				this.delegate = {
-					iterator: values(iterable),
-					resultName: resultName,
-					nextLoc: nextLoc
-				};
-
-				if (this.method === "next") {
-					// Deliberately forget the last sent value so that we don't
-					// accidentally pass it on to the delegate.
-					this.arg = undefined$1;
-				}
-
-				return ContinueSentinel;
-			}
-		}; // Regardless of whether this script is executing as a CommonJS module
-		// or not, return the runtime object so that we can declare the variable
-		// regeneratorRuntime in the outer scope, which allows this module to be
-		// injected easily by `bin/regenerator --include-runtime script.js`.
-
-		return exports;
-	}( // If this script is executing as a CommonJS module, use module.exports
-	// as the regeneratorRuntime namespace. Otherwise create a new empty
-	// object. Either way, the resulting object will be used to initialize
-	// the regeneratorRuntime variable at the top of this file.
-	typeof module === "object" ? module.exports : {});
-
-	try {
-		regeneratorRuntime = runtime;
-	} catch (accidentalStrictMode) {
-		// This module should not be running in strict mode, so the above
-		// assignment should always work unless something is misconfigured. Just
-		// in case runtime.js accidentally runs in strict mode, we can escape
-		// strict mode using a global Function call. This could conceivably fail
-		// if a Content Security Policy forbids using Function, but in that case
-		// the proper solution is to fix the accidental strict mode problem. If
-		// you've misconfigured your bundler to force strict mode and applied a
-		// CSP to forbid Function, and you're not willing to fix either of those
-		// problems, please detail your unique predicament in a GitHub issue.
-		Function("r", "regeneratorRuntime = r")(runtime);
-	}
-
 	const REVISION = '127dev';
 	const MOUSE = {
 		LEFT: 0,
@@ -15017,6 +14295,8 @@
 		const depthBuffer = new DepthBuffer();
 		const stencilBuffer = new StencilBuffer();
 		let enabledCapabilities = {};
+		let xrFramebuffer = null;
+		let currentBoundFramebuffers = {};
 		let currentProgram = null;
 		let currentBlendingEnabled = false;
 		let currentBlending = null;
@@ -15093,6 +14373,23 @@
 			}
 		}
 
+		function bindXRFramebuffer(framebuffer) {
+			if (framebuffer !== xrFramebuffer) {
+				gl.bindFramebuffer(36160, framebuffer);
+				xrFramebuffer = framebuffer;
+			}
+		}
+
+		function bindFramebuffer(target, framebuffer) {
+			if (target === 36009) target = 36160;
+			if (framebuffer === null && xrFramebuffer !== null) framebuffer = xrFramebuffer; // use active XR framebuffer if available
+
+			if (currentBoundFramebuffers[target] !== framebuffer) {
+				gl.bindFramebuffer(target, framebuffer);
+				currentBoundFramebuffers[target] = framebuffer;
+			}
+		}
+
 		function useProgram(program) {
 			if (currentProgram !== program) {
 				gl.useProgram(program);
@@ -15430,6 +14727,15 @@
 			gl.frontFace(2305);
 			gl.polygonOffset(0, 0);
 			gl.activeTexture(33984);
+
+			if (isWebGL2 === true) {
+				gl.bindFramebuffer(36009, null); // Equivalent to 36160
+
+				gl.bindFramebuffer(36008, null);
+			} else {
+				gl.bindFramebuffer(36160, null);
+			}
+
 			gl.useProgram(null);
 			gl.lineWidth(1);
 			gl.scissor(0, 0, gl.canvas.width, gl.canvas.height);
@@ -15438,6 +14744,8 @@
 			enabledCapabilities = {};
 			currentTextureSlot = null;
 			currentBoundTextures = {};
+			xrFramebuffer = null;
+			currentBoundFramebuffers = {};
 			currentProgram = null;
 			currentBlendingEnabled = false;
 			currentBlending = null;
@@ -15468,6 +14776,8 @@
 			},
 			enable: enable,
 			disable: disable,
+			bindFramebuffer: bindFramebuffer,
+			bindXRFramebuffer: bindXRFramebuffer,
 			useProgram: useProgram,
 			setBlending: setBlending,
 			setMaterial: setMaterial,
@@ -16065,11 +15375,11 @@
 				state.texImage2D(textureTarget, 0, glInternalFormat, renderTarget.width, renderTarget.height, 0, glFormat, glType, null);
 			}
 
-			_gl.bindFramebuffer(36160, framebuffer);
+			state.bindFramebuffer(36160, framebuffer);
 
 			_gl.framebufferTexture2D(36160, attachment, textureTarget, properties.get(texture).__webglTexture, 0);
 
-			_gl.bindFramebuffer(36160, null);
+			state.bindFramebuffer(36160, null);
 		} // Setup storage for internal depth/stencil buffers and bind to correct framebuffer
 
 
@@ -16130,8 +15440,7 @@
 		function setupDepthTexture(framebuffer, renderTarget) {
 			const isCube = renderTarget && renderTarget.isWebGLCubeRenderTarget;
 			if (isCube) throw new Error('Depth Texture with cube render targets is not supported');
-
-			_gl.bindFramebuffer(36160, framebuffer);
+			state.bindFramebuffer(36160, framebuffer);
 
 			if (!(renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture)) {
 				throw new Error('renderTarget.depthTexture must be an instance of THREE.DepthTexture');
@@ -16170,20 +15479,18 @@
 					renderTargetProperties.__webglDepthbuffer = [];
 
 					for (let i = 0; i < 6; i++) {
-						_gl.bindFramebuffer(36160, renderTargetProperties.__webglFramebuffer[i]);
-
+						state.bindFramebuffer(36160, renderTargetProperties.__webglFramebuffer[i]);
 						renderTargetProperties.__webglDepthbuffer[i] = _gl.createRenderbuffer();
 						setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer[i], renderTarget, false);
 					}
 				} else {
-					_gl.bindFramebuffer(36160, renderTargetProperties.__webglFramebuffer);
-
+					state.bindFramebuffer(36160, renderTargetProperties.__webglFramebuffer);
 					renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
 					setupRenderBufferStorage(renderTargetProperties.__webglDepthbuffer, renderTarget, false);
 				}
 			}
 
-			_gl.bindFramebuffer(36160, null);
+			state.bindFramebuffer(36160, null);
 		} // Set up GL resources for the render target
 
 
@@ -16228,7 +15535,7 @@
 
 						_gl.renderbufferStorageMultisample(36161, samples, glInternalFormat, renderTarget.width, renderTarget.height);
 
-						_gl.bindFramebuffer(36160, renderTargetProperties.__webglMultisampledFramebuffer);
+						state.bindFramebuffer(36160, renderTargetProperties.__webglMultisampledFramebuffer);
 
 						_gl.framebufferRenderbuffer(36160, 36064, 36161, renderTargetProperties.__webglColorRenderbuffer);
 
@@ -16239,7 +15546,7 @@
 							setupRenderBufferStorage(renderTargetProperties.__webglDepthRenderbuffer, renderTarget, true);
 						}
 
-						_gl.bindFramebuffer(36160, null);
+						state.bindFramebuffer(36160, null);
 					} else {
 						console.warn('THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.');
 					}
@@ -16309,11 +15616,8 @@
 			if (renderTarget.isWebGLMultisampleRenderTarget) {
 				if (isWebGL2) {
 					const renderTargetProperties = properties.get(renderTarget);
-
-					_gl.bindFramebuffer(36008, renderTargetProperties.__webglMultisampledFramebuffer);
-
-					_gl.bindFramebuffer(36009, renderTargetProperties.__webglFramebuffer);
-
+					state.bindFramebuffer(36008, renderTargetProperties.__webglMultisampledFramebuffer);
+					state.bindFramebuffer(36009, renderTargetProperties.__webglFramebuffer);
 					const width = renderTarget.width;
 					const height = renderTarget.height;
 					let mask = 16384;
@@ -16322,8 +15626,7 @@
 
 					_gl.blitFramebuffer(0, 0, width, height, 0, 0, width, height, mask, 9728);
 
-					_gl.bindFramebuffer(36160, renderTargetProperties.__webglMultisampledFramebuffer); // see #18905
-
+					state.bindFramebuffer(36160, renderTargetProperties.__webglMultisampledFramebuffer); // see #18905
 				} else {
 					console.warn('THREE.WebGLRenderer: WebGLMultisampleRenderTarget can only be used with WebGL2.');
 				}
@@ -16707,6 +16010,7 @@
 
 	function WebXRManager(renderer, gl) {
 		const scope = this;
+		const state = renderer.state;
 		let session = null;
 		let framebufferScaleFactor = 1.0;
 		let referenceSpace = null;
@@ -16782,10 +16086,10 @@
 			});
 			inputSourcesMap.clear();
 			_currentDepthNear = null;
-			_currentDepthFar = null; //
+			_currentDepthFar = null; // restore framebuffer/rendering state
 
-			renderer.setFramebuffer(null);
-			renderer.setRenderTarget(renderer.getRenderTarget()); // Hack #15830
+			state.bindXRFramebuffer(null);
+			renderer.setRenderTarget(renderer.getRenderTarget()); //
 
 			animation.stop();
 			scope.isPresenting = false;
@@ -17004,7 +16308,7 @@
 			if (pose !== null) {
 				const views = pose.views;
 				const baseLayer = session.renderState.baseLayer;
-				renderer.setFramebuffer(baseLayer.framebuffer);
+				state.bindXRFramebuffer(baseLayer.framebuffer);
 				let cameraVRNeedsUpdate = false; // check if it's necessary to rebuild cameraVR's camera list
 
 				if (views.length !== cameraVR.cameras.length) {
@@ -17589,11 +16893,9 @@
 
 		let _isContextLost = false; // internal state cache
 
-		let _framebuffer = null;
 		let _currentActiveCubeFace = 0;
 		let _currentActiveMipmapLevel = 0;
 		let _currentRenderTarget = null;
-		let _currentFramebuffer = null;
 
 		let _currentMaterialId = -1;
 
@@ -18690,13 +17992,7 @@
 
 		function materialNeedsLights(material) {
 			return material.isMeshLambertMaterial || material.isMeshToonMaterial || material.isMeshPhongMaterial || material.isMeshStandardMaterial || material.isShadowMaterial || material.isShaderMaterial && material.lights === true;
-		} //
-
-
-		this.setFramebuffer = function (value) {
-			if (_framebuffer !== value && _currentRenderTarget === null) _gl.bindFramebuffer(36160, value);
-			_framebuffer = value;
-		};
+		}
 
 		this.getActiveCubeFace = function () {
 			return _currentActiveCubeFace;
@@ -18719,7 +18015,7 @@
 				textures.setupRenderTarget(renderTarget);
 			}
 
-			let framebuffer = _framebuffer;
+			let framebuffer = null;
 			let isCube = false;
 			let isRenderTarget3D = false;
 
@@ -18754,12 +18050,7 @@
 				_currentScissorTest = _scissorTest;
 			}
 
-			if (_currentFramebuffer !== framebuffer) {
-				_gl.bindFramebuffer(36160, framebuffer);
-
-				_currentFramebuffer = framebuffer;
-			}
-
+			state.bindFramebuffer(36160, framebuffer);
 			state.viewport(_currentViewport);
 			state.scissor(_currentScissor);
 			state.setScissorTest(_currentScissorTest);
@@ -18789,13 +18080,7 @@
 			}
 
 			if (framebuffer) {
-				let restore = false;
-
-				if (framebuffer !== _currentFramebuffer) {
-					_gl.bindFramebuffer(36160, framebuffer);
-
-					restore = true;
-				}
+				state.bindFramebuffer(36160, framebuffer);
 
 				try {
 					const texture = renderTarget.texture;
@@ -18825,9 +18110,9 @@
 						console.error('THREE.WebGLRenderer.readRenderTargetPixels: readPixels from renderTarget failed. Framebuffer not complete.');
 					}
 				} finally {
-					if (restore) {
-						_gl.bindFramebuffer(36160, _currentFramebuffer);
-					}
+					// restore framebuffer of current render target if necessary
+					const framebuffer = _currentRenderTarget !== null ? properties.get(_currentRenderTarget).__webglFramebuffer : null;
+					state.bindFramebuffer(36160, framebuffer);
 				}
 			}
 		};
@@ -18948,14 +18233,9 @@
 		};
 
 		this.resetState = function () {
-			_framebuffer = null;
 			_currentActiveCubeFace = 0;
 			_currentActiveMipmapLevel = 0;
 			_currentRenderTarget = null;
-			_currentFramebuffer = null;
-
-			_gl.bindFramebuffer(36160, null);
-
 			state.reset();
 			bindingStates.reset();
 		};

文件差异内容过多而无法显示
+ 0 - 0
build/three.min.js


+ 72 - 50
build/three.module.js

@@ -19383,6 +19383,9 @@ function WebGLState( gl, extensions, capabilities ) {
 
 	let enabledCapabilities = {};
 
+	let xrFramebuffer = null;
+	let currentBoundFramebuffers = {};
+
 	let currentProgram = null;
 
 	let currentBlendingEnabled = false;
@@ -19489,6 +19492,34 @@ function WebGLState( gl, extensions, capabilities ) {
 
 	}
 
+	function bindXRFramebuffer( framebuffer ) {
+
+		if ( framebuffer !== xrFramebuffer ) {
+
+			gl.bindFramebuffer( 36160, framebuffer );
+
+			xrFramebuffer = framebuffer;
+
+		}
+
+	}
+
+	function bindFramebuffer( target, framebuffer ) {
+
+		if ( target === 36009 ) target = 36160;
+
+		if ( framebuffer === null && xrFramebuffer !== null ) framebuffer = xrFramebuffer; // use active XR framebuffer if available
+
+		if ( currentBoundFramebuffers[ target ] !== framebuffer ) {
+
+			gl.bindFramebuffer( target, framebuffer );
+
+			currentBoundFramebuffers[ target ] = framebuffer;
+
+		}
+
+	}
+
 	function useProgram( program ) {
 
 		if ( currentProgram !== program ) {
@@ -19981,6 +20012,17 @@ function WebGLState( gl, extensions, capabilities ) {
 
 		gl.activeTexture( 33984 );
 
+		if ( isWebGL2 === true ) {
+
+			gl.bindFramebuffer( 36009, null ); // Equivalent to 36160
+			gl.bindFramebuffer( 36008, null );
+
+		} else {
+
+			gl.bindFramebuffer( 36160, null );
+
+		}
+
 		gl.useProgram( null );
 
 		gl.lineWidth( 1 );
@@ -19995,6 +20037,9 @@ function WebGLState( gl, extensions, capabilities ) {
 		currentTextureSlot = null;
 		currentBoundTextures = {};
 
+		xrFramebuffer = null;
+		currentBoundFramebuffers = {};
+
 		currentProgram = null;
 
 		currentBlendingEnabled = false;
@@ -20035,6 +20080,9 @@ function WebGLState( gl, extensions, capabilities ) {
 		enable: enable,
 		disable: disable,
 
+		bindFramebuffer: bindFramebuffer,
+		bindXRFramebuffer: bindXRFramebuffer,
+
 		useProgram: useProgram,
 
 		setBlending: setBlending,
@@ -20914,9 +20962,9 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 		}
 
-		_gl.bindFramebuffer( 36160, framebuffer );
+		state.bindFramebuffer( 36160, framebuffer );
 		_gl.framebufferTexture2D( 36160, attachment, textureTarget, properties.get( texture ).__webglTexture, 0 );
-		_gl.bindFramebuffer( 36160, null );
+		state.bindFramebuffer( 36160, null );
 
 	}
 
@@ -21008,7 +21056,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 		const isCube = ( renderTarget && renderTarget.isWebGLCubeRenderTarget );
 		if ( isCube ) throw new Error( 'Depth Texture with cube render targets is not supported' );
 
-		_gl.bindFramebuffer( 36160, framebuffer );
+		state.bindFramebuffer( 36160, framebuffer );
 
 		if ( ! ( renderTarget.depthTexture && renderTarget.depthTexture.isDepthTexture ) ) {
 
@@ -21068,7 +21116,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 				for ( let i = 0; i < 6; i ++ ) {
 
-					_gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer[ i ] );
+					state.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer[ i ] );
 					renderTargetProperties.__webglDepthbuffer[ i ] = _gl.createRenderbuffer();
 					setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer[ i ], renderTarget, false );
 
@@ -21076,7 +21124,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 			} else {
 
-				_gl.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer );
+				state.bindFramebuffer( 36160, renderTargetProperties.__webglFramebuffer );
 				renderTargetProperties.__webglDepthbuffer = _gl.createRenderbuffer();
 				setupRenderBufferStorage( renderTargetProperties.__webglDepthbuffer, renderTarget, false );
 
@@ -21084,7 +21132,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 		}
 
-		_gl.bindFramebuffer( 36160, null );
+		state.bindFramebuffer( 36160, null );
 
 	}
 
@@ -21148,7 +21196,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 					const samples = getRenderTargetSamples( renderTarget );
 					_gl.renderbufferStorageMultisample( 36161, samples, glInternalFormat, renderTarget.width, renderTarget.height );
 
-					_gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer );
+					state.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer );
 					_gl.framebufferRenderbuffer( 36160, 36064, 36161, renderTargetProperties.__webglColorRenderbuffer );
 					_gl.bindRenderbuffer( 36161, null );
 
@@ -21159,7 +21207,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 					}
 
-					_gl.bindFramebuffer( 36160, null );
+					state.bindFramebuffer( 36160, null );
 
 
 				} else {
@@ -21265,8 +21313,8 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 				const renderTargetProperties = properties.get( renderTarget );
 
-				_gl.bindFramebuffer( 36008, renderTargetProperties.__webglMultisampledFramebuffer );
-				_gl.bindFramebuffer( 36009, renderTargetProperties.__webglFramebuffer );
+				state.bindFramebuffer( 36008, renderTargetProperties.__webglMultisampledFramebuffer );
+				state.bindFramebuffer( 36009, renderTargetProperties.__webglFramebuffer );
 
 				const width = renderTarget.width;
 				const height = renderTarget.height;
@@ -21277,7 +21325,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils,
 
 				_gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, 9728 );
 
-				_gl.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer ); // see #18905
+				state.bindFramebuffer( 36160, renderTargetProperties.__webglMultisampledFramebuffer ); // see #18905
 
 			} else {
 
@@ -21837,6 +21885,7 @@ Object.assign( WebXRController.prototype, {
 function WebXRManager( renderer, gl ) {
 
 	const scope = this;
+	const state = renderer.state;
 
 	let session = null;
 
@@ -21947,10 +21996,13 @@ function WebXRManager( renderer, gl ) {
 		_currentDepthNear = null;
 		_currentDepthFar = null;
 
+		// restore framebuffer/rendering state
+
+		state.bindXRFramebuffer( null );
+		renderer.setRenderTarget( renderer.getRenderTarget() );
+
 		//
 
-		renderer.setFramebuffer( null );
-		renderer.setRenderTarget( renderer.getRenderTarget() ); // Hack #15830
 		animation.stop();
 
 		scope.isPresenting = false;
@@ -22240,7 +22292,7 @@ function WebXRManager( renderer, gl ) {
 			const views = pose.views;
 			const baseLayer = session.renderState.baseLayer;
 
-			renderer.setFramebuffer( baseLayer.framebuffer );
+			state.bindXRFramebuffer( baseLayer.framebuffer );
 
 			let cameraVRNeedsUpdate = false;
 
@@ -23096,12 +23148,9 @@ function WebGLRenderer( parameters ) {
 
 	// internal state cache
 
-	let _framebuffer = null;
-
 	let _currentActiveCubeFace = 0;
 	let _currentActiveMipmapLevel = 0;
 	let _currentRenderTarget = null;
-	let _currentFramebuffer = null;
 	let _currentMaterialId = - 1;
 
 	let _currentCamera = null;
@@ -24729,15 +24778,6 @@ function WebGLRenderer( parameters ) {
 
 	}
 
-	//
-	this.setFramebuffer = function ( value ) {
-
-		if ( _framebuffer !== value && _currentRenderTarget === null ) _gl.bindFramebuffer( 36160, value );
-
-		_framebuffer = value;
-
-	};
-
 	this.getActiveCubeFace = function () {
 
 		return _currentActiveCubeFace;
@@ -24768,7 +24808,7 @@ function WebGLRenderer( parameters ) {
 
 		}
 
-		let framebuffer = _framebuffer;
+		let framebuffer = null;
 		let isCube = false;
 		let isRenderTarget3D = false;
 
@@ -24811,12 +24851,7 @@ function WebGLRenderer( parameters ) {
 
 		}
 
-		if ( _currentFramebuffer !== framebuffer ) {
-
-			_gl.bindFramebuffer( 36160, framebuffer );
-			_currentFramebuffer = framebuffer;
-
-		}
+		state.bindFramebuffer( 36160, framebuffer );
 
 		state.viewport( _currentViewport );
 		state.scissor( _currentScissor );
@@ -24856,15 +24891,7 @@ function WebGLRenderer( parameters ) {
 
 		if ( framebuffer ) {
 
-			let restore = false;
-
-			if ( framebuffer !== _currentFramebuffer ) {
-
-				_gl.bindFramebuffer( 36160, framebuffer );
-
-				restore = true;
-
-			}
+			state.bindFramebuffer( 36160, framebuffer );
 
 			try {
 
@@ -24908,11 +24935,10 @@ function WebGLRenderer( parameters ) {
 
 			} finally {
 
-				if ( restore ) {
+				// restore framebuffer of current render target if necessary
 
-					_gl.bindFramebuffer( 36160, _currentFramebuffer );
-
-				}
+				const framebuffer = ( _currentRenderTarget !== null ) ? properties.get( _currentRenderTarget ).__webglFramebuffer : null;
+				state.bindFramebuffer( 36160, framebuffer );
 
 			}
 
@@ -25059,13 +25085,9 @@ function WebGLRenderer( parameters ) {
 
 	this.resetState = function () {
 
-		_framebuffer = null;
 		_currentActiveCubeFace = 0;
 		_currentActiveMipmapLevel = 0;
 		_currentRenderTarget = null;
-		_currentFramebuffer = null;
-
-		_gl.bindFramebuffer( 36160, null );
 
 		state.reset();
 		bindingStates.reset();

部分文件因为文件数量过多而无法显示