浏览代码

Removed SSRrPass. (#23569)

mrdoob 3 年之前
父节点
当前提交
f51dd8a065

+ 0 - 1
examples/files.json

@@ -252,7 +252,6 @@
 		"webgl_postprocessing_sobel",
 		"webgl_postprocessing_sobel",
 		"webgl_postprocessing_ssao",
 		"webgl_postprocessing_ssao",
 		"webgl_postprocessing_ssr",
 		"webgl_postprocessing_ssr",
-		"webgl_postprocessing_ssrr",
 		"webgl_postprocessing_taa",
 		"webgl_postprocessing_taa",
 		"webgl_postprocessing_unreal_bloom",
 		"webgl_postprocessing_unreal_bloom",
 		"webgl_postprocessing_unreal_bloom_selective"
 		"webgl_postprocessing_unreal_bloom_selective"

+ 0 - 494
examples/js/postprocessing/SSRrPass.js

@@ -1,494 +0,0 @@
-( function () {
-
-	class SSRrPass extends THREE.Pass {
-
-		constructor( {
-			renderer,
-			scene,
-			camera,
-			width,
-			height,
-			selects
-		} ) {
-
-			super();
-			this.width = width !== undefined ? width : 512;
-			this.height = height !== undefined ? height : 512;
-			this.clear = true;
-			this.renderer = renderer;
-			this.scene = scene;
-			this.camera = camera;
-			this.output = 0; // this.output = 1;
-
-			this.ior = THREE.SSRrShader.uniforms.ior.value;
-			this.maxDistance = THREE.SSRrShader.uniforms.maxDistance.value;
-			this.surfDist = THREE.SSRrShader.uniforms.surfDist.value;
-			this.tempColor = new THREE.Color();
-			this.selects = selects;
-			this._specular = THREE.SSRrShader.defines.SPECULAR;
-			Object.defineProperty( this, 'specular', {
-				get() {
-
-					return this._specular;
-
-				},
-
-				set( val ) {
-
-					if ( this._specular === val ) return;
-					this._specular = val;
-					this.ssrrMaterial.defines.SPECULAR = val;
-					this.ssrrMaterial.needsUpdate = true;
-
-				}
-
-			} );
-			this._fillHole = THREE.SSRrShader.defines.FILL_HOLE;
-			Object.defineProperty( this, 'fillHole', {
-				get() {
-
-					return this._fillHole;
-
-				},
-
-				set( val ) {
-
-					if ( this._fillHole === val ) return;
-					this._fillHole = val;
-					this.ssrrMaterial.defines.FILL_HOLE = val;
-					this.ssrrMaterial.needsUpdate = true;
-
-				}
-
-			} );
-			this._infiniteThick = THREE.SSRrShader.defines.INFINITE_THICK;
-			Object.defineProperty( this, 'infiniteThick', {
-				get() {
-
-					return this._infiniteThick;
-
-				},
-
-				set( val ) {
-
-					if ( this._infiniteThick === val ) return;
-					this._infiniteThick = val;
-					this.ssrrMaterial.defines.INFINITE_THICK = val;
-					this.ssrrMaterial.needsUpdate = true;
-
-				}
-
-			} ); // beauty render target with depth buffer
-
-			const depthTexture = new THREE.DepthTexture();
-			depthTexture.type = THREE.UnsignedShortType;
-			depthTexture.minFilter = THREE.NearestFilter;
-			depthTexture.magFilter = THREE.NearestFilter;
-			this.beautyRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
-				minFilter: THREE.NearestFilter,
-				magFilter: THREE.NearestFilter,
-				format: THREE.RGBAFormat,
-				depthTexture: depthTexture,
-				depthBuffer: true
-			} );
-			this.specularRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
-				// TODO: Can merge with refractiveRenderTarget?
-				minFilter: THREE.NearestFilter,
-				magFilter: THREE.NearestFilter,
-				format: THREE.RGBAFormat
-			} ); // normalSelects render target
-
-			const depthTextureSelects = new THREE.DepthTexture();
-			depthTextureSelects.type = THREE.UnsignedShortType;
-			depthTextureSelects.minFilter = THREE.NearestFilter;
-			depthTextureSelects.magFilter = THREE.NearestFilter;
-			this.normalSelectsRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
-				minFilter: THREE.NearestFilter,
-				magFilter: THREE.NearestFilter,
-				format: THREE.RGBAFormat,
-				type: THREE.HalfFloatType,
-				depthTexture: depthTextureSelects,
-				depthBuffer: true
-			} ); // refractive render target
-
-			this.refractiveRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
-				minFilter: THREE.NearestFilter,
-				magFilter: THREE.NearestFilter,
-				format: THREE.RGBAFormat
-			} ); // ssrr render target
-
-			this.ssrrRenderTarget = new THREE.WebGLRenderTarget( this.width, this.height, {
-				minFilter: THREE.NearestFilter,
-				magFilter: THREE.NearestFilter,
-				format: THREE.RGBAFormat
-			} ); // ssrr material
-
-			if ( THREE.SSRrShader === undefined ) {
-
-				console.error( 'THREE.SSRrPass: The pass relies on THREE.SSRrShader.' );
-
-			}
-
-			this.ssrrMaterial = new THREE.ShaderMaterial( {
-				defines: Object.assign( {}, THREE.SSRrShader.defines, {
-					MAX_STEP: Math.sqrt( this.width * this.width + this.height * this.height )
-				} ),
-				uniforms: THREE.UniformsUtils.clone( THREE.SSRrShader.uniforms ),
-				vertexShader: THREE.SSRrShader.vertexShader,
-				fragmentShader: THREE.SSRrShader.fragmentShader,
-				blending: THREE.NoBlending
-			} );
-			this.ssrrMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
-			this.ssrrMaterial.uniforms[ 'tSpecular' ].value = this.specularRenderTarget.texture;
-			this.ssrrMaterial.uniforms[ 'tNormalSelects' ].value = this.normalSelectsRenderTarget.texture;
-			this.ssrrMaterial.needsUpdate = true;
-			this.ssrrMaterial.uniforms[ 'tRefractive' ].value = this.refractiveRenderTarget.texture;
-			this.ssrrMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
-			this.ssrrMaterial.uniforms[ 'tDepthSelects' ].value = this.normalSelectsRenderTarget.depthTexture;
-			this.ssrrMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
-			this.ssrrMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
-			this.ssrrMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
-			this.ssrrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
-			this.ssrrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse ); // normal material
-
-			this.normalMaterial = new THREE.MeshNormalMaterial();
-			this.normalMaterial.blending = THREE.NoBlending; // refractiveOn material
-
-			this.refractiveOnMaterial = new THREE.MeshBasicMaterial( {
-				color: 'white'
-			} ); // refractiveOff material
-
-			this.refractiveOffMaterial = new THREE.MeshBasicMaterial( {
-				color: 'black'
-			} ); // specular material
-
-			this.specularMaterial = new THREE.MeshStandardMaterial( {
-				color: 'black',
-				metalness: 0,
-				roughness: .2
-			} ); // material for rendering the depth
-
-			this.depthRenderMaterial = new THREE.ShaderMaterial( {
-				defines: Object.assign( {}, THREE.SSRrDepthShader.defines ),
-				uniforms: THREE.UniformsUtils.clone( THREE.SSRrDepthShader.uniforms ),
-				vertexShader: THREE.SSRrDepthShader.vertexShader,
-				fragmentShader: THREE.SSRrDepthShader.fragmentShader,
-				blending: THREE.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 THREE.ShaderMaterial( {
-				uniforms: THREE.UniformsUtils.clone( THREE.CopyShader.uniforms ),
-				vertexShader: THREE.CopyShader.vertexShader,
-				fragmentShader: THREE.CopyShader.fragmentShader,
-				transparent: true,
-				depthTest: false,
-				depthWrite: false,
-				blendSrc: THREE.SrcAlphaFactor,
-				blendDst: THREE.OneMinusSrcAlphaFactor,
-				blendEquation: THREE.AddEquation,
-				blendSrcAlpha: THREE.SrcAlphaFactor,
-				blendDstAlpha: THREE.OneMinusSrcAlphaFactor,
-				blendEquationAlpha: THREE.AddEquation // premultipliedAlpha:true,
-
-			} );
-			this.fsQuad = new THREE.FullScreenQuad( null );
-			this.originalClearColor = new THREE.Color();
-
-		}
-
-		dispose() {
-
-			// dispose render targets
-			this.beautyRenderTarget.dispose();
-			this.specularRenderTarget.dispose();
-			this.normalSelectsRenderTarget.dispose();
-			this.refractiveRenderTarget.dispose();
-			this.ssrrRenderTarget.dispose(); // dispose materials
-
-			this.normalMaterial.dispose();
-			this.refractiveOnMaterial.dispose();
-			this.refractiveOffMaterial.dispose();
-			this.copyMaterial.dispose();
-			this.depthRenderMaterial.dispose(); // dipsose full screen quad
-
-			this.fsQuad.dispose();
-
-		}
-
-		render( renderer, writeBuffer
-			/*, readBuffer, deltaTime, maskActive */
-		) {
-
-			// render beauty and depth
-			renderer.setRenderTarget( this.beautyRenderTarget );
-			renderer.clear();
-			this.scene.children.forEach( child => {
-
-				if ( this.selects.includes( child ) ) {
-
-					child.visible = false;
-
-				} else {
-
-					child.visible = true;
-
-				}
-
-			} );
-			renderer.render( this.scene, this.camera );
-			renderer.setRenderTarget( this.specularRenderTarget );
-			renderer.clear();
-			this.scene.children.forEach( child => {
-
-				if ( this.selects.includes( child ) ) {
-
-					child.visible = true;
-					child._SSRrPassBackupMaterial = child.material;
-					child.material = this.specularMaterial;
-
-				} else if ( ! child.isLight ) {
-
-					child.visible = false;
-
-				}
-
-			} );
-			renderer.render( this.scene, this.camera );
-			this.scene.children.forEach( child => {
-
-				if ( this.selects.includes( child ) ) {
-
-					child.material = child._SSRrPassBackupMaterial;
-
-				}
-
-			} ); // render normalSelectss
-
-			this.scene.children.forEach( child => {
-
-				if ( this.selects.includes( child ) ) {
-
-					child.visible = true;
-
-				} else {
-
-					child.visible = false;
-
-				}
-
-			} );
-			this.renderOverride( renderer, this.normalMaterial, this.normalSelectsRenderTarget, 0, 0 );
-			this.renderRefractive( renderer, this.refractiveOnMaterial, this.refractiveRenderTarget, 0, 0 ); // render SSRr
-
-			this.ssrrMaterial.uniforms[ 'ior' ].value = this.ior;
-			this.ssrrMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance;
-			this.ssrrMaterial.uniforms[ 'surfDist' ].value = this.surfDist;
-			this.ssrrMaterial.uniforms[ 'tSpecular' ].value = this.specularRenderTarget.texture;
-			this.renderPass( renderer, this.ssrrMaterial, this.ssrrRenderTarget ); // output result to screen
-
-			switch ( this.output ) {
-
-				case SSRrPass.OUTPUT.Default:
-					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
-					this.copyMaterial.blending = THREE.NoBlending;
-					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrrRenderTarget.texture;
-					this.copyMaterial.blending = THREE.NormalBlending;
-					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-					break;
-
-				case SSRrPass.OUTPUT.SSRr:
-					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrrRenderTarget.texture;
-					this.copyMaterial.blending = THREE.NoBlending;
-					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-					break;
-
-				case SSRrPass.OUTPUT.Beauty:
-					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
-					this.copyMaterial.blending = THREE.NoBlending;
-					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-					break;
-
-				case SSRrPass.OUTPUT.Depth:
-					this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
-					this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
-					break;
-
-				case SSRrPass.OUTPUT.DepthSelects:
-					this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.normalSelectsRenderTarget.depthTexture;
-					this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
-					break;
-
-				case SSRrPass.OUTPUT.NormalSelects:
-					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalSelectsRenderTarget.texture;
-					this.copyMaterial.blending = THREE.NoBlending;
-					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-					break;
-
-				case SSRrPass.OUTPUT.Refractive:
-					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.refractiveRenderTarget.texture;
-					this.copyMaterial.blending = THREE.NoBlending;
-					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-					break;
-
-				case SSRrPass.OUTPUT.Specular:
-					this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.specularRenderTarget.texture;
-					this.copyMaterial.blending = THREE.NoBlending;
-					this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-					break;
-
-				default:
-					console.warn( 'THREE.SSRrPass: Unknown output type.' );
-
-			}
-
-		}
-
-		renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
-
-			// save original state
-			this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
-			const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
-			const originalAutoClear = renderer.autoClear;
-			renderer.setRenderTarget( renderTarget ); // setup pass state
-
-			renderer.autoClear = false;
-
-			if ( clearColor !== undefined && clearColor !== null ) {
-
-				renderer.setClearColor( clearColor );
-				renderer.setClearAlpha( clearAlpha || 0.0 );
-				renderer.clear();
-
-			}
-
-			this.fsQuad.material = passMaterial;
-			this.fsQuad.render( renderer ); // restore original state
-
-			renderer.autoClear = originalAutoClear;
-			renderer.setClearColor( this.originalClearColor );
-			renderer.setClearAlpha( originalClearAlpha );
-
-		}
-
-		renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
-
-			this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
-			const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
-			const originalAutoClear = renderer.autoClear;
-			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; // restore original state
-
-			renderer.autoClear = originalAutoClear;
-			renderer.setClearColor( this.originalClearColor );
-			renderer.setClearAlpha( originalClearAlpha );
-
-		}
-
-		renderRefractive( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
-
-			this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
-			const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
-			const originalAutoClear = renderer.autoClear;
-			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.children.forEach( child => {
-
-				child.visible = true;
-
-			} );
-			this.scene.traverse( child => {
-
-				child._SSRrPassBackupMaterial = child.material;
-
-				if ( this.selects.includes( child ) ) {
-
-					child.material = this.refractiveOnMaterial;
-
-				} else {
-
-					child.material = this.refractiveOffMaterial;
-
-				}
-
-			} );
-			this.scene._SSRrPassBackupBackground = this.scene.background;
-			this.scene.background = null;
-			this.scene._SSRrPassBackupFog = this.scene.fog;
-			this.scene.fog = null;
-			renderer.render( this.scene, this.camera );
-			this.scene.fog = this.scene._SSRrPassBackupFog;
-			this.scene.background = this.scene._SSRrPassBackupBackground;
-			this.scene.traverse( child => {
-
-				child.material = child._SSRrPassBackupMaterial;
-
-			} ); // restore original state
-
-			renderer.autoClear = originalAutoClear;
-			renderer.setClearColor( this.originalClearColor );
-			renderer.setClearAlpha( originalClearAlpha );
-
-		}
-
-		setSize( width, height ) {
-
-			this.width = width;
-			this.height = height;
-			this.ssrrMaterial.defines.MAX_STEP = Math.sqrt( width * width + height * height );
-			this.ssrrMaterial.needsUpdate = true;
-			this.beautyRenderTarget.setSize( width, height );
-			this.specularRenderTarget.setSize( width, height );
-			this.ssrrRenderTarget.setSize( width, height );
-			this.normalSelectsRenderTarget.setSize( width, height );
-			this.refractiveRenderTarget.setSize( width, height );
-			this.ssrrMaterial.uniforms[ 'resolution' ].value.set( width, height );
-			this.ssrrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
-			this.ssrrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
-
-		}
-
-	}
-
-	SSRrPass.OUTPUT = {
-		'Default': 0,
-		'SSRr': 1,
-		'Beauty': 3,
-		'Depth': 4,
-		'DepthSelects': 9,
-		'NormalSelects': 5,
-		'Refractive': 7,
-		'Specular': 8
-	};
-
-	THREE.SSRrPass = SSRrPass;
-
-} )();

