TAARenderPass.js 3.8 KB
Newer Older
1
/**
2 3 4 5 6 7 8 9 10 11 12
 *
 * Temporal Anti-Aliasing Render Pass
 *
 * @author bhouston / http://clara.io/
 *
 * When there is no motion in the scene, the TAA render pass accumulates jittered camera samples across frames to create a high quality anti-aliased result.
 *
 * References:
 *
 * TODO: Add support for motion vector pas so that accumulation of samples across frames can occur on dynamics scenes.
 *
13 14 15 16
 */

THREE.TAARenderPass = function ( scene, camera, params ) {

17
	if ( THREE.SSAARenderPass === undefined ) {
18

M
Mr.doob 已提交
19
		console.error( "THREE.TAARenderPass relies on THREE.SSAARenderPass" );
20 21

	}
M
Mr.doob 已提交
22

23
	THREE.SSAARenderPass.call( this, scene, camera, params );
24

25
	this.sampleLevel = 0;
26
	this.accumulate = false;
27

28 29
};

30
THREE.TAARenderPass.JitterVectors = THREE.SSAARenderPass.JitterVectors;
31

32
THREE.TAARenderPass.prototype = Object.assign( Object.create( THREE.SSAARenderPass.prototype ), {
33

M
Mr.doob 已提交
34
	constructor: THREE.TAARenderPass,
35

36
	render: function ( renderer, writeBuffer, readBuffer, deltaTime ) {
37

M
Mr.doob 已提交
38
		if ( ! this.accumulate ) {
39

40
			THREE.SSAARenderPass.prototype.render.call( this, renderer, writeBuffer, readBuffer, deltaTime );
41

M
Mr.doob 已提交
42 43
			this.accumulateIndex = - 1;
			return;
44

45
		}
46

47
		var jitterOffsets = THREE.TAARenderPass.JitterVectors[ 5 ];
48

49
		if ( ! this.sampleRenderTarget ) {
50

51
			this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
52
			this.sampleRenderTarget.texture.name = "TAARenderPass.sample";
53

54
		}
55

56
		if ( ! this.holdRenderTarget ) {
57

58
			this.holdRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );
59
			this.holdRenderTarget.texture.name = "TAARenderPass.hold";
60

61
		}
62

M
Mr.doob 已提交
63
		if ( this.accumulate && this.accumulateIndex === - 1 ) {
64

65
			THREE.SSAARenderPass.prototype.render.call( this, renderer, this.holdRenderTarget, readBuffer, deltaTime );
66

M
Mr.doob 已提交
67
			this.accumulateIndex = 0;
68

69
		}
70

71 72
		var autoClear = renderer.autoClear;
		renderer.autoClear = false;
B
Ben Houston 已提交
73

74
		var sampleWeight = 1.0 / ( jitterOffsets.length );
75

M
Mr.doob 已提交
76
		if ( this.accumulateIndex >= 0 && this.accumulateIndex < jitterOffsets.length ) {
77

78 79
			this.copyUniforms[ "opacity" ].value = sampleWeight;
			this.copyUniforms[ "tDiffuse" ].value = writeBuffer.texture;
80

81 82 83
			// render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
			var numSamplesPerFrame = Math.pow( 2, this.sampleLevel );
			for ( var i = 0; i < numSamplesPerFrame; i ++ ) {
84

85
				var j = this.accumulateIndex;
M
Mr.doob 已提交
86 87
				var jitterOffset = jitterOffsets[ j ];

88
				if ( this.camera.setViewOffset ) {
M
Mr.doob 已提交
89

90
					this.camera.setViewOffset( readBuffer.width, readBuffer.height,
M
Mugen87 已提交
91
						jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625, // 0.0625 = 1 / 16
92
						readBuffer.width, readBuffer.height );
M
Mr.doob 已提交
93

94
				}
95

96 97 98 99 100 101
				renderer.setRenderTarget( writeBuffer );
				renderer.clear();
				renderer.render( this.scene, this.camera );

				renderer.setRenderTarget( this.sampleRenderTarget );
				if ( this.accumulateIndex === 0 ) renderer.clear();
102
				this.fsQuad.render( renderer );
103

104
				this.accumulateIndex ++;
M
Mr.doob 已提交
105 106 107

				if ( this.accumulateIndex >= jitterOffsets.length ) break;

108
			}
109

110
			if ( this.camera.clearViewOffset ) this.camera.clearViewOffset();
M
Mr.doob 已提交
111

112
		}
113

114
		var accumulationWeight = this.accumulateIndex * sampleWeight;
115

M
Mr.doob 已提交
116 117
		if ( accumulationWeight > 0 ) {

118 119
			this.copyUniforms[ "opacity" ].value = 1.0;
			this.copyUniforms[ "tDiffuse" ].value = this.sampleRenderTarget.texture;
120 121
			renderer.setRenderTarget( writeBuffer );
			renderer.clear();
122
			this.fsQuad.render( renderer );
M
Mr.doob 已提交
123

124
		}
M
Mr.doob 已提交
125 126 127

		if ( accumulationWeight < 1.0 ) {

128 129
			this.copyUniforms[ "opacity" ].value = 1.0 - accumulationWeight;
			this.copyUniforms[ "tDiffuse" ].value = this.holdRenderTarget.texture;
130 131
			renderer.setRenderTarget( writeBuffer );
			if ( accumulationWeight === 0 ) renderer.clear();
132
			this.fsQuad.render( renderer );
M
Mr.doob 已提交
133

134
		}
135

136 137 138
		renderer.autoClear = autoClear;

	}
139

M
Mr.doob 已提交
140
} );