Ver Fonte

Examples: Clean up.

Mugen87 há 4 anos atrás
pai
commit
1c55bb2e8a
2 ficheiros alterados com 734 adições e 656 exclusões
  1. 552 501
      examples/jsm/postprocessing/SSRPass.js
  2. 182 155
      examples/webgl_postprocessing_ssr.html

+ 552 - 501
examples/jsm/postprocessing/SSRPass.js

@@ -1,623 +1,674 @@
 import {
-  AddEquation,
-  Color,
-  NormalBlending,
-  DepthTexture,
+	AddEquation,
+	Color,
+	NormalBlending,
+	DepthTexture,
 	SrcAlphaFactor,
 	OneMinusSrcAlphaFactor,
-  LinearFilter,
-  MeshNormalMaterial,
-  MeshBasicMaterial,
-  NearestFilter,
-  NoBlending,
-  RGBAFormat,
-  ShaderMaterial,
-  UniformsUtils,
-  UnsignedShortType,
-  WebGLRenderTarget,
+	LinearFilter,
+	MeshNormalMaterial,
+	MeshBasicMaterial,
+	NearestFilter,
+	NoBlending,
+	RGBAFormat,
+	ShaderMaterial,
+	UniformsUtils,
+	UnsignedShortType,
+	WebGLRenderTarget,
 	HalfFloatType,
-} from "../../../build/three.module.js";
-import { Pass } from "../postprocessing/Pass.js";
-import { SSRShader } from "../shaders/SSRShader.js";
-import { SSRBlurShader } from "../shaders/SSRShader.js";
-import { SSRDepthShader } from "../shaders/SSRShader.js";
-import { CopyShader } from "../shaders/CopyShader.js";
+} from '../../../build/three.module.js';
+import { Pass } from '../postprocessing/Pass.js';
+import { SSRShader } from '../shaders/SSRShader.js';
+import { SSRBlurShader } from '../shaders/SSRShader.js';
+import { SSRDepthShader } from '../shaders/SSRShader.js';
+import { CopyShader } from '../shaders/CopyShader.js';
 