+ 0 - 336
examples/js/shaders/SSRrShader.js

@@ -1,336 +0,0 @@
-( function () {
-
-	const SSRrShader = {
-		defines: {
-			MAX_STEP: 0,
-			PERSPECTIVE_CAMERA: true,
-			SPECULAR: true,
-			FILL_HOLE: true,
-			INFINITE_THICK: false
-		},
-		uniforms: {
-			'tDiffuse': {
-				value: null
-			},
-			'tSpecular': {
-				value: null
-			},
-			'tNormalSelects': {
-				value: null
-			},
-			'tRefractive': {
-				value: null
-			},
-			'tDepth': {
-				value: null
-			},
-			'tDepthSelects': {
-				value: null
-			},
-			'cameraNear': {
-				value: null
-			},
-			'cameraFar': {
-				value: null
-			},
-			'resolution': {
-				value: new THREE.Vector2()
-			},
-			'cameraProjectionMatrix': {
-				value: new THREE.Matrix4()
-			},
-			'cameraInverseProjectionMatrix': {
-				value: new THREE.Matrix4()
-			},
-			'ior': {
-				value: 1.03
-			},
-			'cameraRange': {
-				value: 0
-			},
-			'maxDistance': {
-				value: 180
-			},
-			'surfDist': {
-				value: .007
-			}
-		},
-		vertexShader:
-  /* glsl */
-  `
-
-		varying vec2 vUv;
-
-		void main() {
-
-			vUv = uv;
-
-			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-		}
-
-	`,
-		fragmentShader:
-  /* glsl */
-  `
-		// precision highp float;
-		precision highp sampler2D;
-		varying vec2 vUv;
-		uniform sampler2D tDepth;
-		uniform sampler2D tDepthSelects;
-		uniform sampler2D tNormalSelects;
-		uniform sampler2D tRefractive;
-		uniform sampler2D tDiffuse;
-		uniform sampler2D tSpecular;
-		uniform float cameraRange;
-		uniform vec2 resolution;
-		uniform float cameraNear;
-		uniform float cameraFar;
-		uniform float ior;
-		uniform mat4 cameraProjectionMatrix;
-		uniform mat4 cameraInverseProjectionMatrix;
-		uniform float maxDistance;
-		uniform float surfDist;
-		#include <packing>
-		float pointToLineDistance(vec3 x0, vec3 x1, vec3 x2) {
-			//x0: point, x1: linePointA, x2: linePointB
-			//https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
-			return length(cross(x0-x1,x0-x2))/length(x2-x1);
-		}
-		float pointPlaneDistance(vec3 point,vec3 planePoint,vec3 planeNormal){
-			// https://mathworld.wolfram.com/Point-PlaneDistance.html
-			//// https://en.wikipedia.org/wiki/Plane_(geometry)
-			//// http://paulbourke.net/geometry/pointlineplane/
-			float a=planeNormal.x,b=planeNormal.y,c=planeNormal.z;
-			float x0=point.x,y0=point.y,z0=point.z;
-			float x=planePoint.x,y=planePoint.y,z=planePoint.z;
-			float d=-(a*x+b*y+c*z);
-			float distance=(a*x0+b*y0+c*z0+d)/sqrt(a*a+b*b+c*c);
-			return distance;
-		}
-		float getDepth( const in vec2 uv ) {
-			return texture2D( tDepth, uv ).x;
-		}
-		float getDepthSelects( const in vec2 uv ) {
-			return texture2D( tDepthSelects, uv ).x;
-		}
-		float getViewZ( const in float depth ) {
-			#ifdef PERSPECTIVE_CAMERA
-				return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
-			#else
-				return orthographicDepthToViewZ( depth, cameraNear, cameraFar );
-			#endif
-		}
-		vec3 getViewPosition( const in vec2 uv, const in float depth/*clip space*/, const in float clipW ) {
-			vec4 clipPosition = vec4( ( vec3( uv, depth ) - 0.5 ) * 2.0, 1.0 );//ndc
-			clipPosition *= clipW; //clip
-			return ( cameraInverseProjectionMatrix * clipPosition ).xyz;//view
-		}
-		vec3 getViewNormalSelects( const in vec2 uv ) {
-			return unpackRGBToNormal( texture2D( tNormalSelects, uv ).xyz );
-		}
-		vec2 viewPositionToXY(vec3 viewPosition){
-			vec2 xy;
-			vec4 clip=cameraProjectionMatrix*vec4(viewPosition,1);
-			xy=clip.xy;//clip
-			float clipW=clip.w;
-			xy/=clipW;//NDC
-			xy=(xy+1.)/2.;//uv
-			xy*=resolution;//screen
-			return xy;
-		}
-		void setResultColor(vec2 uv){
-			vec4 refractColor=texture2D(tDiffuse,uv);
-			#ifdef SPECULAR
-				vec4 specularColor=texture2D(tSpecular,vUv);
-				gl_FragColor.xyz=mix(refractColor.xyz,vec3(1),specularColor.r);
-				// gl_FragColor.xyz=refractColor.xyz*(1.+specularColor.r*3.);
-			#else
-				gl_FragColor.xyz=refractColor.xyz;
-			#endif
-			gl_FragColor.a=1.;
-
-		}
-		void main(){
-			if(ior==1.) return; // Adding this line may have better performance, but more importantly, it can avoid display errors at the very edges of the model when IOR is equal to 1.
-
-			float refractive=texture2D(tRefractive,vUv).r;
-			if(refractive<=0.) return;
-
-			// gl_FragColor=vec4(0,0,.5,1);return;
-			vec3 viewNormalSelects=getViewNormalSelects( vUv );
-			// gl_FragColor=vec4(viewNormalSelects,1);return;
-
-			// if(viewNormalSelects.x<=0.&&viewNormalSelects.y<=0.&&viewNormalSelects.z<=0.) return;
-
-			float depth = getDepthSelects( vUv );
-			float viewZ = getViewZ( depth );
-			// if(-viewZ>=cameraFar) return;
-
-			float clipW = cameraProjectionMatrix[2][3] * viewZ+cameraProjectionMatrix[3][3];
-			vec3 viewPosition=getViewPosition( vUv, depth, clipW );
-
-			vec2 d0=gl_FragCoord.xy;
-			vec2 d1;
-
-			#ifdef PERSPECTIVE_CAMERA
-				vec3 viewIncidentDir=normalize(viewPosition);
-			#else
-				vec3 viewIncidentDir=vec3(0,0,-1);
-			#endif
-
-			vec3 viewRefractDir=refract(viewIncidentDir,viewNormalSelects,1./ior);
-			// https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/refract.xhtml
-
-			vec3 d1viewPosition=viewPosition+viewRefractDir*maxDistance;
-			#ifdef PERSPECTIVE_CAMERA
-				if(d1viewPosition.z>-cameraNear){
-					//https://tutorial.math.lamar.edu/Classes/CalcIII/EqnsOfLines.aspx
-					float t=(-cameraNear-viewPosition.z)/viewRefractDir.z;
-					d1viewPosition=viewPosition+viewRefractDir*t;
-				}
-			#endif
-			d1=viewPositionToXY(d1viewPosition);
-
-			float totalLen=length(d1-d0);
-			float xLen=d1.x-d0.x;
-			float yLen=d1.y-d0.y;
-			float totalStep=max(abs(xLen),abs(yLen));
-			float xSpan=xLen/totalStep;
-			float ySpan=yLen/totalStep;
-			#ifdef FILL_HOLE
-				bool isRough=false;
-				vec2 uvRough;
-			#endif
-			for(float i=0.;i<float(MAX_STEP);i++){
-				if(i>=totalStep) break;
-				vec2 xy=vec2(d0.x+i*xSpan,d0.y+i*ySpan);
-				if(xy.x<0.||xy.x>resolution.x||xy.y<0.||xy.y>resolution.y) break;
-				float s=length(xy-d0)/totalLen;
-				vec2 uv=xy/resolution;
-
-				float d = getDepth(uv);
-				float vZ = getViewZ( d );
-				float cW = cameraProjectionMatrix[2][3] * vZ+cameraProjectionMatrix[3][3];
-				vec3 vP=getViewPosition( uv, d, cW );
-
-				#ifdef PERSPECTIVE_CAMERA
-					// https://comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf
-					float recipVPZ=1./viewPosition.z;
-					float viewRefractRayZ=1./(recipVPZ+s*(1./d1viewPosition.z-recipVPZ));
-					float sD=surfDist*cW;
-				#else
-					float viewRefractRayZ=viewPosition.z+s*(d1viewPosition.z-viewPosition.z);
-					float sD=surfDist;
-				#endif
-
-				#ifdef FILL_HOLE // TODO: May can improve performance by check if INFINITE_THICK too.
-					if(viewRefractRayZ<=vZ){
-						if(!isRough){
-							uvRough=uv;
-							isRough=true;
-						}
-					}
-				#endif
-
-				bool hit;
-				#ifdef INFINITE_THICK
-					hit=viewRefractRayZ<=vZ;
-				#else
-					if(viewRefractRayZ-sD>vZ) continue;
-					float away=pointToLineDistance(vP,viewPosition,d1viewPosition);
-					hit=away<=sD;
-				#endif
-				if(hit){
-					setResultColor(uv);
-					return;
-				}
-			}
-
-			#ifdef FILL_HOLE
-				if(isRough){
-					setResultColor(uvRough);
-				}
-				// else{
-				// 	gl_FragColor=texture2D(tDiffuse,vUv);//For afterward add color mix feature.
-				// }
-			#else
-				// gl_FragColor=texture2D(tDiffuse,vUv);//For afterward add color mix feature.
-			#endif
-		}
-	`
-	};
-	const SSRrDepthShader = {
-		defines: {
-			'PERSPECTIVE_CAMERA': 1
-		},
-		uniforms: {
-			'tDepth': {
-				value: null
-			},
-			'cameraNear': {
-				value: null
-			},
-			'cameraFar': {
-				value: null
-			}
-		},
-		vertexShader:
-  /* glsl */
-  `
-
-		varying vec2 vUv;
-
-		void main() {
-
-			vUv = uv;
-			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-		}
-
-	`,
-		fragmentShader:
-  /* glsl */
-  `
-
-		uniform sampler2D tDepth;
-
-		uniform float cameraNear;
-		uniform float cameraFar;
-
-		varying vec2 vUv;
-
-		#include <packing>
-
-		float getLinearDepth( const in vec2 uv ) {
-
-			#if PERSPECTIVE_CAMERA == 1
-
-				float fragCoordZ = texture2D( tDepth, uv ).x;
-				float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
-				return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
-
-			#else
-
-				return texture2D( tDepth, uv ).x;
-
-			#endif
-
-		}
-
-		void main() {
-
-			float depth = getLinearDepth( vUv );
-			float d = 1.0 - depth;
-			// d=(d-.999)*1000.;
-			gl_FragColor = vec4( vec3( d ), 1.0 );
-
-		}
-
-	`
-	};
-
-	THREE.SSRrDepthShader = SSRrDepthShader;
-	THREE.SSRrShader = SSRrShader;
-
-} )();

