浏览代码

CopyShader: Assume render targets have premultiplied alpha. (#26179)

* CopyShader: Assume render targets have have premultiplied alpha.

* TAARenderPass: Fix accumulation issues.

* Use NoBlending in EffectComposer and SavePass.
Michael Herzog 2 年之前
父节点
当前提交
c1655d49d4

+ 2 - 0
examples/jsm/postprocessing/EffectComposer.js

@@ -1,6 +1,7 @@
 import {
 import {
 	Clock,
 	Clock,
 	HalfFloatType,
 	HalfFloatType,
+	NoBlending,
 	Vector2,
 	Vector2,
 	WebGLRenderTarget
 	WebGLRenderTarget
 } from 'three';
 } from 'three';
@@ -45,6 +46,7 @@ class EffectComposer {
 		this.passes = [];
 		this.passes = [];
 
 
 		this.copyPass = new ShaderPass( CopyShader );
 		this.copyPass = new ShaderPass( CopyShader );
+		this.copyPass.material.blending = NoBlending;
 
 
 		this.clock = new Clock();
 		this.clock = new Clock();
 
 

+ 3 - 12
examples/jsm/postprocessing/SSAARenderPass.js

@@ -1,8 +1,5 @@
 import {
 import {
-	CustomBlending,
-	OneFactor,
-	AddEquation,
-	SrcAlphaFactor,
+	AdditiveBlending,
 	Color,
 	Color,
 	HalfFloatType,
 	HalfFloatType,
 	ShaderMaterial,
 	ShaderMaterial,
@@ -48,14 +45,8 @@ class SSAARenderPass extends Pass {
 			transparent: true,
 			transparent: true,
 			depthTest: false,
 			depthTest: false,
 			depthWrite: false,
 			depthWrite: false,
-
-			// do not use AdditiveBlending because it mixes the alpha channel instead of adding
-			blending: CustomBlending,
-			blendEquation: AddEquation,
-			blendDst: OneFactor,
-			blendDstAlpha: OneFactor,
-			blendSrc: SrcAlphaFactor,
-			blendSrcAlpha: OneFactor
+			premultipliedAlpha: true,
+			blending: AdditiveBlending
 		} );
 		} );
 
 
 		this.fsQuad = new FullScreenQuad( this.copyMaterial );
 		this.fsQuad = new FullScreenQuad( this.copyMaterial );

+ 3 - 1
examples/jsm/postprocessing/SavePass.js

@@ -1,5 +1,6 @@
 import {
 import {
 	HalfFloatType,
 	HalfFloatType,
+	NoBlending,
 	ShaderMaterial,
 	ShaderMaterial,
 	UniformsUtils,
 	UniformsUtils,
 	WebGLRenderTarget
 	WebGLRenderTarget
@@ -23,7 +24,8 @@ class SavePass extends Pass {
 
 
 			uniforms: this.uniforms,
 			uniforms: this.uniforms,
 			vertexShader: shader.vertexShader,
 			vertexShader: shader.vertexShader,
-			fragmentShader: shader.fragmentShader
+			fragmentShader: shader.fragmentShader,
+			blending: NoBlending
 
 
 		} );
 		} );
 
 

+ 14 - 2
examples/jsm/postprocessing/TAARenderPass.js

@@ -65,7 +65,11 @@ class TAARenderPass extends SSAARenderPass {
 		const autoClear = renderer.autoClear;
 		const autoClear = renderer.autoClear;
 		renderer.autoClear = false;
 		renderer.autoClear = false;
 
 
+		renderer.getClearColor( this._oldClearColor );
+		const oldClearAlpha = renderer.getClearAlpha();
+
 		const sampleWeight = 1.0 / ( jitterOffsets.length );
 		const sampleWeight = 1.0 / ( jitterOffsets.length );
+		const accumulationWeight = this.accumulateIndex * sampleWeight;
 
 
 		if ( this.accumulateIndex >= 0 && this.accumulateIndex < jitterOffsets.length ) {
 		if ( this.accumulateIndex >= 0 && this.accumulateIndex < jitterOffsets.length ) {
 
 
@@ -88,11 +92,18 @@ class TAARenderPass extends SSAARenderPass {
 				}
 				}
 
 
 				renderer.setRenderTarget( writeBuffer );
 				renderer.setRenderTarget( writeBuffer );
+				renderer.setClearColor( this.clearColor, this.clearAlpha );
 				renderer.clear();
 				renderer.clear();
 				renderer.render( this.scene, this.camera );
 				renderer.render( this.scene, this.camera );
 
 
 				renderer.setRenderTarget( this.sampleRenderTarget );
 				renderer.setRenderTarget( this.sampleRenderTarget );
-				if ( this.accumulateIndex === 0 ) renderer.clear();
+				if ( this.accumulateIndex === 0 ) {
+
+					renderer.setClearColor( 0x000000, 0.0 );
+					renderer.clear();
+
+				}
+
 				this.fsQuad.render( renderer );
 				this.fsQuad.render( renderer );
 
 
 				this.accumulateIndex ++;
 				this.accumulateIndex ++;
@@ -105,7 +116,7 @@ class TAARenderPass extends SSAARenderPass {
 
 
 		}
 		}
 
 
-		const accumulationWeight = this.accumulateIndex * sampleWeight;
+		renderer.setClearColor( this.clearColor, this.clearAlpha );
 
 
 		if ( accumulationWeight > 0 ) {
 		if ( accumulationWeight > 0 ) {
 
 
@@ -128,6 +139,7 @@ class TAARenderPass extends SSAARenderPass {
 		}
 		}
 
 
 		renderer.autoClear = autoClear;
 		renderer.autoClear = autoClear;
+		renderer.setClearColor( this._oldClearColor, oldClearAlpha );
 
 
 	}
 	}
 
 

+ 2 - 1
examples/jsm/postprocessing/TexturePass.js

@@ -24,7 +24,8 @@ class TexturePass extends Pass {
 			vertexShader: shader.vertexShader,
 			vertexShader: shader.vertexShader,
 			fragmentShader: shader.fragmentShader,
 			fragmentShader: shader.fragmentShader,
 			depthTest: false,
 			depthTest: false,
-			depthWrite: false
+			depthWrite: false,
+			premultipliedAlpha: true
 
 
 		} );
 		} );
 
 

+ 1 - 2
examples/jsm/shaders/BlendShader.js

@@ -38,8 +38,7 @@ const BlendShader = {
 
 
 			vec4 texel1 = texture2D( tDiffuse1, vUv );
 			vec4 texel1 = texture2D( tDiffuse1, vUv );
 			vec4 texel2 = texture2D( tDiffuse2, vUv );
 			vec4 texel2 = texture2D( tDiffuse2, vUv );
-			gl_FragColor = mix( texel1, texel2, mixRatio );
-			gl_FragColor.a *= opacity;
+			gl_FragColor = opacity * mix( texel1, texel2, mixRatio );
 
 
 		}`
 		}`
 
 

+ 2 - 2
examples/jsm/shaders/CopyShader.js

@@ -34,8 +34,8 @@ const CopyShader = {
 
 
 		void main() {
 		void main() {
 
 
-			gl_FragColor = texture2D( tDiffuse, vUv );
-			gl_FragColor.a *= opacity;
+			vec4 texel = texture2D( tDiffuse, vUv );
+			gl_FragColor = opacity * texel;
 
 
 
 
 		}`
 		}`