-var SSRPass = function({ renderer, scene, camera, width, height, selects, encoding, isPerspectiveCamera = true, isBouncing = false, morphTargets = false, groundReflector }) {
+var SSRPass = function ( { renderer, scene, camera, width, height, selects, encoding, isPerspectiveCamera = true, isBouncing = false, morphTargets = false, groundReflector } ) {
 
-  Pass.call(this);
+	Pass.call( this );
 
-  this.width = (width !== undefined) ? width : 512;
-  this.height = (height !== undefined) ? height : 512;
+	this.width = ( width !== undefined ) ? width : 512;
+	this.height = ( height !== undefined ) ? height : 512;
 
-  this.clear = true;
+	this.clear = true;
 
 	this.renderer = renderer;
 	this.scene = scene;
-  this.camera = camera;
+	this.camera = camera;
 	this.groundReflector = groundReflector;
 
-  this.opacity = SSRShader.uniforms.opacity.value;;
-  this.output = 0;
+	this.opacity = SSRShader.uniforms.opacity.value;
+	this.output = 0;
 
-  this.maxDistance = SSRShader.uniforms.maxDistance.value;
-  this.surfDist = SSRShader.uniforms.surfDist.value;
+	this.maxDistance = SSRShader.uniforms.maxDistance.value;
+	this.surfDist = SSRShader.uniforms.surfDist.value;
 
-	this.encoding = encoding
+	this.encoding = encoding;
 
-	this.tempColor = new Color()
+	this.tempColor = new Color();
 
-	this._selects = selects
-  this.isSelective = Array.isArray(this._selects)
-	Object.defineProperty(this, 'selects', {
+	this._selects = selects;
+	this.isSelective = Array.isArray( this._selects );
+	Object.defineProperty( this, 'selects', {
 		get() {
-			return this._selects
+
+			return this._selects;
+
+		},
+		set( val ) {
+
+			if ( this._selects === val ) return;
+			this._selects = val;
+			if ( Array.isArray( val ) ) {
+
+				this.isSelective = true;
+				this.ssrMaterial.defines.isSelective = true;
+				this.ssrMaterial.needsUpdate = true;
+
+			} else {
+
+				this.isSelective = false;
+				this.ssrMaterial.defines.isSelective = false;
+				this.ssrMaterial.needsUpdate = true;
+
+			}
+
+		}
+	} );
+
+	this._isBouncing = isBouncing; ///todo: don't need defineProperty
+	Object.defineProperty( this, 'isBouncing', {
+		get() {
+
+			return this._isBouncing;
+
 		},
-		set(val) {
-      if (this._selects === val) return
-      this._selects = val
-			if (Array.isArray(val)) {
-				this.isSelective = true
-				this.ssrMaterial.defines.isSelective = true
-				this.ssrMaterial.needsUpdate = true
+		set( val ) {
+
+			if ( this._isBouncing === val ) return;
+			this._isBouncing = val;
+			if ( val ) {
+
+				this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.prevRenderTarget.texture;
+
 			} else {
-				this.isSelective = false
-				this.ssrMaterial.defines.isSelective = false
-				this.ssrMaterial.needsUpdate = true
+
+				this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
+
 			}
+
 		}
-	})
-
-  this._isBouncing = isBouncing ///todo: don't need defineProperty
-  Object.defineProperty(this, 'isBouncing', {
-    get() {
-      return this._isBouncing
-    },
-    set(val) {
-      if (this._isBouncing === val) return
-      this._isBouncing = val
-      if (val) {
-        this.ssrMaterial.uniforms['tDiffuse'].value = this.prevRenderTarget.texture;
-      } else {
-        this.ssrMaterial.uniforms['tDiffuse'].value = this.beautyRenderTarget.texture;
-      }
-    }
-  })
-
-  this.isBlur = true
-
-  this._isDistanceAttenuation = SSRShader.defines.isDistanceAttenuation
-  Object.defineProperty(this, 'isDistanceAttenuation', {
-    get() {
-      return this._isDistanceAttenuation
-    },
-    set(val) {
-      if (this._isDistanceAttenuation === val) return
-      this._isDistanceAttenuation = val
-      this.ssrMaterial.defines.isDistanceAttenuation = val
-      this.ssrMaterial.needsUpdate = true
-    }
-	})
-
-
-  this._isFresnel = SSRShader.defines.isFresnel
-  Object.defineProperty(this, 'isFresnel', {
-    get() {
-      return this._isFresnel
-    },
-    set(val) {
-      if (this._isFresnel === val) return
-      this._isFresnel = val
-      this.ssrMaterial.defines.isFresnel = val
-      this.ssrMaterial.needsUpdate = true
-    }
-	})
-
-  this._isInfiniteThick = SSRShader.defines.isInfiniteThick
-  Object.defineProperty(this, 'isInfiniteThick', {
-    get() {
-      return this._isInfiniteThick
-    },
-    set(val) {
-      if (this._isInfiniteThick === val) return
-      this._isInfiniteThick = val
-      this.ssrMaterial.defines.isInfiniteThick = val
-      this.ssrMaterial.needsUpdate = true
-    }
-  })
-  this.thickTolerance = SSRShader.uniforms.thickTolerance.value;
-
-  // beauty render target with depth buffer
-
-  var depthTexture = new DepthTexture();
-  depthTexture.type = UnsignedShortType;
-  depthTexture.minFilter = NearestFilter;
-  depthTexture.maxFilter = NearestFilter;
-
-  this.beautyRenderTarget = new WebGLRenderTarget(this.width, this.height, {
-    minFilter: LinearFilter,
-    magFilter: LinearFilter,
-    format: RGBAFormat,
-    depthTexture: depthTexture,
-    depthBuffer: true
-  });
-
-  //for bouncing
-  this.prevRenderTarget = new WebGLRenderTarget(this.width, this.height, {
-    minFilter: LinearFilter,
-    magFilter: LinearFilter,
-    format: RGBAFormat,
-  });
-
-  // normal render target
-
-  this.normalRenderTarget = new WebGLRenderTarget(this.width, this.height, {
-    minFilter: NearestFilter,
-    magFilter: NearestFilter,
+	} );
+
+	this.isBlur = true;
+
+	this._isDistanceAttenuation = SSRShader.defines.isDistanceAttenuation;
+	Object.defineProperty( this, 'isDistanceAttenuation', {
+		get() {
+
+			return this._isDistanceAttenuation;
+
+		},
+		set( val ) {
+
+			if ( this._isDistanceAttenuation === val ) return;
+			this._isDistanceAttenuation = val;
+			this.ssrMaterial.defines.isDistanceAttenuation = val;
+			this.ssrMaterial.needsUpdate = true;
+
+		}
+	} );
+
+
+	this._isFresnel = SSRShader.defines.isFresnel;
+	Object.defineProperty( this, 'isFresnel', {
+		get() {
+
+			return this._isFresnel;
+
+		},
+		set( val ) {
+
+			if ( this._isFresnel === val ) return;
+			this._isFresnel = val;
+			this.ssrMaterial.defines.isFresnel = val;
+			this.ssrMaterial.needsUpdate = true;
+
+		}
+	} );
+
+	this._isInfiniteThick = SSRShader.defines.isInfiniteThick;
+	Object.defineProperty( this, 'isInfiniteThick', {
+		get() {
+
+			return this._isInfiniteThick;
+
+		},
+		set( val ) {
+
+			if ( this._isInfiniteThick === val ) return;
+			this._isInfiniteThick = val;
+			this.ssrMaterial.defines.isInfiniteThick = val;
+			this.ssrMaterial.needsUpdate = true;
+
+		}
+	} );
+	this.thickTolerance = SSRShader.uniforms.thickTolerance.value;
+
+	// beauty render target with depth buffer
+
+	var depthTexture = new DepthTexture();
+	depthTexture.type = UnsignedShortType;
+	depthTexture.minFilter = NearestFilter;
+	depthTexture.maxFilter = NearestFilter;
+
+	this.beautyRenderTarget = new WebGLRenderTarget( this.width, this.height, {
+		minFilter: LinearFilter,
+		magFilter: LinearFilter,
+		format: RGBAFormat,
+		depthTexture: depthTexture,
+		depthBuffer: true
+	} );
+
+	//for bouncing
+	this.prevRenderTarget = new WebGLRenderTarget( this.width, this.height, {
+		minFilter: LinearFilter,
+		magFilter: LinearFilter,
+		format: RGBAFormat,
+	} );
+
+	// normal render target
+
+	this.normalRenderTarget = new WebGLRenderTarget( this.width, this.height, {
+		minFilter: NearestFilter,
+		magFilter: NearestFilter,
 		format: RGBAFormat,
 		type: HalfFloatType,
-  });
-
-  // metalness render target
-
-  // if (this.isSelective) {
-    this.metalnessRenderTarget = new WebGLRenderTarget(this.width, this.height, {
-      minFilter: NearestFilter,
-      magFilter: NearestFilter,
-      format: RGBAFormat
-    });
-  // }
-
-
-
-  // ssr render target
-
-  this.ssrRenderTarget = new WebGLRenderTarget(this.width, this.height, {
-    minFilter: LinearFilter,
-    magFilter: LinearFilter,
-    format: RGBAFormat
-  });
-
-  this.blurRenderTarget = this.ssrRenderTarget.clone();
-  this.blurRenderTarget2 = this.ssrRenderTarget.clone();
-  // this.blurRenderTarget3 = this.ssrRenderTarget.clone();
-
-  // ssr material
-
-  if (SSRShader === undefined) {
-
-    console.error('THREE.SSRPass: The pass relies on SSRShader.');
-
-  }
-
-  this.ssrMaterial = new ShaderMaterial({
-    defines: Object.assign({
-      MAX_STEP: Math.sqrt(window.innerWidth * window.innerWidth + window.innerHeight * window.innerHeight)
-    }, SSRShader.defines),
-    uniforms: UniformsUtils.clone(SSRShader.uniforms),
-    vertexShader: SSRShader.vertexShader,
-    fragmentShader: SSRShader.fragmentShader,
-    blending: NoBlending
-  });
-  if (!isPerspectiveCamera) {
-    this.ssrMaterial.defines.isPerspectiveCamera = isPerspectiveCamera
-    this.ssrMaterial.needsUpdate = true
-  }
-
-  this.ssrMaterial.uniforms['tDiffuse'].value = this.beautyRenderTarget.texture;
-  this.ssrMaterial.uniforms['tNormal'].value = this.normalRenderTarget.texture;
-  // if (this.isSelective) {
-    this.ssrMaterial.defines.isSelective = this.isSelective
-    this.ssrMaterial.needsUpdate = true
-    this.ssrMaterial.uniforms['tMetalness'].value = this.metalnessRenderTarget.texture;
-  // }
-  this.ssrMaterial.uniforms['tDepth'].value = this.beautyRenderTarget.depthTexture;
-  this.ssrMaterial.uniforms['cameraNear'].value = this.camera.near;
-  this.ssrMaterial.uniforms['cameraFar'].value = this.camera.far;
-  this.ssrMaterial.uniforms['surfDist'].value = this.surfDist;
-  this.ssrMaterial.uniforms['resolution'].value.set(this.width, this.height);
-  this.ssrMaterial.uniforms['cameraProjectionMatrix'].value.copy(this.camera.projectionMatrix);
-  this.ssrMaterial.uniforms['cameraInverseProjectionMatrix'].value.copy(this.camera.projectionMatrixInverse);
-
-  // normal material
-
-  this.normalMaterial = new MeshNormalMaterial({ morphTargets });
-  this.normalMaterial.blending = NoBlending;
-
-  // if (this.isSelective) {
-    // metalnessOn material
-
-    this.metalnessOnMaterial = new MeshBasicMaterial({
-      color: 'white'
-    });
-
-    // metalnessOff material
-
-    this.metalnessOffMaterial = new MeshBasicMaterial({
-      color: 'black'
-    });
-  // }
-
-  // blur material
-
-  this.blurMaterial = new ShaderMaterial({
-    defines: Object.assign({}, SSRBlurShader.defines),
-    uniforms: UniformsUtils.clone(SSRBlurShader.uniforms),
-    vertexShader: SSRBlurShader.vertexShader,
-    fragmentShader: SSRBlurShader.fragmentShader
-  });
-  this.blurMaterial.uniforms['tDiffuse'].value = this.ssrRenderTarget.texture;
-  this.blurMaterial.uniforms['resolution'].value.set(this.width, this.height);
-
-  // blur material 2
-
-  this.blurMaterial2 = new ShaderMaterial({
-    defines: Object.assign({}, SSRBlurShader.defines),
-    uniforms: UniformsUtils.clone(SSRBlurShader.uniforms),
-    vertexShader: SSRBlurShader.vertexShader,
-    fragmentShader: SSRBlurShader.fragmentShader
-  });
-  this.blurMaterial2.uniforms['tDiffuse'].value = this.blurRenderTarget.texture;
-  this.blurMaterial2.uniforms['resolution'].value.set(this.width, this.height);
-
-  // // blur material 3
-
-  // this.blurMaterial3 = new ShaderMaterial({
-  //   defines: Object.assign({}, SSRBlurShader.defines),
-  //   uniforms: UniformsUtils.clone(SSRBlurShader.uniforms),
-  //   vertexShader: SSRBlurShader.vertexShader,
-  //   fragmentShader: SSRBlurShader.fragmentShader
-  // });
-  // this.blurMaterial3.uniforms['tDiffuse'].value = this.blurRenderTarget2.texture;
-  // this.blurMaterial3.uniforms['resolution'].value.set(this.width, this.height);
-
-  // material for rendering the depth
-
-  this.depthRenderMaterial = new ShaderMaterial({
-    defines: Object.assign({}, SSRDepthShader.defines),
-    uniforms: UniformsUtils.clone(SSRDepthShader.uniforms),
-    vertexShader: SSRDepthShader.vertexShader,
-    fragmentShader: SSRDepthShader.fragmentShader,
-    blending: NoBlending
-  });
-  this.depthRenderMaterial.uniforms['tDepth'].value = this.beautyRenderTarget.depthTexture;
-  this.depthRenderMaterial.uniforms['cameraNear'].value = this.camera.near;
-  this.depthRenderMaterial.uniforms['cameraFar'].value = this.camera.far;
-
-  // material for rendering the content of a render target
-
-  this.copyMaterial = new ShaderMaterial({
-    uniforms: UniformsUtils.clone(CopyShader.uniforms),
-    vertexShader: CopyShader.vertexShader,
-    fragmentShader: CopyShader.fragmentShader,
-    transparent: true,
-    depthTest: false,
-    depthWrite: false,
-    blendSrc: SrcAlphaFactor,
-    blendDst: OneMinusSrcAlphaFactor,
-    blendEquation: AddEquation,
-    blendSrcAlpha: SrcAlphaFactor,
-    blendDstAlpha: OneMinusSrcAlphaFactor,
-    blendEquationAlpha: AddEquation,
-    // premultipliedAlpha:true,
-  });
-
-  this.fsQuad = new Pass.FullScreenQuad(null);
-
-  this.originalClearColor = new Color();
+	} );
+
+	// metalness render target
+
+	// if (this.isSelective) {
+	this.metalnessRenderTarget = new WebGLRenderTarget( this.width, this.height, {
+		minFilter: NearestFilter,
+		magFilter: NearestFilter,
+		format: RGBAFormat
+	} );
+	// }
+
+
+
+	// ssr render target
+
+	this.ssrRenderTarget = new WebGLRenderTarget( this.width, this.height, {
+		minFilter: LinearFilter,
+		magFilter: LinearFilter,
+		format: RGBAFormat
+	} );
+
+	this.blurRenderTarget = this.ssrRenderTarget.clone();
+	this.blurRenderTarget2 = this.ssrRenderTarget.clone();
+	// this.blurRenderTarget3 = this.ssrRenderTarget.clone();
+
+	// ssr material
+
+	if ( SSRShader === undefined ) {
+
+		console.error( 'THREE.SSRPass: The pass relies on SSRShader.' );
+
+	}
+
+	this.ssrMaterial = new ShaderMaterial( {
+		defines: Object.assign( {
+			MAX_STEP: Math.sqrt( window.innerWidth * window.innerWidth + window.innerHeight * window.innerHeight )
+		}, SSRShader.defines ),
+		uniforms: UniformsUtils.clone( SSRShader.uniforms ),
+		vertexShader: SSRShader.vertexShader,
+		fragmentShader: SSRShader.fragmentShader,
+		blending: NoBlending
+	} );
+	if ( ! isPerspectiveCamera ) {
+
+		this.ssrMaterial.defines.isPerspectiveCamera = isPerspectiveCamera;
+		this.ssrMaterial.needsUpdate = true;
+
+	}
+
+	this.ssrMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
+	this.ssrMaterial.uniforms[ 'tNormal' ].value = this.normalRenderTarget.texture;
+	// if (this.isSelective) {
+	this.ssrMaterial.defines.isSelective = this.isSelective;
+	this.ssrMaterial.needsUpdate = true;
+	this.ssrMaterial.uniforms[ 'tMetalness' ].value = this.metalnessRenderTarget.texture;
+	// }
+	this.ssrMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
+	this.ssrMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
+	this.ssrMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
+	this.ssrMaterial.uniforms[ 'surfDist' ].value = this.surfDist;
+	this.ssrMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
+	this.ssrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
+	this.ssrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
+
+	// normal material
+
+	this.normalMaterial = new MeshNormalMaterial( { morphTargets } );
+	this.normalMaterial.blending = NoBlending;
+
+	// if (this.isSelective) {
+	// metalnessOn material
+
+	this.metalnessOnMaterial = new MeshBasicMaterial( {
+		color: 'white'
+	} );
+
+	// metalnessOff material
+
+	this.metalnessOffMaterial = new MeshBasicMaterial( {
+		color: 'black'
+	} );
+	// }
+
+	// blur material
+
+	this.blurMaterial = new ShaderMaterial( {
+		defines: Object.assign( {}, SSRBlurShader.defines ),
+		uniforms: UniformsUtils.clone( SSRBlurShader.uniforms ),
+		vertexShader: SSRBlurShader.vertexShader,
+		fragmentShader: SSRBlurShader.fragmentShader
+	} );
+	this.blurMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
+	this.blurMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
+
+	// blur material 2
+
+	this.blurMaterial2 = new ShaderMaterial( {
+		defines: Object.assign( {}, SSRBlurShader.defines ),
+		uniforms: UniformsUtils.clone( SSRBlurShader.uniforms ),
+		vertexShader: SSRBlurShader.vertexShader,
+		fragmentShader: SSRBlurShader.fragmentShader
+	} );
+	this.blurMaterial2.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget.texture;
+	this.blurMaterial2.uniforms[ 'resolution' ].value.set( this.width, this.height );
+
+	// // blur material 3
+
+	// this.blurMaterial3 = new ShaderMaterial({
+	//   defines: Object.assign({}, SSRBlurShader.defines),
+	//   uniforms: UniformsUtils.clone(SSRBlurShader.uniforms),
+	//   vertexShader: SSRBlurShader.vertexShader,
+	//   fragmentShader: SSRBlurShader.fragmentShader
+	// });
+	// this.blurMaterial3.uniforms['tDiffuse'].value = this.blurRenderTarget2.texture;
+	// this.blurMaterial3.uniforms['resolution'].value.set(this.width, this.height);
+
+	// material for rendering the depth
+
+	this.depthRenderMaterial = new ShaderMaterial( {
+		defines: Object.assign( {}, SSRDepthShader.defines ),
+		uniforms: UniformsUtils.clone( SSRDepthShader.uniforms ),
+		vertexShader: SSRDepthShader.vertexShader,
+		fragmentShader: SSRDepthShader.fragmentShader,
+		blending: NoBlending
+	} );
+	this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
+	this.depthRenderMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
+	this.depthRenderMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
+
+	// material for rendering the content of a render target
+
+	this.copyMaterial = new ShaderMaterial( {
+		uniforms: UniformsUtils.clone( CopyShader.uniforms ),
+		vertexShader: CopyShader.vertexShader,
+		fragmentShader: CopyShader.fragmentShader,
+		transparent: true,
+		depthTest: false,
+		depthWrite: false,
+		blendSrc: SrcAlphaFactor,
+		blendDst: OneMinusSrcAlphaFactor,
+		blendEquation: AddEquation,
+		blendSrcAlpha: SrcAlphaFactor,
+		blendDstAlpha: OneMinusSrcAlphaFactor,
+		blendEquationAlpha: AddEquation,
+		// premultipliedAlpha:true,
+	} );
+
+	this.fsQuad = new Pass.FullScreenQuad( null );
+
+	this.originalClearColor = new Color();
 
 };
 
-SSRPass.prototype = Object.assign(Object.create(Pass.prototype), {
+SSRPass.prototype = Object.assign( Object.create( Pass.prototype ), {
 
-  constructor: SSRPass,
+	constructor: SSRPass,
 
-  dispose: function() {
+	dispose: function () {
 
-    // dispose render targets
+		// dispose render targets
 
-    this.beautyRenderTarget.dispose();
-    this.prevRenderTarget.dispose();
-    this.normalRenderTarget.dispose();
+		this.beautyRenderTarget.dispose();
+		this.prevRenderTarget.dispose();
+		this.normalRenderTarget.dispose();
 		// if (this.isSelective)
-			this.metalnessRenderTarget.dispose();
-    this.ssrRenderTarget.dispose();
-    this.blurRenderTarget.dispose();
-    this.blurRenderTarget2.dispose();
-    // this.blurRenderTarget3.dispose();
+		this.metalnessRenderTarget.dispose();
+		this.ssrRenderTarget.dispose();
+		this.blurRenderTarget.dispose();
+		this.blurRenderTarget2.dispose();
+		// this.blurRenderTarget3.dispose();
 
-    // dispose materials
+		// dispose materials
 
-    this.normalMaterial.dispose();
-    // if (this.isSelective) {
-      this.metalnessOnMaterial.dispose();
-      this.metalnessOffMaterial.dispose();
-    // }
-    this.blurMaterial.dispose();
-    this.blurMaterial2.dispose();
-    this.copyMaterial.dispose();
-    this.depthRenderMaterial.dispose();
+		this.normalMaterial.dispose();
+		// if (this.isSelective) {
+		this.metalnessOnMaterial.dispose();
+		this.metalnessOffMaterial.dispose();
+		// }
+		this.blurMaterial.dispose();
+		this.blurMaterial2.dispose();
+		this.copyMaterial.dispose();
+		this.depthRenderMaterial.dispose();
 
-    // dipsose full screen quad
+		// dipsose full screen quad
 
-    this.fsQuad.dispose();
+		this.fsQuad.dispose();
 
-  },
+	},
 
-  render: function(renderer, writeBuffer /*, readBuffer, deltaTime, maskActive */ ) {
+	render: function ( renderer, writeBuffer /*, readBuffer, deltaTime, maskActive */ ) {
 
-    // render beauty and depth
+		// render beauty and depth
 
-    if (this.encoding) this.beautyRenderTarget.texture.encoding = this.encoding
-    renderer.setRenderTarget(this.beautyRenderTarget);
+		if ( this.encoding ) this.beautyRenderTarget.texture.encoding = this.encoding;
+		renderer.setRenderTarget( this.beautyRenderTarget );
 		renderer.clear();
-		if (this.groundReflector) {
-			this.groundReflector.doRender(this.renderer, this.scene, this.camera);
-			this.groundReflector.visible = true
+		if ( this.groundReflector ) {
+
+			this.groundReflector.doRender( this.renderer, this.scene, this.camera );
+			this.groundReflector.visible = true;
+
+		}
+
+		renderer.render( this.scene, this.camera );
+		if ( this.groundReflector ) this.groundReflector.visible = false;
+
+		// render normals
+
+		this.renderOverride( renderer, this.normalMaterial, this.normalRenderTarget, 0, 0 );
+
+		// render metalnesses
+
+		if ( this.isSelective ) {
+
+			this.renderMetalness( renderer, this.metalnessOnMaterial, this.metalnessRenderTarget, 0, 0 );
+
 		}
-    renderer.render(this.scene, this.camera);
-		if(this.groundReflector) this.groundReflector.visible=false
 
-    // render normals
+		// render SSR
+
+		this.ssrMaterial.uniforms[ 'opacity' ].value = this.opacity;
+		this.ssrMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance;
+		this.ssrMaterial.uniforms[ 'surfDist' ].value = this.surfDist;
+		this.ssrMaterial.uniforms[ 'thickTolerance' ].value = this.thickTolerance;
+		this.renderPass( renderer, this.ssrMaterial, this.ssrRenderTarget );
 
-    this.renderOverride(renderer, this.normalMaterial, this.normalRenderTarget, 0, 0);
 
-    // render metalnesses
+		// render blur
 
-    if (this.isSelective) {
-      this.renderMetalness(renderer, this.metalnessOnMaterial, this.metalnessRenderTarget, 0, 0);
-    }
+		if ( this.isBlur ) {
 
-    // render SSR
+			this.renderPass( renderer, this.blurMaterial, this.blurRenderTarget );
+			this.renderPass( renderer, this.blurMaterial2, this.blurRenderTarget2 );
+			// this.renderPass(renderer, this.blurMaterial3, this.blurRenderTarget3);
 
-    this.ssrMaterial.uniforms['opacity'].value = this.opacity;
-    this.ssrMaterial.uniforms['maxDistance'].value = this.maxDistance;
-    this.ssrMaterial.uniforms['surfDist'].value = this.surfDist;
-    this.ssrMaterial.uniforms['thickTolerance'].value = this.thickTolerance
-    this.renderPass(renderer, this.ssrMaterial, this.ssrRenderTarget);
+		}
 
+		// output result to screen
 
-    // render blur
+		switch ( this.output ) {
 
-    if (this.isBlur) {
-      this.renderPass(renderer, this.blurMaterial, this.blurRenderTarget);
-      this.renderPass(renderer, this.blurMaterial2, this.blurRenderTarget2);
-      // this.renderPass(renderer, this.blurMaterial3, this.blurRenderTarget3);
-    }
+			case SSRPass.OUTPUT.Default:
 
-    // output result to screen
+				if ( this.isBouncing ) {
 
-    switch (this.output) {
+					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
+					this.copyMaterial.blending = NoBlending;
+					this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
 
-      case SSRPass.OUTPUT.Default:
+					if ( this.isBlur )
+						this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture;
+					else
+						this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
+					this.copyMaterial.blending = NormalBlending;
+					this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
 
-        if (this.isBouncing) {
-          this.copyMaterial.uniforms['tDiffuse'].value = this.beautyRenderTarget.texture;
-          this.copyMaterial.blending = NoBlending;
-          this.renderPass(renderer, this.copyMaterial, this.prevRenderTarget);
+					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.prevRenderTarget.texture;
+					this.copyMaterial.blending = NoBlending;
+					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
 
-          if (this.isBlur)
-            this.copyMaterial.uniforms['tDiffuse'].value = this.blurRenderTarget2.texture;
-          else
-            this.copyMaterial.uniforms['tDiffuse'].value = this.ssrRenderTarget.texture;
-          this.copyMaterial.blending = NormalBlending;
-          this.renderPass(renderer, this.copyMaterial, this.prevRenderTarget);
+				} else {
 
-          this.copyMaterial.uniforms['tDiffuse'].value = this.prevRenderTarget.texture;
-          this.copyMaterial.blending = NoBlending;
-          this.renderPass(renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer);
-        } else {
-          this.copyMaterial.uniforms['tDiffuse'].value = this.beautyRenderTarget.texture;
-          this.copyMaterial.blending = NoBlending;
-          this.renderPass(renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer);
+					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
+					this.copyMaterial.blending = NoBlending;
+					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
 
-          if (this.isBlur)
-            this.copyMaterial.uniforms['tDiffuse'].value = this.blurRenderTarget2.texture;
-          else
-            this.copyMaterial.uniforms['tDiffuse'].value = this.ssrRenderTarget.texture;
-          this.copyMaterial.blending = NormalBlending;
-          this.renderPass(renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer);
-        }
+					if ( this.isBlur )
+						this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture;
+					else
+						this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
+					this.copyMaterial.blending = NormalBlending;
+					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
 
-        break;
-      case SSRPass.OUTPUT.SSR:
+				}
 
-        if (this.isBlur)
-          this.copyMaterial.uniforms['tDiffuse'].value = this.blurRenderTarget2.texture;
-        else
-          this.copyMaterial.uniforms['tDiffuse'].value = this.ssrRenderTarget.texture;
-        this.copyMaterial.blending = NoBlending;
-        this.renderPass(renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer);
+				break;
+			case SSRPass.OUTPUT.SSR:
 
-        if (this.isBouncing) {
-          if (this.isBlur)
-            this.copyMaterial.uniforms['tDiffuse'].value = this.blurRenderTarget2.texture;
-          else
-            this.copyMaterial.uniforms['tDiffuse'].value = this.beautyRenderTarget.texture;
-          this.copyMaterial.blending = NoBlending;
-          this.renderPass(renderer, this.copyMaterial, this.prevRenderTarget);
+				if ( this.isBlur )
+					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture;
+				else
+					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
+				this.copyMaterial.blending = NoBlending;
+				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
 
-          this.copyMaterial.uniforms['tDiffuse'].value = this.ssrRenderTarget.texture;
-          this.copyMaterial.blending = NormalBlending;
-          this.renderPass(renderer, this.copyMaterial, this.prevRenderTarget);
-        }
+				if ( this.isBouncing ) {
 
-        break;
+					if ( this.isBlur )
+						this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.blurRenderTarget2.texture;
+					else
+						this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
+					this.copyMaterial.blending = NoBlending;
+					this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
 
-      case SSRPass.OUTPUT.Beauty:
+					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrRenderTarget.texture;
+					this.copyMaterial.blending = NormalBlending;
+					this.renderPass( renderer, this.copyMaterial, this.prevRenderTarget );
 
-        this.copyMaterial.uniforms['tDiffuse'].value = this.beautyRenderTarget.texture;
-        this.copyMaterial.blending = NoBlending;
-        this.renderPass(renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer);
+				}
 
-        break;
+				break;
 
-      case SSRPass.OUTPUT.Depth:
+			case SSRPass.OUTPUT.Beauty:
 
-        this.renderPass(renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer);
+				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
+				this.copyMaterial.blending = NoBlending;
+				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
 
-        break;
+				break;
 
-      case SSRPass.OUTPUT.Normal:
+			case SSRPass.OUTPUT.Depth:
 
-        this.copyMaterial.uniforms['tDiffuse'].value = this.normalRenderTarget.texture;
-        this.copyMaterial.blending = NoBlending;
-        this.renderPass(renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer);
+				this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
 
-        break;
+				break;
 
-      case SSRPass.OUTPUT.Metalness:
+			case SSRPass.OUTPUT.Normal:
 
-        this.copyMaterial.uniforms['tDiffuse'].value = this.metalnessRenderTarget.texture;
-        this.copyMaterial.blending = NoBlending;
-        this.renderPass(renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer);
+				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalRenderTarget.texture;
+				this.copyMaterial.blending = NoBlending;
+				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
 
-        break;
+				break;
 
-      default:
-        console.warn('THREE.SSRPass: Unknown output type.');
+			case SSRPass.OUTPUT.Metalness:
 
-    }
+				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.metalnessRenderTarget.texture;
+				this.copyMaterial.blending = NoBlending;
+				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
 
-  },
+				break;
 
-  renderPass: function(renderer, passMaterial, renderTarget, clearColor, clearAlpha) {
+			default:
+				console.warn( 'THREE.SSRPass: Unknown output type.' );
 
-    // save original state
-    this.originalClearColor.copy(renderer.getClearColor(this.tempColor));
-    var originalClearAlpha = renderer.getClearAlpha(this.tempColor);
-    var originalAutoClear = renderer.autoClear;
+		}
 
-    renderer.setRenderTarget(renderTarget);
+	},
 
-    // setup pass state
-    renderer.autoClear = false;
-    if ((clearColor !== undefined) && (clearColor !== null)) {
+	renderPass: function ( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
 
-      renderer.setClearColor(clearColor);
-      renderer.setClearAlpha(clearAlpha || 0.0);
-      renderer.clear();
+		// save original state
+		this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
+		var originalClearAlpha = renderer.getClearAlpha( this.tempColor );
+		var originalAutoClear = renderer.autoClear;
 
-    }
+		renderer.setRenderTarget( renderTarget );
 
-    this.fsQuad.material = passMaterial;
-    this.fsQuad.render(renderer);
+		// setup pass state
+		renderer.autoClear = false;
+		if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
 
-    // restore original state
-    renderer.autoClear = originalAutoClear;
-    renderer.setClearColor(this.originalClearColor);
-    renderer.setClearAlpha(originalClearAlpha);
+			renderer.setClearColor( clearColor );
+			renderer.setClearAlpha( clearAlpha || 0.0 );
+			renderer.clear();
 
-  },
+		}
 
-  renderOverride: function(renderer, overrideMaterial, renderTarget, clearColor, clearAlpha) {
+		this.fsQuad.material = passMaterial;
+		this.fsQuad.render( renderer );
 
-    this.originalClearColor.copy(renderer.getClearColor(this.tempColor));
-    var originalClearAlpha = renderer.getClearAlpha(this.tempColor);
-    var originalAutoClear = renderer.autoClear;
+		// restore original state
+		renderer.autoClear = originalAutoClear;
+		renderer.setClearColor( this.originalClearColor );
+		renderer.setClearAlpha( originalClearAlpha );
 
-    renderer.setRenderTarget(renderTarget);
-    renderer.autoClear = false;
+	},
 
-    clearColor = overrideMaterial.clearColor || clearColor;
-    clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
+	renderOverride: function ( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
 
-    if ((clearColor !== undefined) && (clearColor !== null)) {
+		this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
+		var originalClearAlpha = renderer.getClearAlpha( this.tempColor );
+		var originalAutoClear = renderer.autoClear;
 
-      renderer.setClearColor(clearColor);
-      renderer.setClearAlpha(clearAlpha || 0.0);
-      renderer.clear();
+		renderer.setRenderTarget( renderTarget );
+		renderer.autoClear = false;
+
+		clearColor = overrideMaterial.clearColor || clearColor;
+		clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
+
+		if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
+
+			renderer.setClearColor( clearColor );
+			renderer.setClearAlpha( clearAlpha || 0.0 );
+			renderer.clear();
+
+		}
 
-    }
+		this.scene.overrideMaterial = overrideMaterial;
+		renderer.render( this.scene, this.camera );
+		this.scene.overrideMaterial = null;
 
-    this.scene.overrideMaterial = overrideMaterial;
-    renderer.render(this.scene, this.camera);
-    this.scene.overrideMaterial = null;
+		// restore original state
 
-    // restore original state
+		renderer.autoClear = originalAutoClear;
+		renderer.setClearColor( this.originalClearColor );
+		renderer.setClearAlpha( originalClearAlpha );
 
-    renderer.autoClear = originalAutoClear;
-    renderer.setClearColor(this.originalClearColor);
-    renderer.setClearAlpha(originalClearAlpha);
+	},
 
-  },
+	renderMetalness: function ( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
 
-  renderMetalness: function(renderer, overrideMaterial, renderTarget, clearColor, clearAlpha) {
+		this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
+		var originalClearAlpha = renderer.getClearAlpha( this.tempColor );
+		var originalAutoClear = renderer.autoClear;
 
-    this.originalClearColor.copy(renderer.getClearColor(this.tempColor));
-    var originalClearAlpha = renderer.getClearAlpha(this.tempColor);
-    var originalAutoClear = renderer.autoClear;
+		renderer.setRenderTarget( renderTarget );
+		renderer.autoClear = false;
 
-    renderer.setRenderTarget(renderTarget);
-    renderer.autoClear = false;
+		clearColor = overrideMaterial.clearColor || clearColor;
+		clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
 
-    clearColor = overrideMaterial.clearColor || clearColor;
-    clearAlpha = overrideMaterial.clearAlpha || clearAlpha;
+		if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
 
-    if ((clearColor !== undefined) && (clearColor !== null)) {
+			renderer.setClearColor( clearColor );
+			renderer.setClearAlpha( clearAlpha || 0.0 );
+			renderer.clear();
+
+		}
+
+		this.scene.traverseVisible( child => {
+
+			child._SSRPassMaterialBack = child.material;
+			if ( this._selects.includes( child ) ) {
+
+				child.material = this.metalnessOnMaterial;
+
+			} else {
+
+				child.material = this.metalnessOffMaterial;
+
+			}
 
-      renderer.setClearColor(clearColor);
-      renderer.setClearAlpha(clearAlpha || 0.0);
-      renderer.clear();
+		} );
+		renderer.render( this.scene, this.camera );
+		this.scene.traverseVisible( child => {
 
-    }
+			child.material = child._SSRPassMaterialBack;
 
-    this.scene.traverseVisible(child => {
-      child._SSRPassMaterialBack = child.material
-      if (this._selects.includes(child)) {
-        child.material = this.metalnessOnMaterial
-      } else {
-        child.material = this.metalnessOffMaterial
-      }
-    })
-    renderer.render(this.scene, this.camera);
-    this.scene.traverseVisible(child => {
-      child.material = child._SSRPassMaterialBack
-    })
+		} );
 
-    // restore original state
+		// restore original state
 
-    renderer.autoClear = originalAutoClear;
-    renderer.setClearColor(this.originalClearColor);
-    renderer.setClearAlpha(originalClearAlpha);
+		renderer.autoClear = originalAutoClear;
+		renderer.setClearColor( this.originalClearColor );
+		renderer.setClearAlpha( originalClearAlpha );
 
-  },
+	},
 
-  setSize: function(width, height) {
+	setSize: function ( width, height ) {
 
-    this.width = width;
-    this.height = height;
+		this.width = width;
+		this.height = height;
 
-    this.ssrMaterial.defines.MAX_STEP = Math.sqrt(width * width + height * height)
-    this.ssrMaterial.needsUpdate = true
-    this.beautyRenderTarget.setSize(width, height);
-    this.prevRenderTarget.setSize(width, height);
-    this.ssrRenderTarget.setSize(width, height);
-    this.normalRenderTarget.setSize(width, height);
+		this.ssrMaterial.defines.MAX_STEP = Math.sqrt( width * width + height * height );
+		this.ssrMaterial.needsUpdate = true;
+		this.beautyRenderTarget.setSize( width, height );
+		this.prevRenderTarget.setSize( width, height );
+		this.ssrRenderTarget.setSize( width, height );
+		this.normalRenderTarget.setSize( width, height );
 		// if (this.isSelective)
-			this.metalnessRenderTarget.setSize(width, height);
-    this.blurRenderTarget.setSize(width, height);
-    this.blurRenderTarget2.setSize(width, height);
-    // this.blurRenderTarget3.setSize(width, height);
+		this.metalnessRenderTarget.setSize( width, height );
+		this.blurRenderTarget.setSize( width, height );
+		this.blurRenderTarget2.setSize( width, height );
+		// this.blurRenderTarget3.setSize(width, height);
 
-    this.ssrMaterial.uniforms['resolution'].value.set(width, height);
-    this.ssrMaterial.uniforms['cameraProjectionMatrix'].value.copy(this.camera.projectionMatrix);
-    this.ssrMaterial.uniforms['cameraInverseProjectionMatrix'].value.copy(this.camera.projectionMatrixInverse);
+		this.ssrMaterial.uniforms[ 'resolution' ].value.set( width, height );
+		this.ssrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
+		this.ssrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
 
-    this.blurMaterial.uniforms['resolution'].value.set(width, height);
-    this.blurMaterial2.uniforms['resolution'].value.set(width, height);
+		this.blurMaterial.uniforms[ 'resolution' ].value.set( width, height );
+		this.blurMaterial2.uniforms[ 'resolution' ].value.set( width, height );
 
-  },
+	},
 
-});
+} );
 
 SSRPass.OUTPUT = {
-  'Default': 0,
-  'SSR': 1,
-  'Beauty': 3,
-  'Depth': 4,
-  'Normal': 5,
-  'Metalness': 7,
+	'Default': 0,
+	'SSR': 1,
+	'Beauty': 3,
+	'Depth': 4,
+	'Normal': 5,
+	'Metalness': 7,
 };
 
 export { SSRPass };

+ 182 - 155
examples/webgl_postprocessing_ssr.html

@@ -14,7 +14,7 @@
 	<div id="container"></div>
 	<div id="info">
 		<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> -
-		<a href="https://github.com/mrdoob/three.js/pull/20156" target="_blank" rel="noopener">SSRPass</a> demo by <a href="https://github.com/gonnavis" target="_blank">Vis</a>.<br />
+		SSRPass demo by <a href="https://github.com/gonnavis" target="_blank">Vis</a>.<br />
 	</div>
 
 	<script type="module">
@@ -22,7 +22,7 @@
 
 		import Stats from './jsm/libs/stats.module.js';
 
-		import { OrbitControls } from './jsm/controls/OrbitControls.js'
+		import { OrbitControls } from './jsm/controls/OrbitControls.js';
 
 		import { GUI } from './jsm/libs/dat.gui.module.js';
 		import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
@@ -31,150 +31,142 @@
 
 		import { DRACOLoader } from './jsm/loaders/DRACOLoader.js';
 
-		let params = {
+		const params = {
 			enableSSR: true,
 			autoRotate: true,
 			isOtherMeshes: true,
 			isGroundReflector: true,
-		}
-		let composer
-		let ssrPass
-		let gui
-		let isPerspectiveCamera = true
+		};
+		let composer;
+		let ssrPass;
+		let gui;
+		const isPerspectiveCamera = true;
 		let stats;
-		let mesh;
 		let controls;
 		let camera, scene, renderer;
-		let otherMeshes = []
-		let groundReflector
-		let selects=[]
+		const otherMeshes = [];
+		let groundReflector;
+		const selects = [];
 
-		const container = document.querySelector('#container');
+		const container = document.querySelector( '#container' );
 
 		// Configure and create Draco decoder.
 		const dracoLoader = new DRACOLoader();
-		dracoLoader.setDecoderPath('js/libs/draco/');
-		dracoLoader.setDecoderConfig({ type: 'js' });
+		dracoLoader.setDecoderPath( 'js/libs/draco/' );
+		dracoLoader.setDecoderConfig( { type: 'js' } );
 
 		init();
 		animate();
 
 		function init() {
 
-			camera = new THREE.PerspectiveCamera(35, window.innerWidth / window.innerHeight, 0.1, 15);
-			camera.position.set(0.13271600513224902, 0.3489546826045913, 0.43921296427927076);
+			camera = new THREE.PerspectiveCamera( 35, window.innerWidth / window.innerHeight, 0.1, 15 );
+			camera.position.set( 0.13271600513224902, 0.3489546826045913, 0.43921296427927076 );
 
 			scene = new THREE.Scene();
-			scene.background = new THREE.Color(0x443333);
-			scene.fog = new THREE.Fog(0x443333, 1, 4);
+			scene.background = new THREE.Color( 0x443333 );
+			scene.fog = new THREE.Fog( 0x443333, 1, 4 );
 
 			// Ground
 			const plane = new THREE.Mesh(
-				new THREE.PlaneGeometry(8, 8),
-				new THREE.MeshPhongMaterial({ color: 0x999999, specular: 0x101010 })
+				new THREE.PlaneGeometry( 8, 8 ),
+				new THREE.MeshPhongMaterial( { color: 0x999999, specular: 0x101010 } )
 			);
 			plane.rotation.x = - Math.PI / 2;
 			plane.position.y = 0.0365;
 			// plane.receiveShadow = true;
-			scene.add(plane);
+			scene.add( plane );
 
 			// Lights
-			const hemiLight = new THREE.HemisphereLight(0x443333, 0x111122);
-			scene.add(hemiLight);
+			const hemiLight = new THREE.HemisphereLight( 0x443333, 0x111122 );
+			scene.add( hemiLight );
 
 			const spotLight = new THREE.SpotLight();
 			spotLight.angle = Math.PI / 16;
 			spotLight.penumbra = 0.5;
 			// spotLight.castShadow = true;
-			spotLight.position.set(- 1, 1, 1);
-			scene.add(spotLight);
+			spotLight.position.set( - 1, 1, 1 );
+			scene.add( spotLight );
 
-			dracoLoader.load('models/draco/bunny.drc', function (geometry) {
+			dracoLoader.load( 'models/draco/bunny.drc', function ( geometry ) {
 
 				geometry.computeVertexNormals();
 
-				const material = new THREE.MeshStandardMaterial({ color: 0x606060 });
-				const mesh = new THREE.Mesh(geometry, material);
-				// mesh.castShadow = true;
-				// mesh.receiveShadow = true;
-				scene.add(mesh);
-				selects.push(mesh)
+				const material = new THREE.MeshStandardMaterial( { color: 0x606060 } );
+				const mesh = new THREE.Mesh( geometry, material );
+				scene.add( mesh );
+				selects.push( mesh );
 
 				// Release decoder resources.
 				dracoLoader.dispose();
 
-			});
-
-			{
-				const geometry = new THREE.BoxBufferGeometry(.05, .05, .05);
-				const material = new THREE.MeshStandardMaterial({ color: 'green' })
-				const mesh = new THREE.Mesh(geometry, material)
-				mesh.position.set(-.12, plane.position.y + .025, .015)
-				scene.add(mesh)
-				otherMeshes.push(mesh)
-				selects.push(mesh)
-			}
-			{
-				const geometry = new THREE.IcosahedronBufferGeometry(.025, 4);
-				const material = new THREE.MeshStandardMaterial({ color: 'cyan' })
-				const mesh = new THREE.Mesh(geometry, material)
-				mesh.position.set(-.05, plane.position.y + .025, .08)
-				scene.add(mesh)
-				otherMeshes.push(mesh)
-				selects.push(mesh)
-			}
-			{
-				const geometry = new THREE.ConeBufferGeometry(.025, .05, 64);
-				const material = new THREE.MeshStandardMaterial({ color: 'yellow' })
-				const mesh = new THREE.Mesh(geometry, material)
-				mesh.position.set(-.05, plane.position.y + .025, -.055)
-				scene.add(mesh)
-				otherMeshes.push(mesh)
-				selects.push(mesh)
-			}
-			{
-				const geometry = new THREE.PlaneBufferGeometry(8, 8);
-				groundReflector = new Reflector(geometry, {
-					clipBias: 0.003,
-					textureWidth: window.innerWidth,
-					textureHeight: window.innerHeight,
-					color: 0x888888,
-					useDepthTexture: true,
-				});
-				groundReflector.material.depthWrite = false;
-				groundReflector.position.y = plane.position.y + .0001;
-				groundReflector.rotation.x = -Math.PI / 2
-				groundReflector.visible = false
-				scene.add(groundReflector);
-			}
+			} );
+
+			let geometry, material, mesh;
+
+			geometry = new THREE.BoxBufferGeometry( .05, .05, .05 );
+			material = new THREE.MeshStandardMaterial( { color: 'green' } );
+			mesh = new THREE.Mesh( geometry, material );
+			mesh.position.set( - .12, plane.position.y + .025, .015 );
+			scene.add( mesh );
+			otherMeshes.push( mesh );
+			selects.push( mesh );
+
+			geometry = new THREE.IcosahedronBufferGeometry( .025, 4 );
+			material = new THREE.MeshStandardMaterial( { color: 'cyan' } );
+			mesh = new THREE.Mesh( geometry, material );
+			mesh.position.set( - .05, plane.position.y + .025, .08 );
+			scene.add( mesh );
+			otherMeshes.push( mesh );
+			selects.push( mesh );
+
+			geometry = new THREE.ConeBufferGeometry( .025, .05, 64 );
+			material = new THREE.MeshStandardMaterial( { color: 'yellow' } );
+			mesh = new THREE.Mesh( geometry, material );
+			mesh.position.set( - .05, plane.position.y + .025, - .055 );
+			scene.add( mesh );
+			otherMeshes.push( mesh );
+			selects.push( mesh );
+
+			geometry = new THREE.PlaneBufferGeometry( 8, 8 );
+			groundReflector = new Reflector( geometry, {
+				clipBias: 0.003,
+				textureWidth: window.innerWidth,
+				textureHeight: window.innerHeight,
+				color: 0x888888,
+				useDepthTexture: true,
+			} );
+			groundReflector.material.depthWrite = false;
+			groundReflector.position.y = plane.position.y + .0001;
+			groundReflector.rotation.x = - Math.PI / 2;
+			groundReflector.visible = false;
+			scene.add( groundReflector );
 
 			// renderer
-			renderer = new THREE.WebGLRenderer({ antialias: false });
-			// renderer.setPixelRatio(window.devicePixelRatio);
-			renderer.setSize(window.innerWidth, window.innerHeight);
+			renderer = new THREE.WebGLRenderer( { antialias: false } );
+			renderer.setSize( window.innerWidth, window.innerHeight );
 			renderer.outputEncoding = THREE.sRGBEncoding;
-			// renderer.shadowMap.enabled = true;
-			container.appendChild(renderer.domElement);
+			container.appendChild( renderer.domElement );
 
 			//
 
-			controls = new OrbitControls(camera, renderer.domElement);
-			controls.enableDamping = true
-			controls.target.set(0, 0.1, 0);
-			controls.update()
-			controls.enabled = !params.autoRotate
+			controls = new OrbitControls( camera, renderer.domElement );
+			controls.enableDamping = true;
+			controls.target.set( 0, 0.1, 0 );
+			controls.update();
+			controls.enabled = ! params.autoRotate;
 
 			// STATS
 
 			stats = new Stats();
-			container.appendChild(stats.dom);
+			container.appendChild( stats.dom );
 
-			window.addEventListener('resize', onWindowResize, false);
+			window.addEventListener( 'resize', onWindowResize, false );
 
 			// composer
 
-			composer = new EffectComposer(renderer);
-			ssrPass = new SSRPass({
+			composer = new EffectComposer( renderer );
+			ssrPass = new SSRPass( {
 				renderer,
 				scene,
 				camera,
@@ -183,76 +175,103 @@
 				encoding: THREE.sRGBEncoding,
 				isPerspectiveCamera: isPerspectiveCamera,
 				groundReflector: params.isGroundReflector ? groundReflector : null,
-				selects: params.isGroundReflector ? selects : null,
-				// morphTargets: true,
-			});
-			// window.ssrPass = ssrPass
-			composer.addPass(ssrPass);
+				selects: params.isGroundReflector ? selects : null
+			} );
+
+			composer.addPass( ssrPass );
 
 			// GUI
 
 			gui = new GUI();
-			gui.add(params, 'enableSSR').name('Enable SSR');
-			gui.add(params, 'isGroundReflector').onChange(() => {
-				if (params.isGroundReflector) {
+			gui.add( params, 'enableSSR' ).name( 'Enable SSR' );
+			gui.add( params, 'isGroundReflector' ).onChange( () => {
+
+				if ( params.isGroundReflector ) {
+
 					ssrPass.groundReflector = groundReflector,
-					ssrPass.selects = selects
+					ssrPass.selects = selects;
+
 				} else {
+
 					ssrPass.groundReflector = null,
-					ssrPass.selects = null
+					ssrPass.selects = null;
+
 				}
-			})
-			gui.add(params, 'autoRotate').onChange(() => {
-				controls.enabled = !params.autoRotate
-			})
-
-			let folder = gui.addFolder( 'more settings' )
-			folder.add(ssrPass, 'isFresnel').onChange(()=>{
-				groundReflector.isFresnel=ssrPass.isFresnel
-			});
-			folder.add(ssrPass, 'isDistanceAttenuation').onChange(()=>{
-				groundReflector.isDistanceAttenuation=ssrPass.isDistanceAttenuation
-			});
-			ssrPass.maxDistance = .1
-			groundReflector.maxDistance = ssrPass.maxDistance
-			folder.add(ssrPass, 'maxDistance').min(0).max(.5).step(.001).onChange(()=>{
-				groundReflector.maxDistance=ssrPass.maxDistance
-			});
-			folder.add(params, 'isOtherMeshes').onChange(() => {
-				if (params.isOtherMeshes) {
-					otherMeshes.forEach(mesh => mesh.visible = true)
+
+			} );
+			gui.add( params, 'autoRotate' ).onChange( () => {
+
+				controls.enabled = ! params.autoRotate;
+
+			} );
+
+			const folder = gui.addFolder( 'more settings' );
+			folder.add( ssrPass, 'isFresnel' ).onChange( ()=>{
+
+				groundReflector.isFresnel = ssrPass.isFresnel;
+
+			} );
+			folder.add( ssrPass, 'isDistanceAttenuation' ).onChange( ()=>{
+
+				groundReflector.isDistanceAttenuation = ssrPass.isDistanceAttenuation;
+
+			} );
+			ssrPass.maxDistance = .1;
+			groundReflector.maxDistance = ssrPass.maxDistance;
+			folder.add( ssrPass, 'maxDistance' ).min( 0 ).max( .5 ).step( .001 ).onChange( ()=>{
+
+				groundReflector.maxDistance = ssrPass.maxDistance;
+
+			} );
+			folder.add( params, 'isOtherMeshes' ).onChange( () => {
+
+				if ( params.isOtherMeshes ) {
+
+					otherMeshes.forEach( mesh => mesh.visible = true );
+
 				} else {
-					otherMeshes.forEach(mesh => mesh.visible = false)
+
+					otherMeshes.forEach( mesh => mesh.visible = false );
+
 				}
-			})
-			folder.add(ssrPass, 'isBouncing')
-			folder.add(ssrPass, 'output', {
+
+			} );
+			folder.add( ssrPass, 'isBouncing' );
+			folder.add( ssrPass, 'output', {
 				'Default': SSRPass.OUTPUT.Default,
 				'SSR Only': SSRPass.OUTPUT.SSR,
 				'Beauty': SSRPass.OUTPUT.Beauty,
 				'Depth': SSRPass.OUTPUT.Depth,
 				'Normal': SSRPass.OUTPUT.Normal,
 				'Metalness': SSRPass.OUTPUT.Metalness,
-			}).onChange(function (value) {
-
-				ssrPass.output = parseInt(value);
-
-			});
-			ssrPass.opacity = 1
-			groundReflector.opacity=ssrPass.opacity
-			folder.add(ssrPass, 'opacity').min(0).max(1).onChange(()=>{
-				groundReflector.opacity=ssrPass.opacity
-			});
-			if (isPerspectiveCamera) {
-				ssrPass.surfDist = 0.0015
-				folder.add(ssrPass, 'surfDist').min(0).max(.005).step(.0001);
+			} ).onChange( function ( value ) {
+
+				ssrPass.output = parseInt( value );
+
+			} );
+			ssrPass.opacity = 1;
+			groundReflector.opacity = ssrPass.opacity;
+			folder.add( ssrPass, 'opacity' ).min( 0 ).max( 1 ).onChange( ()=>{
+
+				groundReflector.opacity = ssrPass.opacity;
+
+			} );
+
+			if ( isPerspectiveCamera ) {
+
+				ssrPass.surfDist = 0.0015;
+				folder.add( ssrPass, 'surfDist' ).min( 0 ).max( .005 ).step( .0001 );
+
 			} else {
-				ssrPass.surfDist = 2
-				folder.add(ssrPass, 'surfDist').min(0).max(7).step(.01);
+
+				ssrPass.surfDist = 2;
+				folder.add( ssrPass, 'surfDist' ).min( 0 ).max( 7 ).step( .01 );
+
 			}
-			folder.add(ssrPass, 'isInfiniteThick');
-			folder.add(ssrPass, 'thickTolerance').min(0).max(.05).step(.0001);
-			folder.add(ssrPass, 'isBlur');
+
+			folder.add( ssrPass, 'isInfiniteThick' );
+			folder.add( ssrPass, 'thickTolerance' ).min( 0 ).max( .05 ).step( .0001 );
+			folder.add( ssrPass, 'isBlur' );
 			// gui.close()
 
 		}
@@ -263,15 +282,15 @@
 			camera.aspect = window.innerWidth / window.innerHeight;
 			camera.updateProjectionMatrix();
 
-			renderer.setSize(window.innerWidth, window.innerHeight);
-			composer.setSize(window.innerWidth, window.innerHeight);
-			groundReflector.getRenderTarget().setSize(window.innerWidth, window.innerHeight);
+			renderer.setSize( window.innerWidth, window.innerHeight );
+			composer.setSize( window.innerWidth, window.innerHeight );
+			groundReflector.getRenderTarget().setSize( window.innerWidth, window.innerHeight );
 
 		}
 
 		function animate() {
 
-			requestAnimationFrame(animate);
+			requestAnimationFrame( animate );
 
 			stats.begin();
 			render();
@@ -281,23 +300,31 @@
 
 		function render() {
 
-			if(params.autoRotate){
+			if ( params.autoRotate ) {
+
 				const timer = Date.now() * 0.0003;
 
-				camera.position.x = Math.sin(timer) * 0.5;
+				camera.position.x = Math.sin( timer ) * 0.5;
 				camera.position.y = 0.25;
-				camera.position.z = Math.cos(timer) * 0.5;
-				camera.lookAt(0, 0.1, 0);
-			}else {
-				controls.update()
+				camera.position.z = Math.cos( timer ) * 0.5;
+				camera.lookAt( 0, 0.1, 0 );
+
+			} else {
+
+				controls.update();
+
 			}
 
-			if (params.enableSSR) {
+			if ( params.enableSSR ) {
+
 				///todo: groundReflector has full ground info, need use it to solve reflection gaps problem on objects when camera near ground.
 				///todo: the normal info where groundReflector reflected need to be changed.
 				composer.render();
+
 			} else {
-				renderer.render(scene, camera)
+
+				renderer.render( scene, camera );
+
 			}
 
 		}