+ 0 - 579
examples/jsm/postprocessing/SSRrPass.js

@@ -1,579 +0,0 @@
-import {
-	AddEquation,
-	Color,
-	NormalBlending,
-	DepthTexture,
-	SrcAlphaFactor,
-	OneMinusSrcAlphaFactor,
-	MeshNormalMaterial,
-	MeshBasicMaterial,
-	NearestFilter,
-	NoBlending,
-	RGBAFormat,
-	ShaderMaterial,
-	UniformsUtils,
-	UnsignedShortType,
-	WebGLRenderTarget,
-	HalfFloatType,
-	MeshStandardMaterial
-} from 'three';
-import { Pass, FullScreenQuad } from './Pass.js';
-import { SSRrShader } from '../shaders/SSRrShader.js';
-import { SSRrDepthShader } from '../shaders/SSRrShader.js';
-import { CopyShader } from '../shaders/CopyShader.js';
-
-class SSRrPass extends Pass {
-
-	constructor( { renderer, scene, camera, width, height, selects } ) {
-
-		super();
-
-		this.width = ( width !== undefined ) ? width : 512;
-		this.height = ( height !== undefined ) ? height : 512;
-
-		this.clear = true;
-
-		this.renderer = renderer;
-		this.scene = scene;
-		this.camera = camera;
-
-		this.output = 0;
-		// this.output = 1;
-
-		this.ior = SSRrShader.uniforms.ior.value;
-		this.maxDistance = SSRrShader.uniforms.maxDistance.value;
-		this.surfDist = SSRrShader.uniforms.surfDist.value;
-
-		this.tempColor = new Color();
-
-		this.selects = selects;
-
-		this._specular = SSRrShader.defines.SPECULAR;
-		Object.defineProperty( this, 'specular', {
-			get() {
-
-				return this._specular;
-
-			},
-			set( val ) {
-
-				if ( this._specular === val ) return;
-				this._specular = val;
-				this.ssrrMaterial.defines.SPECULAR = val;
-				this.ssrrMaterial.needsUpdate = true;
-
-			}
-		} );
-
-		this._fillHole = SSRrShader.defines.FILL_HOLE;
-		Object.defineProperty( this, 'fillHole', {
-			get() {
-
-				return this._fillHole;
-
-			},
-			set( val ) {
-
-				if ( this._fillHole === val ) return;
-				this._fillHole = val;
-				this.ssrrMaterial.defines.FILL_HOLE = val;
-				this.ssrrMaterial.needsUpdate = true;
-
-			}
-		} );
-
-		this._infiniteThick = SSRrShader.defines.INFINITE_THICK;
-		Object.defineProperty( this, 'infiniteThick', {
-			get() {
-
-				return this._infiniteThick;
-
-			},
-			set( val ) {
-
-				if ( this._infiniteThick === val ) return;
-				this._infiniteThick = val;
-				this.ssrrMaterial.defines.INFINITE_THICK = val;
-				this.ssrrMaterial.needsUpdate = true;
-
-			}
-		} );
-
-		// beauty render target with depth buffer
-
-		const depthTexture = new DepthTexture();
-		depthTexture.type = UnsignedShortType;
-		depthTexture.minFilter = NearestFilter;
-		depthTexture.magFilter = NearestFilter;
-
-		this.beautyRenderTarget = new WebGLRenderTarget( this.width, this.height, {
-			minFilter: NearestFilter,
-			magFilter: NearestFilter,
-			format: RGBAFormat,
-			depthTexture: depthTexture,
-			depthBuffer: true
-		} );
-
-		this.specularRenderTarget = new WebGLRenderTarget( this.width, this.height, { // TODO: Can merge with refractiveRenderTarget?
-			minFilter: NearestFilter,
-			magFilter: NearestFilter,
-			format: RGBAFormat,
-		} );
-
-		// normalSelects render target
-
-		const depthTextureSelects = new DepthTexture();
-		depthTextureSelects.type = UnsignedShortType;
-		depthTextureSelects.minFilter = NearestFilter;
-		depthTextureSelects.magFilter = NearestFilter;
-
-		this.normalSelectsRenderTarget = new WebGLRenderTarget( this.width, this.height, {
-			minFilter: NearestFilter,
-			magFilter: NearestFilter,
-			format: RGBAFormat,
-			type: HalfFloatType,
-			depthTexture: depthTextureSelects,
-			depthBuffer: true
-		} );
-
-		// refractive render target
-
-		this.refractiveRenderTarget = new WebGLRenderTarget( this.width, this.height, {
-			minFilter: NearestFilter,
-			magFilter: NearestFilter,
-			format: RGBAFormat
-		} );
-
-		// ssrr render target
-
-		this.ssrrRenderTarget = new WebGLRenderTarget( this.width, this.height, {
-			minFilter: NearestFilter,
-			magFilter: NearestFilter,
-			format: RGBAFormat
-		} );
-
-		// ssrr material
-
-		if ( SSRrShader === undefined ) {
-
-			console.error( 'THREE.SSRrPass: The pass relies on SSRrShader.' );
-
-		}
-
-		this.ssrrMaterial = new ShaderMaterial( {
-			defines: Object.assign( {}, SSRrShader.defines, {
-				MAX_STEP: Math.sqrt( this.width * this.width + this.height * this.height )
-			} ),
-			uniforms: UniformsUtils.clone( SSRrShader.uniforms ),
-			vertexShader: SSRrShader.vertexShader,
-			fragmentShader: SSRrShader.fragmentShader,
-			blending: NoBlending
-		} );
-
-		this.ssrrMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
-		this.ssrrMaterial.uniforms[ 'tSpecular' ].value = this.specularRenderTarget.texture;
-		this.ssrrMaterial.uniforms[ 'tNormalSelects' ].value = this.normalSelectsRenderTarget.texture;
-		this.ssrrMaterial.needsUpdate = true;
-		this.ssrrMaterial.uniforms[ 'tRefractive' ].value = this.refractiveRenderTarget.texture;
-		this.ssrrMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
-		this.ssrrMaterial.uniforms[ 'tDepthSelects' ].value = this.normalSelectsRenderTarget.depthTexture;
-		this.ssrrMaterial.uniforms[ 'cameraNear' ].value = this.camera.near;
-		this.ssrrMaterial.uniforms[ 'cameraFar' ].value = this.camera.far;
-		this.ssrrMaterial.uniforms[ 'resolution' ].value.set( this.width, this.height );
-		this.ssrrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
-		this.ssrrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
-
-		// normal material
-
-		this.normalMaterial = new MeshNormalMaterial();
-		this.normalMaterial.blending = NoBlending;
-
-		// refractiveOn material
-
-		this.refractiveOnMaterial = new MeshBasicMaterial( {
-			color: 'white'
-		} );
-
-		// refractiveOff material
-
-		this.refractiveOffMaterial = new MeshBasicMaterial( {
-			color: 'black'
-		} );
-
-		// specular material
-		this.specularMaterial = new MeshStandardMaterial( {
-			color: 'black',
-			metalness: 0,
-			roughness: .2,
-		} );
-
-		// material for rendering the depth
-
-		this.depthRenderMaterial = new ShaderMaterial( {
-			defines: Object.assign( {}, SSRrDepthShader.defines ),
-			uniforms: UniformsUtils.clone( SSRrDepthShader.uniforms ),
-			vertexShader: SSRrDepthShader.vertexShader,
-			fragmentShader: SSRrDepthShader.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 FullScreenQuad( null );
-
-		this.originalClearColor = new Color();
-
-	}
-
-	dispose() {
-
-		// dispose render targets
-
-		this.beautyRenderTarget.dispose();
-		this.specularRenderTarget.dispose();
-		this.normalSelectsRenderTarget.dispose();
-		this.refractiveRenderTarget.dispose();
-		this.ssrrRenderTarget.dispose();
-
-		// dispose materials
-
-		this.normalMaterial.dispose();
-		this.refractiveOnMaterial.dispose();
-		this.refractiveOffMaterial.dispose();
-		this.copyMaterial.dispose();
-		this.depthRenderMaterial.dispose();
-
-		// dipsose full screen quad
-
-		this.fsQuad.dispose();
-
-	}
-
-	render( renderer, writeBuffer /*, readBuffer, deltaTime, maskActive */ ) {
-
-		// render beauty and depth
-
-		renderer.setRenderTarget( this.beautyRenderTarget );
-		renderer.clear();
-		this.scene.children.forEach( child => {
-
-			if ( this.selects.includes( child ) ) {
-
-				child.visible = false;
-
-			} else {
-
-				child.visible = true;
-
-			}
-
-		} );
-		renderer.render( this.scene, this.camera );
-
-		renderer.setRenderTarget( this.specularRenderTarget );
-		renderer.clear();
-		this.scene.children.forEach( child => {
-
-			if ( this.selects.includes( child ) ) {
-
-				child.visible = true;
-				child._SSRrPassBackupMaterial = child.material;
-				child.material = this.specularMaterial;
-
-			} else if ( ! child.isLight ) {
-
-				child.visible = false;
-
-			}
-
-		} );
-		renderer.render( this.scene, this.camera );
-		this.scene.children.forEach( child => {
-
-			if ( this.selects.includes( child ) ) {
-
-				child.material = child._SSRrPassBackupMaterial;
-
-			}
-
-		} );
-
-
-		// render normalSelectss
-
-		this.scene.children.forEach( child => {
-
-			if ( this.selects.includes( child ) ) {
-
-				child.visible = true;
-
-			} else {
-
-				child.visible = false;
-
-			}
-
-		} );
-
-		this.renderOverride( renderer, this.normalMaterial, this.normalSelectsRenderTarget, 0, 0 );
-
-		this.renderRefractive( renderer, this.refractiveOnMaterial, this.refractiveRenderTarget, 0, 0 );
-
-		// render SSRr
-
-		this.ssrrMaterial.uniforms[ 'ior' ].value = this.ior;
-		this.ssrrMaterial.uniforms[ 'maxDistance' ].value = this.maxDistance;
-		this.ssrrMaterial.uniforms[ 'surfDist' ].value = this.surfDist;
-		this.ssrrMaterial.uniforms[ 'tSpecular' ].value = this.specularRenderTarget.texture;
-		this.renderPass( renderer, this.ssrrMaterial, this.ssrrRenderTarget );
-
-		// output result to screen
-
-		switch ( this.output ) {
-
-			case SSRrPass.OUTPUT.Default:
-
-
-				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.ssrrRenderTarget.texture;
-				this.copyMaterial.blending = NormalBlending;
-				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-
-				break;
-			case SSRrPass.OUTPUT.SSRr:
-
-				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.ssrrRenderTarget.texture;
-				this.copyMaterial.blending = NoBlending;
-				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-
-				break;
-
-			case SSRrPass.OUTPUT.Beauty:
-
-				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.beautyRenderTarget.texture;
-				this.copyMaterial.blending = NoBlending;
-				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-
-				break;
-
-			case SSRrPass.OUTPUT.Depth:
-
-				this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.beautyRenderTarget.depthTexture;
-				this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
-
-				break;
-
-			case SSRrPass.OUTPUT.DepthSelects:
-
-				this.depthRenderMaterial.uniforms[ 'tDepth' ].value = this.normalSelectsRenderTarget.depthTexture;
-				this.renderPass( renderer, this.depthRenderMaterial, this.renderToScreen ? null : writeBuffer );
-
-				break;
-
-			case SSRrPass.OUTPUT.NormalSelects:
-
-				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.normalSelectsRenderTarget.texture;
-				this.copyMaterial.blending = NoBlending;
-				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-
-				break;
-
-			case SSRrPass.OUTPUT.Refractive:
-
-				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.refractiveRenderTarget.texture;
-				this.copyMaterial.blending = NoBlending;
-				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-
-				break;
-
-			case SSRrPass.OUTPUT.Specular:
-
-				this.copyMaterial.uniforms[ 'tDiffuse' ].value = this.specularRenderTarget.texture;
-				this.copyMaterial.blending = NoBlending;
-				this.renderPass( renderer, this.copyMaterial, this.renderToScreen ? null : writeBuffer );
-
-				break;
-
-			default:
-				console.warn( 'THREE.SSRrPass: Unknown output type.' );
-
-		}
-
-	}
-
-	renderPass( renderer, passMaterial, renderTarget, clearColor, clearAlpha ) {
-
-		// save original state
-		this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
-		const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
-		const originalAutoClear = renderer.autoClear;
-
-		renderer.setRenderTarget( renderTarget );
-
-		// setup pass state
-		renderer.autoClear = false;
-		if ( ( clearColor !== undefined ) && ( clearColor !== null ) ) {
-
-			renderer.setClearColor( clearColor );
-			renderer.setClearAlpha( clearAlpha || 0.0 );
-			renderer.clear();
-
-		}
-
-		this.fsQuad.material = passMaterial;
-		this.fsQuad.render( renderer );
-
-		// restore original state
-		renderer.autoClear = originalAutoClear;
-		renderer.setClearColor( this.originalClearColor );
-		renderer.setClearAlpha( originalClearAlpha );
-
-	}
-
-	renderOverride( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
-
-		this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
-		const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
-		const originalAutoClear = renderer.autoClear;
-
-		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;
-
-		// restore original state
-
-		renderer.autoClear = originalAutoClear;
-		renderer.setClearColor( this.originalClearColor );
-		renderer.setClearAlpha( originalClearAlpha );
-
-	}
-
-	renderRefractive( renderer, overrideMaterial, renderTarget, clearColor, clearAlpha ) {
-
-		this.originalClearColor.copy( renderer.getClearColor( this.tempColor ) );
-		const originalClearAlpha = renderer.getClearAlpha( this.tempColor );
-		const originalAutoClear = renderer.autoClear;
-
-		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.children.forEach( child => {
-
-			child.visible = true;
-
-		} );
-		this.scene.traverse( child => {
-
-			child._SSRrPassBackupMaterial = child.material;
-			if ( this.selects.includes( child ) ) {
-
-				child.material = this.refractiveOnMaterial;
-
-			} else {
-
-				child.material = this.refractiveOffMaterial;
-
-			}
-
-		} );
-		this.scene._SSRrPassBackupBackground = this.scene.background;
-		this.scene.background = null;
-		this.scene._SSRrPassBackupFog = this.scene.fog;
-		this.scene.fog = null;
-		renderer.render( this.scene, this.camera );
-		this.scene.fog = this.scene._SSRrPassBackupFog;
-		this.scene.background = this.scene._SSRrPassBackupBackground;
-		this.scene.traverse( child => {
-
-			child.material = child._SSRrPassBackupMaterial;
-
-		} );
-
-		// restore original state
-
-		renderer.autoClear = originalAutoClear;
-		renderer.setClearColor( this.originalClearColor );
-		renderer.setClearAlpha( originalClearAlpha );
-
-	}
-
-	setSize( width, height ) {
-
-		this.width = width;
-		this.height = height;
-
-		this.ssrrMaterial.defines.MAX_STEP = Math.sqrt( width * width + height * height );
-		this.ssrrMaterial.needsUpdate = true;
-		this.beautyRenderTarget.setSize( width, height );
-		this.specularRenderTarget.setSize( width, height );
-		this.ssrrRenderTarget.setSize( width, height );
-		this.normalSelectsRenderTarget.setSize( width, height );
-		this.refractiveRenderTarget.setSize( width, height );
-
-		this.ssrrMaterial.uniforms[ 'resolution' ].value.set( width, height );
-		this.ssrrMaterial.uniforms[ 'cameraProjectionMatrix' ].value.copy( this.camera.projectionMatrix );
-		this.ssrrMaterial.uniforms[ 'cameraInverseProjectionMatrix' ].value.copy( this.camera.projectionMatrixInverse );
-
-	}
-
-}
-
-SSRrPass.OUTPUT = {
-	'Default': 0,
-	'SSRr': 1,
-	'Beauty': 3,
-	'Depth': 4,
-	'DepthSelects': 9,
-	'NormalSelects': 5,
-	'Refractive': 7,
-	'Specular': 8,
-};
-
-export { SSRrPass };

+ 0 - 307
examples/jsm/shaders/SSRrShader.js

@@ -1,307 +0,0 @@
-import {
-	Matrix4,
-	Vector2
-} from 'three';
-
-const SSRrShader = {
-
-	defines: {
-		MAX_STEP: 0,
-		PERSPECTIVE_CAMERA: true,
-		SPECULAR: true,
-		FILL_HOLE: true,
-		INFINITE_THICK: false,
-	},
-
-	uniforms: {
-
-		'tDiffuse': { value: null },
-		'tSpecular': { value: null },
-		'tNormalSelects': { value: null },
-		'tRefractive': { value: null },
-		'tDepth': { value: null },
-		'tDepthSelects': { value: null },
-		'cameraNear': { value: null },
-		'cameraFar': { value: null },
-		'resolution': { value: new Vector2() },
-		'cameraProjectionMatrix': { value: new Matrix4() },
-		'cameraInverseProjectionMatrix': { value: new Matrix4() },
-		'ior': { value: 1.03 },
-		'cameraRange': { value: 0 },
-		'maxDistance': { value: 180 },
-		'surfDist': { value: .007 },
-
-	},
-
-	vertexShader: /* glsl */`
-
-		varying vec2 vUv;
-
-		void main() {
-
-			vUv = uv;
-
-			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-		}
-
-	`,
-
-	fragmentShader: /* glsl */`
-		// precision highp float;
-		precision highp sampler2D;
-		varying vec2 vUv;
-		uniform sampler2D tDepth;
-		uniform sampler2D tDepthSelects;
-		uniform sampler2D tNormalSelects;
-		uniform sampler2D tRefractive;
-		uniform sampler2D tDiffuse;
-		uniform sampler2D tSpecular;
-		uniform float cameraRange;
-		uniform vec2 resolution;
-		uniform float cameraNear;
-		uniform float cameraFar;
-		uniform float ior;
-		uniform mat4 cameraProjectionMatrix;
-		uniform mat4 cameraInverseProjectionMatrix;
-		uniform float maxDistance;
-		uniform float surfDist;
-		#include <packing>
-		float pointToLineDistance(vec3 x0, vec3 x1, vec3 x2) {
-			//x0: point, x1: linePointA, x2: linePointB
-			//https://mathworld.wolfram.com/Point-LineDistance3-Dimensional.html
-			return length(cross(x0-x1,x0-x2))/length(x2-x1);
-		}
-		float pointPlaneDistance(vec3 point,vec3 planePoint,vec3 planeNormal){
-			// https://mathworld.wolfram.com/Point-PlaneDistance.html
-			//// https://en.wikipedia.org/wiki/Plane_(geometry)
-			//// http://paulbourke.net/geometry/pointlineplane/
-			float a=planeNormal.x,b=planeNormal.y,c=planeNormal.z;
-			float x0=point.x,y0=point.y,z0=point.z;
-			float x=planePoint.x,y=planePoint.y,z=planePoint.z;
-			float d=-(a*x+b*y+c*z);
-			float distance=(a*x0+b*y0+c*z0+d)/sqrt(a*a+b*b+c*c);
-			return distance;
-		}
-		float getDepth( const in vec2 uv ) {
-			return texture2D( tDepth, uv ).x;
-		}
-		float getDepthSelects( const in vec2 uv ) {
-			return texture2D( tDepthSelects, uv ).x;
-		}
-		float getViewZ( const in float depth ) {
-			#ifdef PERSPECTIVE_CAMERA
-				return perspectiveDepthToViewZ( depth, cameraNear, cameraFar );
-			#else
-				return orthographicDepthToViewZ( depth, cameraNear, cameraFar );
-			#endif
-		}
-		vec3 getViewPosition( const in vec2 uv, const in float depth/*clip space*/, const in float clipW ) {
-			vec4 clipPosition = vec4( ( vec3( uv, depth ) - 0.5 ) * 2.0, 1.0 );//ndc
-			clipPosition *= clipW; //clip
-			return ( cameraInverseProjectionMatrix * clipPosition ).xyz;//view
-		}
-		vec3 getViewNormalSelects( const in vec2 uv ) {
-			return unpackRGBToNormal( texture2D( tNormalSelects, uv ).xyz );
-		}
-		vec2 viewPositionToXY(vec3 viewPosition){
-			vec2 xy;
-			vec4 clip=cameraProjectionMatrix*vec4(viewPosition,1);
-			xy=clip.xy;//clip
-			float clipW=clip.w;
-			xy/=clipW;//NDC
-			xy=(xy+1.)/2.;//uv
-			xy*=resolution;//screen
-			return xy;
-		}
-		void setResultColor(vec2 uv){
-			vec4 refractColor=texture2D(tDiffuse,uv);
-			#ifdef SPECULAR
-				vec4 specularColor=texture2D(tSpecular,vUv);
-				gl_FragColor.xyz=mix(refractColor.xyz,vec3(1),specularColor.r);
-				// gl_FragColor.xyz=refractColor.xyz*(1.+specularColor.r*3.);
-			#else
-				gl_FragColor.xyz=refractColor.xyz;
-			#endif
-			gl_FragColor.a=1.;
-
-		}
-		void main(){
-			if(ior==1.) return; // Adding this line may have better performance, but more importantly, it can avoid display errors at the very edges of the model when IOR is equal to 1.
-
-			float refractive=texture2D(tRefractive,vUv).r;
-			if(refractive<=0.) return;
-
-			// gl_FragColor=vec4(0,0,.5,1);return;
-			vec3 viewNormalSelects=getViewNormalSelects( vUv );
-			// gl_FragColor=vec4(viewNormalSelects,1);return;
-
-			// if(viewNormalSelects.x<=0.&&viewNormalSelects.y<=0.&&viewNormalSelects.z<=0.) return;
-
-			float depth = getDepthSelects( vUv );
-			float viewZ = getViewZ( depth );
-			// if(-viewZ>=cameraFar) return;
-
-			float clipW = cameraProjectionMatrix[2][3] * viewZ+cameraProjectionMatrix[3][3];
-			vec3 viewPosition=getViewPosition( vUv, depth, clipW );
-
-			vec2 d0=gl_FragCoord.xy;
-			vec2 d1;
-
-			#ifdef PERSPECTIVE_CAMERA
-				vec3 viewIncidentDir=normalize(viewPosition);
-			#else
-				vec3 viewIncidentDir=vec3(0,0,-1);
-			#endif
-
-			vec3 viewRefractDir=refract(viewIncidentDir,viewNormalSelects,1./ior);
-			// https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/refract.xhtml
-
-			vec3 d1viewPosition=viewPosition+viewRefractDir*maxDistance;
-			#ifdef PERSPECTIVE_CAMERA
-				if(d1viewPosition.z>-cameraNear){
-					//https://tutorial.math.lamar.edu/Classes/CalcIII/EqnsOfLines.aspx
-					float t=(-cameraNear-viewPosition.z)/viewRefractDir.z;
-					d1viewPosition=viewPosition+viewRefractDir*t;
-				}
-			#endif
-			d1=viewPositionToXY(d1viewPosition);
-
-			float totalLen=length(d1-d0);
-			float xLen=d1.x-d0.x;
-			float yLen=d1.y-d0.y;
-			float totalStep=max(abs(xLen),abs(yLen));
-			float xSpan=xLen/totalStep;
-			float ySpan=yLen/totalStep;
-			#ifdef FILL_HOLE
-				bool isRough=false;
-				vec2 uvRough;
-			#endif
-			for(float i=0.;i<float(MAX_STEP);i++){
-				if(i>=totalStep) break;
-				vec2 xy=vec2(d0.x+i*xSpan,d0.y+i*ySpan);
-				if(xy.x<0.||xy.x>resolution.x||xy.y<0.||xy.y>resolution.y) break;
-				float s=length(xy-d0)/totalLen;
-				vec2 uv=xy/resolution;
-
-				float d = getDepth(uv);
-				float vZ = getViewZ( d );
-				float cW = cameraProjectionMatrix[2][3] * vZ+cameraProjectionMatrix[3][3];
-				vec3 vP=getViewPosition( uv, d, cW );
-
-				#ifdef PERSPECTIVE_CAMERA
-					// https://comp.nus.edu.sg/~lowkl/publications/lowk_persp_interp_techrep.pdf
-					float recipVPZ=1./viewPosition.z;
-					float viewRefractRayZ=1./(recipVPZ+s*(1./d1viewPosition.z-recipVPZ));
-					float sD=surfDist*cW;
-				#else
-					float viewRefractRayZ=viewPosition.z+s*(d1viewPosition.z-viewPosition.z);
-					float sD=surfDist;
-				#endif
-
-				#ifdef FILL_HOLE // TODO: May can improve performance by check if INFINITE_THICK too.
-					if(viewRefractRayZ<=vZ){
-						if(!isRough){
-							uvRough=uv;
-							isRough=true;
-						}
-					}
-				#endif
-
-				bool hit;
-				#ifdef INFINITE_THICK
-					hit=viewRefractRayZ<=vZ;
-				#else
-					if(viewRefractRayZ-sD>vZ) continue;
-					float away=pointToLineDistance(vP,viewPosition,d1viewPosition);
-					hit=away<=sD;
-				#endif
-				if(hit){
-					setResultColor(uv);
-					return;
-				}
-			}
-
-			#ifdef FILL_HOLE
-				if(isRough){
-					setResultColor(uvRough);
-				}
-				// else{
-				// 	gl_FragColor=texture2D(tDiffuse,vUv);//For afterward add color mix feature.
-				// }
-			#else
-				// gl_FragColor=texture2D(tDiffuse,vUv);//For afterward add color mix feature.
-			#endif
-		}
-	`
-
-};
-
-const SSRrDepthShader = {
-
-	defines: {
-		'PERSPECTIVE_CAMERA': 1
-	},
-
-	uniforms: {
-
-		'tDepth': { value: null },
-		'cameraNear': { value: null },
-		'cameraFar': { value: null },
-
-	},
-
-	vertexShader: /* glsl */`
-
-		varying vec2 vUv;
-
-		void main() {
-
-			vUv = uv;
-			gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-
-		}
-
-	`,
-
-	fragmentShader: /* glsl */`
-
-		uniform sampler2D tDepth;
-
-		uniform float cameraNear;
-		uniform float cameraFar;
-
-		varying vec2 vUv;
-
-		#include <packing>
-
-		float getLinearDepth( const in vec2 uv ) {
-
-			#if PERSPECTIVE_CAMERA == 1
-
-				float fragCoordZ = texture2D( tDepth, uv ).x;
-				float viewZ = perspectiveDepthToViewZ( fragCoordZ, cameraNear, cameraFar );
-				return viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
-
-			#else
-
-				return texture2D( tDepth, uv ).x;
-
-			#endif
-
-		}
-
-		void main() {
-
-			float depth = getLinearDepth( vUv );
-			float d = 1.0 - depth;
-			// d=(d-.999)*1000.;
-			gl_FragColor = vec4( vec3( d ), 1.0 );
-
-		}
-
-	`
-
-};
-
-export { SSRrShader, SSRrDepthShader };

二进制
examples/screenshots/webgl_postprocessing_ssrr.jpg


+ 0 - 329
examples/webgl_postprocessing_ssrr.html

@@ -1,329 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-
-<head>
-
-	<head>
-		<title>three.js webgl - postprocessing - Screen Space Refraction</title>
-		<meta charset="utf-8">
-		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
-		<link type="text/css" rel="stylesheet" href="main.css">
-	</head>
-
-<body>
-	<div id="container"></div>
-	<div id="info">
-		<a href="https://threejs.org" target="_blank" rel="noopener">three.js</a> -
-		SSRrPass demo by <a href="https://github.com/gonnavis" target="_blank">Vis</a>.<br />
-		click object to toggle transparent<br/>
-	</div>
-
-	<!-- Import maps polyfill -->
-	<!-- Remove this when import maps will be widely supported -->
-	<script async src="https://unpkg.com/[email protected]/dist/es-module-shims.js"></script>
-
-	<script type="importmap">
-		{
-			"imports": {
-				"three": "../build/three.module.js"
-			}
-		}
-	</script>
-
-	<script type="module">
-		import * as THREE from 'three';
-
-		import Stats from './jsm/libs/stats.module.js';
-
-		import { OrbitControls } from './jsm/controls/OrbitControls.js';
-
-		import { GUI } from './jsm/libs/lil-gui.module.min.js';
-		import { EffectComposer } from './jsm/postprocessing/EffectComposer.js';
-		import { SSRrPass } from './jsm/postprocessing/SSRrPass.js';
-		import { ShaderPass } from './jsm/postprocessing/ShaderPass.js';
-		import { GammaCorrectionShader } from './jsm/shaders/GammaCorrectionShader.js';
-
-		import { DRACOLoader } from './jsm/loaders/DRACOLoader.js';
-
-		const params = {
-			enableSSRr: true,
-			autoRotate: true,
-		};
-		let composer;
-		let ssrrPass;
-		let gui;
-		let stats;
-		let controls;
-		let camera, scene, renderer;
-		const objects = [];
-		const selects = [];
-		const raycaster = new THREE.Raycaster();
-		const mouseDown = new THREE.Vector2();
-		const mouse = new THREE.Vector2();
-
-		const container = document.querySelector( '#container' );
-
-		// Configure and create Draco decoder.
-		const dracoLoader = new DRACOLoader();
-		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 );
-
-			scene = new THREE.Scene();
-			scene.background = new THREE.Color( 0x443333 );
-			scene.fog = new THREE.Fog( 0x443333, 1, 4 );
-
-			// Ground
-			const map = new THREE.TextureLoader().load( './textures/uv_grid_opengl.jpg' );
-			map.wrapS = THREE.RepeatWrapping;
-			map.wrapT = THREE.RepeatWrapping;
-			map.repeat.set( 20, 20 );
-			const plane = new THREE.Mesh(
-				new THREE.PlaneGeometry( 8, 8 ),
-				new THREE.MeshPhongMaterial( {
-					color: 0x999999,
-					specular: 0x101010,
-					map,
-				} )
-			);
-			plane.rotation.x = - Math.PI / 2;
-			plane.position.y = - 0.0001;
-			// plane.receiveShadow = true;
-			scene.add( plane );
-			plane.name = 'plane';
-
-			// Lights
-			const hemiLight = new THREE.HemisphereLight( 0x443333, 0x111122 );
-			hemiLight.name = 'hemiLight';
-			scene.add( hemiLight );
-
-			const spotLight = new THREE.SpotLight();
-			spotLight.name = 'spotLight';
-			spotLight.angle = Math.PI / 16;
-			spotLight.penumbra = 0.5;
-			// spotLight.castShadow = true;
-			spotLight.position.set( - 1, 1, 1 );
-			scene.add( spotLight );
-
-			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.position.y = - 0.0365;
-				mesh.name = 'bunny';
-				scene.add( mesh );
-				objects.push( mesh );
-				selects.push( mesh );
-
-				// Release decoder resources.
-				dracoLoader.dispose();
-
-			} );
-
-			let geometry, material, mesh;
-
-			geometry = new THREE.BoxGeometry( .05, .05, .05 );
-			material = new THREE.MeshStandardMaterial( { color: 'green' } );
-			mesh = new THREE.Mesh( geometry, material );
-			mesh.position.set( - .12, .025, .015 );
-			mesh.name = 'box';
-			scene.add( mesh );
-			objects.push( mesh );
-			selects.push( mesh );
-
-			geometry = new THREE.IcosahedronGeometry( .025, 4 );
-			material = new THREE.MeshStandardMaterial( { color: 'cyan' } );
-			mesh = new THREE.Mesh( geometry, material );
-			mesh.position.set( - .05, .025, .08 );
-			mesh.name = 'sphere';
-			scene.add( mesh );
-			objects.push( mesh );
-			// selects.push( mesh );
-
-			geometry = new THREE.ConeGeometry( .025, .05, 64 );
-			material = new THREE.MeshStandardMaterial( { color: 'yellow' } );
-			mesh = new THREE.Mesh( geometry, material );
-			mesh.position.set( - .05, .025, - .055 );
-			mesh.name = 'cone';
-			scene.add( mesh );
-			objects.push( mesh );
-			// selects.push( mesh );
-
-			// renderer
-			renderer = new THREE.WebGLRenderer( { antialias: false } );
-			renderer.setSize( window.innerWidth, window.innerHeight );
-			renderer.autoClear = false;
-			container.appendChild( renderer.domElement );
-
-			//
-
-			controls = new OrbitControls( camera, renderer.domElement );
-			controls.enableDamping = true;
-			controls.target.set( 0, 0.0635, 0 );
-			controls.update();
-			controls.enabled = ! params.autoRotate;
-
-			// STATS
-
-			stats = new Stats();
-			container.appendChild( stats.dom );
-
-			window.addEventListener( 'resize', onWindowResize );
-			window.addEventListener( 'pointerdown', onPointerDown );
-			window.addEventListener( 'pointerup', onPointerUp );
-
-			// composer
-
-			composer = new EffectComposer( renderer );
-			ssrrPass = new SSRrPass( {
-				renderer,
-				scene,
-				camera,
-				width: innerWidth,
-				height: innerHeight,
-				selects: selects
-			} );
-
-			composer.addPass( ssrrPass );
-			composer.addPass( new ShaderPass( GammaCorrectionShader ) );
-
-			// GUI
-
-			gui = new GUI();
-			gui.add( params, 'enableSSRr' ).name( 'Enable SSRr' );
-			ssrrPass.ior = 1.1;
-			gui.add( ssrrPass, 'ior' ).name( 'IOR' ).min( 1 ).max( 1.5 ).step( .0001 );
-			gui.add( ssrrPass, 'fillHole' );
-			gui.add( params, 'autoRotate' ).onChange( () => {
-
-				controls.enabled = ! params.autoRotate;
-
-			} );
-
-			const folder = gui.addFolder( 'more settings' );
-			folder.add( ssrrPass, 'specular' );
-			folder.add( ssrrPass.specularMaterial, 'metalness' ).min( 0 ).max( 1 ).step( .01 );
-			folder.add( ssrrPass.specularMaterial, 'roughness' ).min( 0 ).max( 1 ).step( .01 );
-			folder.add( ssrrPass, 'output', {
-				'Default': SSRrPass.OUTPUT.Default,
-				'SSRr Only': SSRrPass.OUTPUT.SSRr,
-				'Beauty': SSRrPass.OUTPUT.Beauty,
-				'Depth': SSRrPass.OUTPUT.Depth,
-				'DepthSelects': SSRrPass.OUTPUT.DepthSelects,
-				'NormalSelects': SSRrPass.OUTPUT.NormalSelects,
-				'Refractive': SSRrPass.OUTPUT.Refractive,
-				'Specular': SSRrPass.OUTPUT.Specular,
-			} ).onChange( function ( value ) {
-
-				ssrrPass.output = parseInt( value );
-
-			} );
-			ssrrPass.surfDist = 0.0015;
-			folder.add( ssrrPass, 'surfDist' ).min( 0 ).max( .005 ).step( .0001 );
-			ssrrPass.maxDistance = 50;
-			folder.add( ssrrPass, 'maxDistance' ).min( 0 ).max( 100 ).step( .001 );
-			folder.add( ssrrPass, 'infiniteThick' );
-			// folder.open()
-			// gui.close()
-
-		}
-
-		function onPointerDown( event ) {
-
-			mouseDown.x = ( event.clientX / window.innerWidth ) * 2 - 1;
-			mouseDown.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
-
-		}
-
-		function onPointerUp( event ) {
-
-			// calculate mouse position in normalized device coordinates
-			// (-1 to +1) for both components
-
-			mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
-			mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
-
-			if ( mouseDown.sub( mouse ).length() > 0 ) return;
-
-
-			raycaster.setFromCamera( mouse, camera );
-			const intersect = raycaster.intersectObjects( objects, false )[ 0 ];
-
-			if ( intersect ) {
-
-				const index = selects.indexOf( intersect.object );
-				if ( index >= 0 ) {
-
-					selects.splice( index, 1 );
-
-				} else {
-
-					selects.push( intersect.object );
-
-				}
-
-			}
-
-		}
-
-		function onWindowResize() {
-
-			camera.aspect = window.innerWidth / window.innerHeight;
-			camera.updateProjectionMatrix();
-
-			renderer.setSize( window.innerWidth, window.innerHeight );
-			composer.setSize( window.innerWidth, window.innerHeight );
-
-		}
-
-		function animate() {
-
-			requestAnimationFrame( animate );
-
-			stats.begin();
-			render();
-			stats.end();
-
-		}
-
-		function render() {
-
-			if ( params.autoRotate ) {
-
-				const timer = Date.now() * 0.0003;
-
-				camera.position.x = Math.sin( timer ) * 0.5;
-				camera.position.y = 0.2135;
-				camera.position.z = Math.cos( timer ) * 0.5;
-				camera.lookAt( 0, 0.0635, 0 );
-
-			} else {
-
-				controls.update();
-
-			}
-
-			if ( params.enableSSRr ) {
-
-				composer.render();
-
-			} else {
-
-				renderer.render( scene, camera );
-
-			}
-
-		}
-	</script>
-</body>
-
-</html>