Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
* @author bhouston / http://clara.io/ *
*/

THREE.MSAAPass = function ( scene, camera, params ) {
THREE.ManualMSAARenderPass = function ( scene, camera, params ) {

this.scene = scene;
this.camera = camera;
Expand All @@ -12,7 +12,6 @@ THREE.MSAAPass = function ( scene, camera, params ) {
this.params = params || { minFilter: THREE.NearestFilter, magFilter: THREE.NearestFilter, format: THREE.RGBAFormat };
this.params.minFilter = THREE.NearestFilter;
this.params.maxFilter = THREE.NearestFilter;
console.log( 'this.params', this.params );
this.enabled = true;

this.needsSwap = true;
Expand All @@ -34,7 +33,7 @@ THREE.MSAAPass = function ( scene, camera, params ) {
transparent: true,
blending: THREE.CustomBlending,
blendSrc: THREE.OneFactor,
blendDst: THREE.OneMinusSrcAlphaFactor,
blendDst: THREE.OneFactor,
blendEquation: THREE.AddEquation,
depthTest: false,
depthWrite: false
Expand All @@ -48,7 +47,7 @@ THREE.MSAAPass = function ( scene, camera, params ) {

};

THREE.MSAAPass.prototype = {
THREE.ManualMSAARenderPass.prototype = {

dispose: function() {

Expand All @@ -70,43 +69,41 @@ THREE.MSAAPass.prototype = {

render: function ( renderer, writeBuffer, readBuffer, delta ) {

if ( ! this.sampleRenderTarget ) {
var camera = ( this.camera || this.scene.camera );
var jitterOffsets = THREE.ManualMSAARenderPass.JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 4 ) ) ];

if( jitterOffsets.length === 1 ) {

this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params, "msaa.renderTarget0" );
renderer.render( this.scene, camera, writeBuffer, true );
return;

}

var camera = ( this.camera || this.scene.camera );
if ( ! this.sampleRenderTarget ) {

this.sampleRenderTarget = new THREE.WebGLRenderTarget( readBuffer.width, readBuffer.height, this.params );

var jitterOffsets = THREE.MSAAPass.JitterVectors[ Math.max( 0, Math.min( this.sampleLevel, 5 ) ) ];
}

var autoClear = renderer.autoClear;
renderer.autoClear = false;

this.uniforms[ "scale" ].value = 1.0 / ( jitterOffsets.length );
this.uniforms[ "tForeground" ].value = this.sampleRenderTarget;

// render the scene multiple times, each slightly jitter offset from the last and accumulate the results.
for ( var i = 0; i < jitterOffsets.length; i ++ ) {

// only jitters perspective cameras. TODO: add support for jittering orthogonal cameras
if ( camera.setViewOffset ) camera.setViewOffset( readBuffer.width, readBuffer.height, jitterOffsets[ i ].x, jitterOffsets[ i ].y, readBuffer.width, readBuffer.height );

// on first sample, no need to accumulate
if ( i == 0 ) {

renderer.render( this.scene, camera, writeBuffer, true );

var jitterOffset = jitterOffsets[i];
if ( camera.setViewOffset ) {
camera.setViewOffset( readBuffer.width, readBuffer.height,
jitterOffset[ 0 ] * 0.0625, jitterOffset[ 1 ] * 0.0625, // 0.0625 = 1 / 16
readBuffer.width, readBuffer.height );
}
else {

renderer.render( this.scene, camera, this.sampleRenderTarget, true );

// this accumulation strategy is used to prevent decimation at low bit depths with lots of samples.
this.uniforms[ "scale" ].value = 1.0 / ( i + 1 );

renderer.render( this.scene2, this.camera2, writeBuffer, false );

}
renderer.render( this.scene, this.camera, this.sampleRenderTarget, true );
renderer.render( this.scene2, this.camera2, writeBuffer, ( i === 0 ) );

}

Expand All @@ -119,54 +116,29 @@ THREE.MSAAPass.prototype = {

};

THREE.MSAAPass.normalizedJitterOffsets = function( jitterVectors ) {

var scaledJitterOffsets = [];

for ( var i = 0; i < jitterVectors.length; i ++ ) {

scaledJitterOffsets.push( new THREE.Vector2( jitterVectors[ i ][ 0 ], jitterVectors[ i ][ 1 ] ).multiplyScalar( 1.0 / 16.0 ) );

}

return scaledJitterOffsets;

},

// These jitter vectors are specified in integers because it is easier.
// I am assuming a [-8,8) integer grid, but it needs to be mapped onto [-0.5,0.5)
// before being used, thus these integers need to be scaled by 1/16.
//
// Sample patterns reference: https://msdn.microsoft.com/en-us/library/windows/desktop/ff476218%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
THREE.MSAAPass.JitterVectors = [
THREE.MSAAPass.normalizedJitterOffsets( [
THREE.ManualMSAARenderPass.JitterVectors = [
[
[ 0, 0 ]
] ),
THREE.MSAAPass.normalizedJitterOffsets( [
],
[
[ 4, 4 ], [ - 4, - 4 ]
] ),
THREE.MSAAPass.normalizedJitterOffsets( [
],
[
[ - 2, - 6 ], [ 6, - 2 ], [ - 6, 2 ], [ 2, 6 ]
] ),
THREE.MSAAPass.normalizedJitterOffsets( [
],
[
[ 1, - 3 ], [ - 1, 3 ], [ 5, 1 ], [ - 3, - 5 ],
[ - 5, 5 ], [ - 7, - 1 ], [ 3, 7 ], [ 7, - 7 ]
] ),
THREE.MSAAPass.normalizedJitterOffsets( [
],
[
[ 1, 1 ], [ - 1, - 3 ], [ - 3, 2 ], [ 4, - 1 ],
[ - 5, - 2 ], [ 2, 5 ], [ 5, 3 ], [ 3, - 5 ],
[ - 2, 6 ], [ 0, - 7 ], [ - 4, - 6 ], [ - 6, 4 ],
[ - 8, 0 ], [ 7, - 4 ], [ 6, 7 ], [ - 7, - 8 ]
] ),
THREE.MSAAPass.normalizedJitterOffsets( [
[ - 4, - 7 ], [ - 7, - 5 ], [ - 3, - 5 ], [ - 5, - 4 ],
[ - 1, - 4 ], [ - 2, - 2 ], [ - 6, - 1 ], [ - 4, 0 ],
[ - 7, 1 ], [ - 1, 2 ], [ - 6, 3 ], [ - 3, 3 ],
[ - 7, 6 ], [ - 3, 6 ], [ - 5, 7 ], [ - 1, 7 ],
[ 5, - 7 ], [ 1, - 6 ], [ 6, - 5 ], [ 4, - 4 ],
[ 2, - 3 ], [ 7, - 2 ], [ 1, - 1 ], [ 4, - 1 ],
[ 2, 1 ], [ 6, 2 ], [ 0, 4 ], [ 4, 4 ],
[ 2, 5 ], [ 7, 5 ], [ 5, 6 ], [ 3, 7 ]
] )

]
];
19 changes: 9 additions & 10 deletions examples/webgl_postprocessing_msaa.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
<script src="js/libs/stats.min.js"></script>
<script src="js/libs/dat.gui.min.js"></script>

<script src="js/postprocessing/MSAAPass.js"></script>
<script src="js/postprocessing/ManualMSAARenderPass.js"></script>
<script src="js/shaders/CopyShader.js"></script>
<script src="js/shaders/CompositeShader.js"></script>

Expand All @@ -50,7 +50,7 @@

<script>

var camera, scene, renderer, composer, copyPass, msaaPass;
var camera, scene, renderer, composer, copyPass, manualMSAARenderPass;
var gui, stats, texture;

var param = { MSAASampleLevel: 2 };
Expand All @@ -71,12 +71,11 @@
'Level 1: 2 Samples': 1,
'Level 2: 4 Samples': 2,
'Level 3: 8 Samples': 3,
'Level 4: 16 Samples': 4,
'Level 5: 32 Samples': 5
'Level 4: 16 Samples': 4
} ).onFinishChange( function() {

if( massPass ) {
massPass.sampleLevel = param.MSAASampleLevel;
if( manualMSAARenderPass ) {
manualMSAARenderPass.sampleLevel = param.MSAASampleLevel;
}

} );
Expand Down Expand Up @@ -129,9 +128,9 @@

composer = new THREE.EffectComposer( renderer );

massPass = new THREE.MSAAPass( scene, camera );
massPass.sampleLevel = param.MSAASampleLevel;
composer.addPass( massPass );
manualMSAARenderPass = new THREE.ManualMSAARenderPass( scene, camera );
manualMSAARenderPass.sampleLevel = param.MSAASampleLevel;
composer.addPass( manualMSAARenderPass );

copyPass = new THREE.ShaderPass( THREE.CopyShader );
copyPass.renderToScreen = true;
Expand All @@ -155,7 +154,7 @@
var newWidth = Math.floor( width / pixelRatio ) || 1;
var newHeight = Math.floor( height / pixelRatio ) || 1;
composer.setSize( newWidth, newHeight );
if( msaaPass ) msaaPass.setSize( newWidth, newHeight );
msaaPass.setSize( newWidth, newHeight );

}

Expand Down