@@ -4,14 +4,14 @@ import {
44 FrontSide ,
55 DoubleSide ,
66 HalfFloatType ,
7- UnsignedByteType ,
87 NoToneMapping ,
98 LinearMipmapLinearFilter ,
109 SRGBColorSpace ,
1110 LinearSRGBColorSpace ,
1211 RGBAIntegerFormat ,
1312 RGIntegerFormat ,
1413 RedIntegerFormat ,
14+ UnsignedByteType ,
1515 UnsignedIntType ,
1616 UnsignedShortType ,
1717 UnsignedInt248Type ,
@@ -31,6 +31,7 @@ import { WebGLBindingStates } from './webgl/WebGLBindingStates.js';
3131import { WebGLBufferRenderer } from './webgl/WebGLBufferRenderer.js' ;
3232import { WebGLCapabilities } from './webgl/WebGLCapabilities.js' ;
3333import { WebGLClipping } from './webgl/WebGLClipping.js' ;
34+ import { WebGLComposite } from './webgl/WebGLComposite.js' ;
3435import { WebGLCubeMaps } from './webgl/WebGLCubeMaps.js' ;
3536import { WebGLCubeUVMaps } from './webgl/WebGLCubeUVMaps.js' ;
3637import { WebGLExtensions } from './webgl/WebGLExtensions.js' ;
@@ -339,6 +340,10 @@ class WebGLRenderer {
339340
340341 let _renderBackground = false ;
341342
343+ // internal composite pass for tonemapping, color space conversion, and dithering
344+ let _composite = null ;
345+ let _isRenderingComposite = false ;
346+
342347 function getTargetPixelRatio ( ) {
343348
344349 return _currentRenderTarget === null ? _pixelRatio : 1 ;
@@ -454,6 +459,10 @@ class WebGLRenderer {
454459
455460 info . programs = programCache . programs ;
456461
462+ // Initialize composite pass for tonemapping, color space conversion, and dithering
463+ _composite = new WebGLComposite ( extensions , capabilities ) ;
464+ _composite . setSize ( _width * _pixelRatio , _height * _pixelRatio ) ;
465+
457466 /**
458467 * Holds details about the capabilities of the current rendering context.
459468 *
@@ -655,6 +664,9 @@ class WebGLRenderer {
655664
656665 }
657666
667+ // Resize composite render target
668+ _composite . setSize ( width * _pixelRatio , height * _pixelRatio ) ;
669+
658670 this . setViewport ( 0 , 0 , width , height ) ;
659671
660672 } ;
@@ -694,6 +706,9 @@ class WebGLRenderer {
694706 canvas . width = Math . floor ( width * pixelRatio ) ;
695707 canvas . height = Math . floor ( height * pixelRatio ) ;
696708
709+ // Resize composite render target
710+ _composite . setSize ( width * pixelRatio , height * pixelRatio ) ;
711+
697712 this . setViewport ( 0 , 0 , width , height ) ;
698713
699714 } ;
@@ -1007,6 +1022,9 @@ class WebGLRenderer {
10071022 uniformsGroups . dispose ( ) ;
10081023 programCache . dispose ( ) ;
10091024
1025+ // Dispose composite pass
1026+ _composite . dispose ( ) ;
1027+
10101028 xr . dispose ( ) ;
10111029
10121030 xr . removeEventListener ( 'sessionstart' , onXRSessionStart ) ;
@@ -1563,6 +1581,36 @@ class WebGLRenderer {
15631581
15641582 }
15651583
1584+ // Determine if we should use composite pass for tonemapping, color space conversion, and dithering
1585+ const useComposite = scene . isScene === true && _currentRenderTarget === null && _isRenderingComposite === false ;
1586+ const useXR = xr . enabled === true && xr . isPresenting === true ;
1587+ const userToneMapping = _this . toneMapping ;
1588+
1589+ let compositeRenderTarget = null ;
1590+
1591+ if ( useComposite ) {
1592+
1593+ // Choose render target based on XR mode
1594+ if ( useXR ) {
1595+
1596+ compositeRenderTarget = _composite . xrRenderTarget ;
1597+
1598+ // Resize XR render target to match the XR framebuffer
1599+ const size = _this . getDrawingBufferSize ( _vector2 ) ;
1600+ _composite . setXRSize ( size . x , size . y ) ;
1601+
1602+ } else {
1603+
1604+ compositeRenderTarget = _composite . renderTarget ;
1605+
1606+ }
1607+
1608+ // Render to internal MSAA target, disable tone mapping (will be applied in composite pass)
1609+ _this . setRenderTarget ( compositeRenderTarget ) ;
1610+ _this . toneMapping = NoToneMapping ;
1611+
1612+ }
1613+
15661614 //
15671615 if ( scene . isScene === true ) scene . onBeforeRender ( _this , scene , camera , _currentRenderTarget ) ;
15681616
@@ -1684,6 +1732,19 @@ class WebGLRenderer {
16841732
16851733 }
16861734
1735+ // Perform composite pass for tonemapping, color space conversion, and dithering
1736+ if ( useComposite ) {
1737+
1738+ // Restore tone mapping for composite pass
1739+ _this . toneMapping = userToneMapping ;
1740+
1741+ // Render composite pass to canvas
1742+ _isRenderingComposite = true ;
1743+ _composite . render ( _this , compositeRenderTarget ) ;
1744+ _isRenderingComposite = false ;
1745+
1746+ }
1747+
16871748 //
16881749
16891750 if ( scene . isScene === true ) scene . onAfterRender ( _this , scene , camera ) ;
0 commit comments