|
|
@@ -31508,6 +31508,17 @@ class ReflectorBaseNode extends Node {
|
|
|
*/
|
|
|
this.forceUpdate = false;
|
|
|
|
|
|
+ /**
|
|
|
+ * Whether the reflector has been rendered or not.
|
|
|
+ *
|
|
|
+ * When the reflector is facing away from the camera,
|
|
|
+ * this flag is set to `false` and the texture will be empty(black).
|
|
|
+ *
|
|
|
+ * @type {boolean}
|
|
|
+ * @default {false}
|
|
|
+ */
|
|
|
+ this.hasOutput = false;
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -31640,7 +31651,21 @@ class ReflectorBaseNode extends Node {
|
|
|
// Avoid rendering when reflector is facing away unless forcing an update
|
|
|
const isFacingAway = _view.dot( _normal ) > 0;
|
|
|
|
|
|
- if ( isFacingAway === true && this.forceUpdate === false ) return;
|
|
|
+ let needsClear = false;
|
|
|
+
|
|
|
+ if ( isFacingAway === true && this.forceUpdate === false ) {
|
|
|
+
|
|
|
+ if ( this.hasOutput === false ) {
|
|
|
+
|
|
|
+ _inReflector = false;
|
|
|
+
|
|
|
+ return;
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ needsClear = true;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
_view.reflect( _normal ).negate();
|
|
|
_view.add( _reflectorWorldPosition );
|
|
|
@@ -31715,7 +31740,19 @@ class ReflectorBaseNode extends Node {
|
|
|
renderer.setRenderTarget( renderTarget );
|
|
|
renderer.autoClear = true;
|
|
|
|
|
|
- renderer.render( scene, virtualCamera );
|
|
|
+ if ( needsClear ) {
|
|
|
+
|
|
|
+ renderer.clear();
|
|
|
+
|
|
|
+ this.hasOutput = false;
|
|
|
+
|
|
|
+ } else {
|
|
|
+
|
|
|
+ renderer.render( scene, virtualCamera );
|
|
|
+
|
|
|
+ this.hasOutput = true;
|
|
|
+
|
|
|
+ }
|
|
|
|
|
|
renderer.setMRT( currentMRT );
|
|
|
renderer.setRenderTarget( currentRenderTarget );
|
|
|
@@ -33357,6 +33394,47 @@ const blendColor = /*@__PURE__*/ Fn( ( [ base, blend ] ) => {
|
|
|
]
|
|
|
} );
|
|
|
|
|
|
+/**
|
|
|
+ * Premultiplies the RGB channels of a color by its alpha channel.
|
|
|
+ *
|
|
|
+ * This function is useful for converting a non-premultiplied alpha color
|
|
|
+ * into a premultiplied alpha format, where the RGB values are scaled
|
|
|
+ * by the alpha value. Premultiplied alpha is often used in graphics
|
|
|
+ * rendering for certain operations, such as compositing and image processing.
|
|
|
+ *
|
|
|
+ * @tsl
|
|
|
+ * @function
|
|
|
+ * @param {Node<vec4>} color - The input color with non-premultiplied alpha.
|
|
|
+ * @return {Node<vec4>} The color with premultiplied alpha.
|
|
|
+ */
|
|
|
+const premult = /*@__PURE__*/ Fn( ( [ color ] ) => {
|
|
|
+
|
|
|
+ return vec4( color.rgb.mul( color.a ), color.a );
|
|
|
+
|
|
|
+}, { color: 'vec4', return: 'vec4' } );
|
|
|
+
|
|
|
+/**
|
|
|
+ * Unpremultiplies the RGB channels of a color by its alpha channel.
|
|
|
+ *
|
|
|
+ * This function is useful for converting a premultiplied alpha color
|
|
|
+ * back into a non-premultiplied alpha format, where the RGB values are
|
|
|
+ * divided by the alpha value. Unpremultiplied alpha is often used in graphics
|
|
|
+ * rendering for certain operations, such as compositing and image processing.
|
|
|
+ *
|
|
|
+ * @tsl
|
|
|
+ * @function
|
|
|
+ * @param {Node<vec4>} color - The input color with premultiplied alpha.
|
|
|
+ * @return {Node<vec4>} The color with non-premultiplied alpha.
|
|
|
+ */
|
|
|
+const unpremult = /*@__PURE__*/ Fn( ( [ color ] ) => {
|
|
|
+
|
|
|
+ If( color.a.equal( 0.0 ), () => vec4( 0.0 ) );
|
|
|
+
|
|
|
+ return vec4( color.rgb.div( color.a ), color.a );
|
|
|
+
|
|
|
+}, { color: 'vec4', return: 'vec4' } );
|
|
|
+
|
|
|
+
|
|
|
// Deprecated
|
|
|
|
|
|
/**
|
|
|
@@ -38638,7 +38716,7 @@ class ShadowNode extends ShadowBaseNode {
|
|
|
|
|
|
// VSM
|
|
|
|
|
|
- if ( shadowMapType === VSMShadowMap ) {
|
|
|
+ if ( shadowMapType === VSMShadowMap && shadow.isPointLightShadow !== true ) {
|
|
|
|
|
|
depthTexture.compareFunction = null; // VSM does not use textureSampleCompare()/texture2DCompare()
|
|
|
|
|
|
@@ -38718,7 +38796,7 @@ class ShadowNode extends ShadowBaseNode {
|
|
|
|
|
|
}
|
|
|
|
|
|
- const shadowDepthTexture = ( shadowMapType === VSMShadowMap ) ? this.vsmShadowMapHorizontal.texture : depthTexture;
|
|
|
+ const shadowDepthTexture = ( shadowMapType === VSMShadowMap && shadow.isPointLightShadow !== true ) ? this.vsmShadowMapHorizontal.texture : depthTexture;
|
|
|
|
|
|
const shadowNode = this.setupShadowFilter( builder, { filterFn, shadowTexture: shadowMap.texture, depthTexture: shadowDepthTexture, shadowCoord, shadow, depthLayer: this.depthLayer } );
|
|
|
|
|
|
@@ -38845,7 +38923,7 @@ class ShadowNode extends ShadowBaseNode {
|
|
|
|
|
|
// vsm blur pass
|
|
|
|
|
|
- if ( light.isPointLight !== true && shadowType === VSMShadowMap ) {
|
|
|
+ if ( shadowType === VSMShadowMap && shadow.isPointLightShadow !== true ) {
|
|
|
|
|
|
this.vsmPass( renderer );
|
|
|
|
|
|
@@ -41652,6 +41730,7 @@ var TSL = /*#__PURE__*/Object.freeze({
|
|
|
pow2: pow2,
|
|
|
pow3: pow3,
|
|
|
pow4: pow4,
|
|
|
+ premult: premult,
|
|
|
property: property,
|
|
|
radians: radians,
|
|
|
rand: rand,
|
|
|
@@ -41774,6 +41853,7 @@ var TSL = /*#__PURE__*/Object.freeze({
|
|
|
uniformArray: uniformArray,
|
|
|
uniformGroup: uniformGroup,
|
|
|
uniforms: uniforms,
|
|
|
+ unpremult: unpremult,
|
|
|
userData: userData,
|
|
|
uv: uv,
|
|
|
uvec2: uvec2,
|
|
|
@@ -49395,7 +49475,22 @@ class XRManager extends EventDispatcher {
|
|
|
|
|
|
}
|
|
|
|
|
|
- createQuadLayer( width, height, translation, quaternion, pixelwidth, pixelheight, rendercall, attributes = [] ) {
|
|
|
+ /**
|
|
|
+ * This method can be used in XR applications to create a quadratic layer that presents a separate
|
|
|
+ * rendered scene.
|
|
|
+ *
|
|
|
+ * @param {number} width - The width of the layer plane in world units.
|
|
|
+ * @param {number} height - The height of the layer plane in world units.
|
|
|
+ * @param {Vector3} translation - The position/translation of the layer plane in world units.
|
|
|
+ * @param {Quaternion} quaternion - The orientation of the layer plane expressed as a quaternion.
|
|
|
+ * @param {number} pixelwidth - The width of the layer's render target in pixels.
|
|
|
+ * @param {number} pixelheight - The height of the layer's render target in pixels.
|
|
|
+ * @param {Function} rendercall - A callback function that renders the layer. Similar to code in
|
|
|
+ * the default animation loop, this method can be used to update/transform 3D object in the layer's scene.
|
|
|
+ * @param {Object} [attributes={}] - Allows to configure the layer's render target.
|
|
|
+ * @return {Mesh} A mesh representing the quadratic XR layer. This mesh should be added to the XR scene.
|
|
|
+ */
|
|
|
+ createQuadLayer( width, height, translation, quaternion, pixelwidth, pixelheight, rendercall, attributes = {} ) {
|
|
|
|
|
|
const geometry = new PlaneGeometry( width, height );
|
|
|
const renderTarget = new XRRenderTarget(
|
|
|
@@ -49468,7 +49563,23 @@ class XRManager extends EventDispatcher {
|
|
|
|
|
|
}
|
|
|
|
|
|
- createCylinderLayer( radius, centralAngle, aspectratio, translation, quaternion, pixelwidth, pixelheight, rendercall, attributes = [] ) {
|
|
|
+ /**
|
|
|
+ * This method can be used in XR applications to create a cylindrical layer that presents a separate
|
|
|
+ * rendered scene.
|
|
|
+ *
|
|
|
+ * @param {number} radius - The radius of the cylinder in world units.
|
|
|
+ * @param {number} centralAngle - The central angle of the cylinder in radians.
|
|
|
+ * @param {number} aspectratio - The aspect ratio.
|
|
|
+ * @param {Vector3} translation - The position/translation of the layer plane in world units.
|
|
|
+ * @param {Quaternion} quaternion - The orientation of the layer plane expressed as a quaternion.
|
|
|
+ * @param {number} pixelwidth - The width of the layer's render target in pixels.
|
|
|
+ * @param {number} pixelheight - The height of the layer's render target in pixels.
|
|
|
+ * @param {Function} rendercall - A callback function that renders the layer. Similar to code in
|
|
|
+ * the default animation loop, this method can be used to update/transform 3D object in the layer's scene.
|
|
|
+ * @param {Object} [attributes={}] - Allows to configure the layer's render target.
|
|
|
+ * @return {Mesh} A mesh representing the cylindrical XR layer. This mesh should be added to the XR scene.
|
|
|
+ */
|
|
|
+ createCylinderLayer( radius, centralAngle, aspectratio, translation, quaternion, pixelwidth, pixelheight, rendercall, attributes = {} ) {
|
|
|
|
|
|
const geometry = new CylinderGeometry( radius, radius, radius * centralAngle / aspectratio, 64, 64, true, Math.PI - centralAngle / 2, centralAngle );
|
|
|
const renderTarget = new XRRenderTarget(
|
|
|
@@ -49542,6 +49653,12 @@ class XRManager extends EventDispatcher {
|
|
|
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Renders the XR layers that have been previously added to the scene.
|
|
|
+ *
|
|
|
+ * This method is usually called in your animation loop before rendering
|
|
|
+ * the actual scene via `renderer.render( scene, camera );`.
|
|
|
+ */
|
|
|
renderLayers( ) {
|
|
|
|
|
|
const translationObject = new Vector3();
|
|
|
@@ -50059,7 +50176,7 @@ function onSessionEnd() {
|
|
|
|
|
|
// restore framebuffer/rendering state
|
|
|
|
|
|
- renderer.XRResetState();
|
|
|
+ renderer._resetXRState();
|
|
|
|
|
|
this._session = null;
|
|
|
this._xrRenderTarget = null;
|
|
|
@@ -52550,7 +52667,7 @@ class Renderer {
|
|
|
* Resets the renderer to the initial state before WebXR started.
|
|
|
*
|
|
|
*/
|
|
|
- XRResetState() {
|
|
|
+ _resetXRState() {
|
|
|
|
|
|
this.backend.setXRTarget( null );
|
|
|
this.setOutputRenderTarget( null );
|