diff --git a/examples/jsm/tsl/display/AfterImageNode.js b/examples/jsm/tsl/display/AfterImageNode.js index cb17dcc48d2d39..5dfa21ce2dbb6e 100644 --- a/examples/jsm/tsl/display/AfterImageNode.js +++ b/examples/jsm/tsl/display/AfterImageNode.js @@ -1,10 +1,11 @@ -import { RenderTarget, Vector2 } from 'three'; +import { RenderTarget, Vector2, PostProcessingUtils } from 'three'; import { TempNode, nodeObject, Fn, float, vec4, NodeUpdateType, uv, texture, passTexture, uniform, sign, max, convertToTexture, QuadMesh, NodeMaterial } from 'three/tsl'; const _size = /*@__PURE__*/ new Vector2(); - const _quadMeshComp = /*@__PURE__*/ new QuadMesh(); +let _rendererState; + class AfterImageNode extends TempNode { static get type() { @@ -50,6 +51,10 @@ class AfterImageNode extends TempNode { const { renderer } = frame; + _rendererState = PostProcessingUtils.resetRendererState( renderer, _rendererState ); + + // + const textureNode = this.textureNode; const map = textureNode.value; @@ -62,23 +67,27 @@ class AfterImageNode extends TempNode { this.setSize( _size.x, _size.y ); - const currentRenderTarget = renderer.getRenderTarget(); const currentTexture = textureNode.value; this.textureNodeOld.value = this._oldRT.texture; // comp + renderer.setRenderTarget( this._compRT ); _quadMeshComp.render( renderer ); // Swap the textures + const temp = this._oldRT; this._oldRT = this._compRT; this._compRT = temp; - renderer.setRenderTarget( currentRenderTarget ); + // + textureNode.value = currentTexture; + PostProcessingUtils.setRendererState( renderer, _rendererState ); + } setup( builder ) { diff --git a/examples/jsm/tsl/display/AnamorphicNode.js b/examples/jsm/tsl/display/AnamorphicNode.js index 1dae2520cb0542..3127bd37513529 100644 --- a/examples/jsm/tsl/display/AnamorphicNode.js +++ b/examples/jsm/tsl/display/AnamorphicNode.js @@ -1,8 +1,10 @@ -import { RenderTarget, Vector2 } from 'three'; +import { RenderTarget, Vector2, PostProcessingUtils } from 'three'; import { TempNode, nodeObject, Fn, float, NodeUpdateType, uv, passTexture, uniform, convertToTexture, QuadMesh, NodeMaterial, vec2, vec3, Loop, threshold } from 'three/tsl'; const _quadMesh = /*@__PURE__*/ new QuadMesh(); +let _rendererState; + class AnamorphicNode extends TempNode { static get type() { @@ -54,12 +56,15 @@ class AnamorphicNode extends TempNode { const { renderer } = frame; + _rendererState = PostProcessingUtils.getRendererState( renderer, _rendererState ); + + // + const textureNode = this.textureNode; const map = textureNode.value; this._renderTarget.texture.type = map.type; - const currentRenderTarget = renderer.getRenderTarget(); const currentTexture = textureNode.value; _quadMesh.material = this._material; @@ -74,9 +79,10 @@ class AnamorphicNode extends TempNode { // restore - renderer.setRenderTarget( currentRenderTarget ); textureNode.value = currentTexture; + PostProcessingUtils.setRendererState( renderer, _rendererState ); + } setup( builder ) { diff --git a/examples/jsm/tsl/display/BloomNode.js b/examples/jsm/tsl/display/BloomNode.js index 5921394ba381dc..d9f46b588d2b23 100644 --- a/examples/jsm/tsl/display/BloomNode.js +++ b/examples/jsm/tsl/display/BloomNode.js @@ -1,15 +1,14 @@ -import { Color, HalfFloatType, RenderTarget, Vector2, Vector3 } from 'three'; +import { HalfFloatType, RenderTarget, Vector2, Vector3, PostProcessingUtils } from 'three'; import { TempNode, nodeObject, Fn, float, NodeUpdateType, uv, passTexture, uniform, QuadMesh, NodeMaterial, Loop, texture, luminance, smoothstep, mix, vec4, uniformArray, add, int } from 'three/tsl'; const _quadMesh = /*@__PURE__*/ new QuadMesh(); - -const _clearColor = /*@__PURE__*/ new Color( 0, 0, 0 ); -const _currentClearColor = /*@__PURE__*/ new Color(); const _size = /*@__PURE__*/ new Vector2(); const _BlurDirectionX = /*@__PURE__*/ new Vector2( 1.0, 0.0 ); const _BlurDirectionY = /*@__PURE__*/ new Vector2( 0.0, 1.0 ); +let _rendererState; + class BloomNode extends TempNode { static get type() { @@ -111,19 +110,13 @@ class BloomNode extends TempNode { const { renderer } = frame; - const size = renderer.getDrawingBufferSize( _size ); - this.setSize( size.width, size.height ); + _rendererState = PostProcessingUtils.getRendererState( renderer, _rendererState ); - const currentRenderTarget = renderer.getRenderTarget(); - const currentMRT = renderer.getMRT(); - renderer.getClearColor( _currentClearColor ); - const currentClearAlpha = renderer.getClearAlpha(); + // + const size = renderer.getDrawingBufferSize( _size ); this.setSize( size.width, size.height ); - renderer.setMRT( null ); - renderer.setClearColor( _clearColor, 0 ); - // 1. Extract Bright Areas renderer.setRenderTarget( this._renderTargetBright ); @@ -163,9 +156,7 @@ class BloomNode extends TempNode { // restore - renderer.setRenderTarget( currentRenderTarget ); - renderer.setMRT( currentMRT ); - renderer.setClearColor( _currentClearColor, currentClearAlpha ); + PostProcessingUtils.setRendererState( renderer, _rendererState ); } diff --git a/examples/jsm/tsl/display/GTAONode.js b/examples/jsm/tsl/display/GTAONode.js index e6ea2ee31cdd59..32248d3d9b203c 100644 --- a/examples/jsm/tsl/display/GTAONode.js +++ b/examples/jsm/tsl/display/GTAONode.js @@ -1,10 +1,11 @@ -import { Color, DataTexture, RenderTarget, RepeatWrapping, Vector2, Vector3 } from 'three'; +import { DataTexture, RenderTarget, RepeatWrapping, Vector2, Vector3, PostProcessingUtils } from 'three'; import { getViewPosition, QuadMesh, TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, Loop, vec2, vec3, vec4, int, dot, max, pow, abs, If, textureSize, sin, cos, PI, texture, passTexture, mat3, add, normalize, mul, cross, div, mix, sqrt, sub, acos, clamp, NodeMaterial } from 'three/tsl'; const _quadMesh = /*@__PURE__*/ new QuadMesh(); -const _currentClearColor = /*@__PURE__*/ new Color(); const _size = /*@__PURE__*/ new Vector2(); +let _rendererState; + class GTAONode extends TempNode { static get type() { @@ -60,20 +61,17 @@ class GTAONode extends TempNode { const { renderer } = frame; - const size = renderer.getDrawingBufferSize( _size ); - - const currentRenderTarget = renderer.getRenderTarget(); - const currentMRT = renderer.getMRT(); - renderer.getClearColor( _currentClearColor ); - const currentClearAlpha = renderer.getClearAlpha(); + _rendererState = PostProcessingUtils.resetRendererState( renderer, _rendererState ); - _quadMesh.material = this._material; + // + const size = renderer.getDrawingBufferSize( _size ); this.setSize( size.width, size.height ); + _quadMesh.material = this._material; + // clear - renderer.setMRT( null ); renderer.setClearColor( 0xffffff, 1 ); // ao @@ -83,9 +81,7 @@ class GTAONode extends TempNode { // restore - renderer.setRenderTarget( currentRenderTarget ); - renderer.setMRT( currentMRT ); - renderer.setClearColor( _currentClearColor, currentClearAlpha ); + PostProcessingUtils.setRendererState( renderer, _rendererState ); } diff --git a/examples/jsm/tsl/display/GaussianBlurNode.js b/examples/jsm/tsl/display/GaussianBlurNode.js index d6438e680c8b7f..2dfa9c3a92a308 100644 --- a/examples/jsm/tsl/display/GaussianBlurNode.js +++ b/examples/jsm/tsl/display/GaussianBlurNode.js @@ -1,4 +1,4 @@ -import { RenderTarget, Vector2 } from 'three'; +import { RenderTarget, Vector2, PostProcessingUtils } from 'three'; import { TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, convertToTexture, vec2, vec4, QuadMesh, passTexture, mul, NodeMaterial } from 'three/tsl'; // WebGPU: The use of a single QuadMesh for both gaussian blur passes results in a single RenderObject with a SampledTexture binding that @@ -7,6 +7,8 @@ import { TempNode, nodeObject, Fn, float, NodeUpdateType, uv, uniform, convertTo const _quadMesh1 = /*@__PURE__*/ new QuadMesh(); const _quadMesh2 = /*@__PURE__*/ new QuadMesh(); +let _rendererState; + class GaussianBlurNode extends TempNode { static get type() { @@ -54,12 +56,13 @@ class GaussianBlurNode extends TempNode { const { renderer } = frame; + _rendererState = PostProcessingUtils.resetRendererState( renderer, _rendererState ); + + // + const textureNode = this.textureNode; const map = textureNode.value; - const currentRenderTarget = renderer.getRenderTarget(); - const currentMRT = renderer.getMRT(); - const currentTexture = textureNode.value; _quadMesh1.material = this._material; @@ -72,10 +75,6 @@ class GaussianBlurNode extends TempNode { this._horizontalRT.texture.type = textureType; this._verticalRT.texture.type = textureType; - // clear - - renderer.setMRT( null ); - // horizontal renderer.setRenderTarget( this._horizontalRT ); @@ -95,10 +94,10 @@ class GaussianBlurNode extends TempNode { // restore - renderer.setRenderTarget( currentRenderTarget ); - renderer.setMRT( currentMRT ); textureNode.value = currentTexture; + PostProcessingUtils.setRendererState( renderer, _rendererState ); + } getTextureNode() { diff --git a/examples/jsm/tsl/display/OutlineNode.js b/examples/jsm/tsl/display/OutlineNode.js index 07f4dd866a24d0..943f2358375855 100644 --- a/examples/jsm/tsl/display/OutlineNode.js +++ b/examples/jsm/tsl/display/OutlineNode.js @@ -1,12 +1,13 @@ -import { Color, DepthTexture, FloatType, RenderTarget, Vector2 } from 'three'; +import { Color, DepthTexture, FloatType, RenderTarget, Vector2, PostProcessingUtils } from 'three'; import { Loop, int, exp, min, float, mul, uv, vec2, vec3, Fn, textureSize, orthographicDepthToViewZ, QuadMesh, screenUV, TempNode, nodeObject, NodeUpdateType, uniform, vec4, NodeMaterial, passTexture, texture, perspectiveDepthToViewZ, positionView } from 'three/tsl'; const _quadMesh = /*@__PURE__*/ new QuadMesh(); -const _currentClearColor = /*@__PURE__*/ new Color(); const _size = /*@__PURE__*/ new Vector2(); const _BLUR_DIRECTION_X = /*@__PURE__*/ new Vector2( 1.0, 0.0 ); const _BLUR_DIRECTION_Y = /*@__PURE__*/ new Vector2( 0.0, 1.0 ); +let _rendererState; + class OutlineNode extends TempNode { static get type() { @@ -151,28 +152,23 @@ class OutlineNode extends TempNode { const { renderer } = frame; const { camera, scene } = this; + _rendererState = PostProcessingUtils.resetRendererAndSceneState( renderer, scene, _rendererState ); + + // + const size = renderer.getDrawingBufferSize( _size ); this.setSize( size.width, size.height ); - renderer.getClearColor( _currentClearColor ); - const currentClearAlpha = renderer.getClearAlpha(); - const currentRenderTarget = renderer.getRenderTarget(); - const currentMRT = renderer.getMRT(); - const currentBackground = scene.background; - const currentRenderObjectFunction = renderer.getRenderObjectFunction(); - // renderer.setClearColor( 0xffffff, 1 ); - renderer.setMRT( null ); this._updateSelectionCache(); - scene.background = null; - // 1. Draw non-selected objects in the depth buffer scene.overrideMaterial = this._depthMaterial; + renderer.setRenderTarget( this._renderTargetDepthBuffer ); renderer.setRenderObjectFunction( ( object, ...params ) => { @@ -183,11 +179,13 @@ class OutlineNode extends TempNode { } } ); + renderer.render( scene, camera ); // 2. Draw only the selected objects by comparing the depth buffer of non-selected objects scene.overrideMaterial = this._prepareMaskMaterial; + renderer.setRenderTarget( this._renderTargetMaskBuffer ); renderer.setRenderObjectFunction( ( object, ...params ) => { @@ -198,11 +196,12 @@ class OutlineNode extends TempNode { } } ); + renderer.render( scene, camera ); - scene.overrideMaterial = null; - scene.background = currentBackground; - renderer.setRenderObjectFunction( currentRenderObjectFunction ); + // + + renderer.setRenderObjectFunction( _rendererState.renderObjectFunction ); this._selectionCache.clear(); @@ -256,9 +255,7 @@ class OutlineNode extends TempNode { // restore - renderer.setRenderTarget( currentRenderTarget ); - renderer.setMRT( currentMRT ); - renderer.setClearColor( _currentClearColor, currentClearAlpha ); + PostProcessingUtils.setRendererAndSceneState( renderer, scene, _rendererState ); } diff --git a/examples/jsm/tsl/display/SMAANode.js b/examples/jsm/tsl/display/SMAANode.js index b9540c45f71561..cfa0afe8a3d163 100644 --- a/examples/jsm/tsl/display/SMAANode.js +++ b/examples/jsm/tsl/display/SMAANode.js @@ -1,10 +1,11 @@ -import { Color, HalfFloatType, LinearFilter, NearestFilter, RenderTarget, Texture, Vector2 } from 'three'; +import { HalfFloatType, LinearFilter, NearestFilter, RenderTarget, Texture, Vector2, PostProcessingUtils } from 'three'; import { abs, QuadMesh, NodeMaterial, TempNode, nodeObject, Fn, NodeUpdateType, uv, uniform, convertToTexture, varyingProperty, vec2, vec4, modelViewProjection, passTexture, max, step, dot, float, texture, If, Loop, int, Break, sqrt, sign, mix } from 'three/tsl'; const _quadMesh = /*@__PURE__*/ new QuadMesh(); -const _currentClearColor = /*@__PURE__*/ new Color(); const _size = /*@__PURE__*/ new Vector2(); +let _rendererState; + /** * Port of Subpixel Morphological Antialiasing (SMAA) v2.8 * Preset: SMAA 1x Medium (with color edge detection) @@ -120,15 +121,12 @@ class SMAANode extends TempNode { const { renderer } = frame; - const size = renderer.getDrawingBufferSize( _size ); - this.setSize( size.width, size.height ); + _rendererState = PostProcessingUtils.resetRendererState( renderer, _rendererState ); - const currentRenderTarget = renderer.getRenderTarget(); - const currentMRT = renderer.getMRT(); - renderer.getClearColor( _currentClearColor ); - const currentClearAlpha = renderer.getClearAlpha(); + // - renderer.setMRT( null ); + const size = renderer.getDrawingBufferSize( _size ); + this.setSize( size.width, size.height ); // edges @@ -153,9 +151,7 @@ class SMAANode extends TempNode { // restore - renderer.setRenderTarget( currentRenderTarget ); - renderer.setMRT( currentMRT ); - renderer.setClearColor( _currentClearColor, currentClearAlpha ); + PostProcessingUtils.setRendererState( renderer, _rendererState ); } diff --git a/examples/jsm/tsl/display/SSAAPassNode.js b/examples/jsm/tsl/display/SSAAPassNode.js index ea0f9cfa22cbbe..149433b02045b2 100644 --- a/examples/jsm/tsl/display/SSAAPassNode.js +++ b/examples/jsm/tsl/display/SSAAPassNode.js @@ -1,8 +1,10 @@ -import { AdditiveBlending, Color, Vector2 } from 'three'; +import { AdditiveBlending, Color, Vector2, PostProcessingUtils } from 'three'; import { nodeObject, uniform, mrt, PassNode, QuadMesh, texture, NodeMaterial, getTextureIndex } from 'three/tsl'; const _size = /*@__PURE__*/ new Vector2(); +let _rendererState; + /** * * Supersample Anti-Aliasing Render Pass @@ -32,8 +34,6 @@ class SSAAPassNode extends PassNode { this.clearColor = new Color( 0x000000 ); this.clearAlpha = 0; - this._currentClearColor = new Color(); - this.sampleWeight = uniform( 1 ); this.sampleRenderTarget = null; @@ -47,6 +47,10 @@ class SSAAPassNode extends PassNode { const { renderer } = frame; const { scene, camera } = this; + _rendererState = PostProcessingUtils.getRendererAndSceneState( renderer, scene, _rendererState ); + + // + this._pixelRatio = renderer.getPixelRatio(); const size = renderer.getSize( _size ); @@ -54,14 +58,6 @@ class SSAAPassNode extends PassNode { this.setSize( size.width, size.height ); this.sampleRenderTarget.setSize( this.renderTarget.width, this.renderTarget.height ); - // save current renderer settings - - renderer.getClearColor( this._currentClearColor ); - const currentClearAlpha = renderer.getClearAlpha(); - const currentRenderTarget = renderer.getRenderTarget(); - const currentMRT = renderer.getMRT(); - const currentAutoClear = renderer.autoClear; - // this._cameraNear.value = camera.near; @@ -165,11 +161,9 @@ class SSAAPassNode extends PassNode { } - renderer.setRenderTarget( currentRenderTarget ); - renderer.setMRT( currentMRT ); + // - renderer.autoClear = currentAutoClear; - renderer.setClearColor( this._currentClearColor, currentClearAlpha ); + PostProcessingUtils.setRendererAndSceneState( renderer, scene, _rendererState ); } diff --git a/examples/jsm/tsl/display/StereoCompositePassNode.js b/examples/jsm/tsl/display/StereoCompositePassNode.js index 68a1854229f525..fd73eb41becbbb 100644 --- a/examples/jsm/tsl/display/StereoCompositePassNode.js +++ b/examples/jsm/tsl/display/StereoCompositePassNode.js @@ -1,9 +1,11 @@ -import { RenderTarget, StereoCamera, HalfFloatType, LinearFilter, NearestFilter, Vector2 } from 'three'; +import { RenderTarget, StereoCamera, HalfFloatType, LinearFilter, NearestFilter, Vector2, PostProcessingUtils } from 'three'; import { PassNode, QuadMesh, texture } from 'three/tsl'; const _size = /*@__PURE__*/ new Vector2(); const _quadMesh = /*@__PURE__*/ new QuadMesh(); +let _rendererState; + class StereoCompositePassNode extends PassNode { static get type() { @@ -53,6 +55,10 @@ class StereoCompositePassNode extends PassNode { const { renderer } = frame; const { scene, stereo, renderTarget } = this; + _rendererState = PostProcessingUtils.getRendererAndSceneState( renderer, scene, _rendererState ); + + // + this._pixelRatio = renderer.getPixelRatio(); this.updateStereoCamera( renderer.coordinateSystem ); @@ -60,8 +66,6 @@ class StereoCompositePassNode extends PassNode { const size = renderer.getSize( _size ); this.setSize( size.width, size.height ); - const currentRenderTarget = renderer.getRenderTarget(); - // left renderer.setRenderTarget( this._renderTargetL ); @@ -80,7 +84,7 @@ class StereoCompositePassNode extends PassNode { // restore - renderer.setRenderTarget( currentRenderTarget ); + PostProcessingUtils.setRendererState( renderer, scene, _rendererState ); } diff --git a/examples/jsm/tsl/display/StereoPassNode.js b/examples/jsm/tsl/display/StereoPassNode.js index 9c0c2e31db5f52..3e7741ed7a52ef 100644 --- a/examples/jsm/tsl/display/StereoPassNode.js +++ b/examples/jsm/tsl/display/StereoPassNode.js @@ -1,8 +1,10 @@ -import { StereoCamera, Vector2 } from 'three'; +import { StereoCamera, Vector2, PostProcessingUtils } from 'three'; import { PassNode, nodeObject } from 'three/tsl'; const _size = /*@__PURE__*/ new Vector2(); +let _rendererState; + class StereoPassNode extends PassNode { static get type() { @@ -27,6 +29,10 @@ class StereoPassNode extends PassNode { const { renderer } = frame; const { scene, camera, stereo, renderTarget } = this; + _rendererState = PostProcessingUtils.resetRendererState( renderer, _rendererState ); + + // + this._pixelRatio = renderer.getPixelRatio(); stereo.cameraL.coordinateSystem = renderer.coordinateSystem; @@ -36,12 +42,8 @@ class StereoPassNode extends PassNode { const size = renderer.getSize( _size ); this.setSize( size.width, size.height ); - const currentAutoClear = renderer.autoClear; renderer.autoClear = false; - const currentRenderTarget = renderer.getRenderTarget(); - const currentMRT = renderer.getMRT(); - this._cameraNear.value = camera.near; this._cameraFar.value = camera.far; @@ -67,10 +69,9 @@ class StereoPassNode extends PassNode { renderTarget.scissorTest = false; - renderer.setRenderTarget( currentRenderTarget ); - renderer.setMRT( currentMRT ); + // restore - renderer.autoClear = currentAutoClear; + PostProcessingUtils.setRendererState( renderer, _rendererState ); } diff --git a/src/Three.WebGPU.Nodes.js b/src/Three.WebGPU.Nodes.js index 319efa3d2076b0..b853ca45bcdbba 100644 --- a/src/Three.WebGPU.Nodes.js +++ b/src/Three.WebGPU.Nodes.js @@ -167,6 +167,8 @@ export { default as WebGPURenderer } from './renderers/webgpu/WebGPURenderer.Nod export { default as QuadMesh } from './renderers/common/QuadMesh.js'; export { default as PMREMGenerator } from './renderers/common/extras/PMREMGenerator.js'; export { default as PostProcessing } from './renderers/common/PostProcessing.js'; +import * as PostProcessingUtils from './renderers/common/PostProcessingUtils.js'; +export { PostProcessingUtils }; export { default as StorageTexture } from './renderers/common/StorageTexture.js'; export { default as StorageBufferAttribute } from './renderers/common/StorageBufferAttribute.js'; export { default as StorageInstancedBufferAttribute } from './renderers/common/StorageInstancedBufferAttribute.js'; diff --git a/src/Three.WebGPU.js b/src/Three.WebGPU.js index 9e314be4a7a9ae..423024ac21462b 100644 --- a/src/Three.WebGPU.js +++ b/src/Three.WebGPU.js @@ -168,6 +168,8 @@ export { default as BundleGroup } from './renderers/common/BundleGroup.js'; export { default as QuadMesh } from './renderers/common/QuadMesh.js'; export { default as PMREMGenerator } from './renderers/common/extras/PMREMGenerator.js'; export { default as PostProcessing } from './renderers/common/PostProcessing.js'; +import * as PostProcessingUtils from './renderers/common/PostProcessingUtils.js'; +export { PostProcessingUtils }; export { default as StorageTexture } from './renderers/common/StorageTexture.js'; export { default as StorageBufferAttribute } from './renderers/common/StorageBufferAttribute.js'; export { default as StorageInstancedBufferAttribute } from './renderers/common/StorageInstancedBufferAttribute.js'; diff --git a/src/renderers/common/PostProcessingUtils.js b/src/renderers/common/PostProcessingUtils.js new file mode 100644 index 00000000000000..a1af474f29c362 --- /dev/null +++ b/src/renderers/common/PostProcessingUtils.js @@ -0,0 +1,86 @@ +import { Color } from '../../math/Color.js'; + +// renderer state + +export function getRendererState( renderer, state = {} ) { + + state.toneMapping = renderer.toneMapping; + state.toneMappingExposure = renderer.toneMappingExposure; + state.outputColorSpace = renderer.outputColorSpace; + state.renderTarget = renderer.getRenderTarget(); + state.activeCubeFace = renderer.getActiveCubeFace(); + state.activeMipmapLevel = renderer.getActiveMipmapLevel(); + state.renderObjectFunction = renderer.getRenderObjectFunction(); + state.pixelRatio = renderer.getPixelRatio(); + state.mrt = renderer.getMRT(); + state.clearColor = renderer.getClearColor( state.clearColor || new Color() ); + state.clearAlpha = renderer.getClearAlpha(); + state.autoClear = renderer.autoClear; + state.scissorTest = renderer.getScissorTest(); + + return state; + +} + +export function resetRendererState( renderer, state ) { + + state = getRendererState( renderer, state ); + + renderer.setMRT( null ); + renderer.setRenderObjectFunction( null ); + renderer.setClearColor( 0x000000, 1 ); + renderer.autoClear = true; + + return state; + +} + +export function setRendererState( renderer, state ) { + + renderer.toneMapping = state.toneMapping; + renderer.toneMappingExposure = state.toneMappingExposure; + renderer.outputColorSpace = state.outputColorSpace; + renderer.setRenderTarget( state.renderTarget, state.activeCubeFace, state.activeMipmapLevel ); + renderer.setRenderObjectFunction( state.renderObjectFunction ); + renderer.setPixelRatio( state.pixelRatio ); + renderer.setMRT( state.mrt ); + renderer.setClearColor( state.clearColor, state.clearAlpha ); + renderer.autoClear = state.autoClear; + renderer.setScissorTest( state.scissorTest ); + +} + +// renderer and scene state + +export function getRendererAndSceneState( renderer, scene, state = {} ) { + + state = getRendererState( renderer, state ); + state.background = scene.background; + state.backgroundNode = scene.backgroundNode; + state.overrideMaterial = scene.overrideMaterial; + + return state; + +} + +export function resetRendererAndSceneState( renderer, scene, state ) { + + state = getRendererAndSceneState( renderer, scene, state ); + + scene.background = null; + scene.backgroundNode = null; + scene.overrideMaterial = null; + + return state; + +} + +export function setRendererAndSceneState( renderer, scene, state ) { + + setRendererState( renderer, state ); + + scene.background = state.background; + scene.backgroundNode = state.backgroundNode; + scene.overrideMaterial = state.overrideMaterial; + +} diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index 20f9eb3affc9a5..d22cd9e1732570 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -825,6 +825,8 @@ class Renderer { setPixelRatio( value = 1 ) { + if ( this._pixelRatio === value ) return; + this._pixelRatio = value; this.setSize( this._width, this._height, false );