OutlinePass.js 19.2 KB
Newer Older
S
spidersharma03 已提交
1 2 3 4 5 6 7 8 9
/**
 * @author spidersharma / http://eduperiment.com/
 */

THREE.OutlinePass = function ( resolution, scene, camera, selectedObjects ) {

	this.renderScene = scene;
	this.renderCamera = camera;
	this.selectedObjects = selectedObjects !== undefined ? selectedObjects : [];
10 11
	this.visibleEdgeColor = new THREE.Color( 1, 1, 1 );
	this.hiddenEdgeColor = new THREE.Color( 0.1, 0.04, 0.02 );
S
spidersharma03 已提交
12 13 14 15 16 17 18 19 20
	this.edgeGlow = 0.0;
	this.usePatternTexture = false;
	this.edgeThickness = 1.0;
	this.edgeStrength = 3.0;
	this.downSampleRatio = 2;
	this.pulsePeriod = 0;

	THREE.Pass.call( this );

21
	this.resolution = ( resolution !== undefined ) ? new THREE.Vector2( resolution.x, resolution.y ) : new THREE.Vector2( 256, 256 );
S
spidersharma03 已提交
22 23 24

	var pars = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat };

25 26
	var resx = Math.round( this.resolution.x / this.downSampleRatio );
	var resy = Math.round( this.resolution.y / this.downSampleRatio );
S
spidersharma03 已提交
27

28
	this.maskBufferMaterial = new THREE.MeshBasicMaterial( { color: 0xffffff } );
S
spidersharma03 已提交
29 30
	this.maskBufferMaterial.side = THREE.DoubleSide;
	this.renderTargetMaskBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars );
31
	this.renderTargetMaskBuffer.texture.name = "OutlinePass.mask";
S
spidersharma03 已提交
32 33 34 35 36 37 38 39 40
	this.renderTargetMaskBuffer.texture.generateMipmaps = false;

	this.depthMaterial = new THREE.MeshDepthMaterial();
	this.depthMaterial.side = THREE.DoubleSide;
	this.depthMaterial.depthPacking = THREE.RGBADepthPacking;
	this.depthMaterial.blending = THREE.NoBlending;

	this.prepareMaskMaterial = this.getPrepareMaskMaterial();
	this.prepareMaskMaterial.side = THREE.DoubleSide;
41
	this.prepareMaskMaterial.fragmentShader = replaceDepthToViewZ( this.prepareMaskMaterial.fragmentShader, this.renderCamera );
S
spidersharma03 已提交
42 43

	this.renderTargetDepthBuffer = new THREE.WebGLRenderTarget( this.resolution.x, this.resolution.y, pars );
44
	this.renderTargetDepthBuffer.texture.name = "OutlinePass.depth";
S
spidersharma03 已提交
45 46 47
	this.renderTargetDepthBuffer.texture.generateMipmaps = false;

	this.renderTargetMaskDownSampleBuffer = new THREE.WebGLRenderTarget( resx, resy, pars );
48
	this.renderTargetMaskDownSampleBuffer.texture.name = "OutlinePass.depthDownSample";
S
spidersharma03 已提交
49 50 51
	this.renderTargetMaskDownSampleBuffer.texture.generateMipmaps = false;

	this.renderTargetBlurBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars );
52
	this.renderTargetBlurBuffer1.texture.name = "OutlinePass.blur1";
S
spidersharma03 已提交
53
	this.renderTargetBlurBuffer1.texture.generateMipmaps = false;
54
	this.renderTargetBlurBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars );
55
	this.renderTargetBlurBuffer2.texture.name = "OutlinePass.blur2";
S
spidersharma03 已提交
56 57 58 59
	this.renderTargetBlurBuffer2.texture.generateMipmaps = false;

	this.edgeDetectionMaterial = this.getEdgeDetectionMaterial();
	this.renderTargetEdgeBuffer1 = new THREE.WebGLRenderTarget( resx, resy, pars );
60
	this.renderTargetEdgeBuffer1.texture.name = "OutlinePass.edge1";
S
spidersharma03 已提交
61
	this.renderTargetEdgeBuffer1.texture.generateMipmaps = false;
62
	this.renderTargetEdgeBuffer2 = new THREE.WebGLRenderTarget( Math.round( resx / 2 ), Math.round( resy / 2 ), pars );
63
	this.renderTargetEdgeBuffer2.texture.name = "OutlinePass.edge2";
S
spidersharma03 已提交
64 65 66 67 68
	this.renderTargetEdgeBuffer2.texture.generateMipmaps = false;

	var MAX_EDGE_THICKNESS = 4;
	var MAX_EDGE_GLOW = 4;

69
	this.separableBlurMaterial1 = this.getSeperableBlurMaterial( MAX_EDGE_THICKNESS );
70
	this.separableBlurMaterial1.uniforms[ "texSize" ].value.set( resx, resy );
71 72
	this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = 1;
	this.separableBlurMaterial2 = this.getSeperableBlurMaterial( MAX_EDGE_GLOW );
73
	this.separableBlurMaterial2.uniforms[ "texSize" ].value.set( Math.round( resx / 2 ), Math.round( resy / 2 ) );
74
	this.separableBlurMaterial2.uniforms[ "kernelRadius" ].value = MAX_EDGE_GLOW;
S
spidersharma03 已提交
75 76 77 78 79 80 81 82 83 84

	// Overlay material
	this.overlayMaterial = this.getOverlayMaterial();

	// copy material
	if ( THREE.CopyShader === undefined )
		console.error( "THREE.OutlinePass relies on THREE.CopyShader" );

	var copyShader = THREE.CopyShader;

85
	this.copyUniforms = THREE.UniformsUtils.clone( copyShader.uniforms );
S
spidersharma03 已提交
86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103
	this.copyUniforms[ "opacity" ].value = 1.0;

	this.materialCopy = new THREE.ShaderMaterial( {
		uniforms: this.copyUniforms,
		vertexShader: copyShader.vertexShader,
		fragmentShader: copyShader.fragmentShader,
		blending: THREE.NoBlending,
		depthTest: false,
		depthWrite: false,
		transparent: true
	} );

	this.enabled = true;
	this.needsSwap = false;

	this.oldClearColor = new THREE.Color();
	this.oldClearAlpha = 1;

104
	this.fsQuad = new THREE.Pass.FullScreenQuad( null );
S
spidersharma03 已提交
105 106 107 108

	this.tempPulseColor1 = new THREE.Color();
	this.tempPulseColor2 = new THREE.Color();
	this.textureMatrix = new THREE.Matrix4();
109

110 111 112 113 114 115 116 117
	function replaceDepthToViewZ( string, camera ) {

		var type = camera.isPerspectiveCamera ? 'perspective' : 'orthographic';

		return string.replace( /DEPTH_TO_VIEW_Z/g, type + 'DepthToViewZ' );

	}

S
spidersharma03 已提交
118 119 120 121 122 123
};

THREE.OutlinePass.prototype = Object.assign( Object.create( THREE.Pass.prototype ), {

	constructor: THREE.OutlinePass,

124 125
	dispose: function () {

S
spidersharma03 已提交
126 127 128 129 130 131 132
		this.renderTargetMaskBuffer.dispose();
		this.renderTargetDepthBuffer.dispose();
		this.renderTargetMaskDownSampleBuffer.dispose();
		this.renderTargetBlurBuffer1.dispose();
		this.renderTargetBlurBuffer2.dispose();
		this.renderTargetEdgeBuffer1.dispose();
		this.renderTargetEdgeBuffer2.dispose();
133

S
spidersharma03 已提交
134 135 136 137
	},

	setSize: function ( width, height ) {

138
		this.renderTargetMaskBuffer.setSize( width, height );
S
spidersharma03 已提交
139

140 141 142 143 144
		var resx = Math.round( width / this.downSampleRatio );
		var resy = Math.round( height / this.downSampleRatio );
		this.renderTargetMaskDownSampleBuffer.setSize( resx, resy );
		this.renderTargetBlurBuffer1.setSize( resx, resy );
		this.renderTargetEdgeBuffer1.setSize( resx, resy );
145
		this.separableBlurMaterial1.uniforms[ "texSize" ].value.set( resx, resy );
S
spidersharma03 已提交
146

147 148
		resx = Math.round( resx / 2 );
		resy = Math.round( resy / 2 );
S
spidersharma03 已提交
149

150 151 152
		this.renderTargetBlurBuffer2.setSize( resx, resy );
		this.renderTargetEdgeBuffer2.setSize( resx, resy );

153
		this.separableBlurMaterial2.uniforms[ "texSize" ].value.set( resx, resy );
S
spidersharma03 已提交
154 155 156

	},

157
	changeVisibilityOfSelectedObjects: function ( bVisible ) {
S
spidersharma03 已提交
158

159
		function gatherSelectedMeshesCallBack( object ) {
S
spidersharma03 已提交
160

M
Mugen87 已提交
161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
			if ( object.isMesh ) {

				if ( bVisible ) {

					object.visible = object.userData.oldVisible;
					delete object.userData.oldVisible;

				} else {

					object.userData.oldVisible = object.visible;
					object.visible = bVisible;

				}

			}
S
spidersharma03 已提交
176

177
		}
S
spidersharma03 已提交
178

179
		for ( var i = 0; i < this.selectedObjects.length; i ++ ) {
S
spidersharma03 已提交
180

181
			var selectedObject = this.selectedObjects[ i ];
S
spidersharma03 已提交
182
			selectedObject.traverse( gatherSelectedMeshesCallBack );
183

S
spidersharma03 已提交
184
		}
185

S
spidersharma03 已提交
186 187
	},

188
	changeVisibilityOfNonSelectedObjects: function ( bVisible ) {
S
spidersharma03 已提交
189 190 191

		var selectedMeshes = [];

192
		function gatherSelectedMeshesCallBack( object ) {
S
spidersharma03 已提交
193

M
Mugen87 已提交
194
			if ( object.isMesh ) selectedMeshes.push( object );
S
spidersharma03 已提交
195

196
		}
S
spidersharma03 已提交
197

198
		for ( var i = 0; i < this.selectedObjects.length; i ++ ) {
S
spidersharma03 已提交
199

200
			var selectedObject = this.selectedObjects[ i ];
S
spidersharma03 已提交
201
			selectedObject.traverse( gatherSelectedMeshesCallBack );
202

S
spidersharma03 已提交
203 204
		}

205
		function VisibilityChangeCallBack( object ) {
S
spidersharma03 已提交
206

M
Mugen87 已提交
207
			if ( object.isMesh || object.isLine || object.isSprite ) {
S
spidersharma03 已提交
208 209 210

				var bFound = false;

211 212 213
				for ( var i = 0; i < selectedMeshes.length; i ++ ) {

					var selectedObjectId = selectedMeshes[ i ].id;
S
spidersharma03 已提交
214

215
					if ( selectedObjectId === object.id ) {
S
spidersharma03 已提交
216 217 218

						bFound = true;
						break;
219

S
spidersharma03 已提交
220 221 222
					}

				}
223 224 225

				if ( ! bFound ) {

S
spidersharma03 已提交
226
					var visibility = object.visible;
227 228 229

					if ( ! bVisible || object.bVisible ) object.visible = bVisible;

S
spidersharma03 已提交
230
					object.bVisible = visibility;
231

S
spidersharma03 已提交
232
				}
233

S
spidersharma03 已提交
234
			}
235 236 237

		}

S
spidersharma03 已提交
238
		this.renderScene.traverse( VisibilityChangeCallBack );
239

S
spidersharma03 已提交
240 241
	},

242
	updateTextureMatrix: function () {
S
spidersharma03 已提交
243 244

		this.textureMatrix.set( 0.5, 0.0, 0.0, 0.5,
245 246 247
			0.0, 0.5, 0.0, 0.5,
			0.0, 0.0, 0.5, 0.5,
			0.0, 0.0, 0.0, 1.0 );
S
spidersharma03 已提交
248 249 250 251 252
		this.textureMatrix.multiply( this.renderCamera.projectionMatrix );
		this.textureMatrix.multiply( this.renderCamera.matrixWorldInverse );

	},

253
	render: function ( renderer, writeBuffer, readBuffer, deltaTime, maskActive ) {
S
spidersharma03 已提交
254

M
Mugen87 已提交
255
		if ( this.selectedObjects.length > 0 ) {
S
spidersharma03 已提交
256

M
Mugen87 已提交
257 258 259
			this.oldClearColor.copy( renderer.getClearColor() );
			this.oldClearAlpha = renderer.getClearAlpha();
			var oldAutoClear = renderer.autoClear;
S
spidersharma03 已提交
260

M
Mugen87 已提交
261
			renderer.autoClear = false;
S
spidersharma03 已提交
262

W
WestLangley 已提交
263
			if ( maskActive ) renderer.state.buffers.stencil.setTest( false );
S
spidersharma03 已提交
264

M
Mugen87 已提交
265
			renderer.setClearColor( 0xffffff, 1 );
S
spidersharma03 已提交
266

M
Mugen87 已提交
267 268
			// Make selected objects invisible
			this.changeVisibilityOfSelectedObjects( false );
S
spidersharma03 已提交
269

M
Mugen87 已提交
270 271
			var currentBackground = this.renderScene.background;
			this.renderScene.background = null;
A
Atrahasis 已提交
272

M
Mugen87 已提交
273 274
			// 1. Draw Non Selected objects in the depth buffer
			this.renderScene.overrideMaterial = this.depthMaterial;
275 276 277
			renderer.setRenderTarget( this.renderTargetDepthBuffer );
			renderer.clear();
			renderer.render( this.renderScene, this.renderCamera );
S
spidersharma03 已提交
278

M
Mugen87 已提交
279 280
			// Make selected objects visible
			this.changeVisibilityOfSelectedObjects( true );
S
spidersharma03 已提交
281

M
Mugen87 已提交
282 283
			// Update Texture Matrix for Depth compare
			this.updateTextureMatrix();
S
spidersharma03 已提交
284

M
Mugen87 已提交
285 286 287
			// Make non selected objects invisible, and draw only the selected objects, by comparing the depth buffer of non selected objects
			this.changeVisibilityOfNonSelectedObjects( false );
			this.renderScene.overrideMaterial = this.prepareMaskMaterial;
288
			this.prepareMaskMaterial.uniforms[ "cameraNearFar" ].value.set( this.renderCamera.near, this.renderCamera.far );
M
Mugen87 已提交
289 290
			this.prepareMaskMaterial.uniforms[ "depthTexture" ].value = this.renderTargetDepthBuffer.texture;
			this.prepareMaskMaterial.uniforms[ "textureMatrix" ].value = this.textureMatrix;
291 292 293
			renderer.setRenderTarget( this.renderTargetMaskBuffer );
			renderer.clear();
			renderer.render( this.renderScene, this.renderCamera );
M
Mugen87 已提交
294 295
			this.renderScene.overrideMaterial = null;
			this.changeVisibilityOfNonSelectedObjects( true );
S
spidersharma03 已提交
296

M
Mugen87 已提交
297
			this.renderScene.background = currentBackground;
A
Atrahasis 已提交
298

M
Mugen87 已提交
299
			// 2. Downsample to Half resolution
300
			this.fsQuad.material = this.materialCopy;
M
Mugen87 已提交
301
			this.copyUniforms[ "tDiffuse" ].value = this.renderTargetMaskBuffer.texture;
302 303
			renderer.setRenderTarget( this.renderTargetMaskDownSampleBuffer );
			renderer.clear();
304
			this.fsQuad.render( renderer );
S
spidersharma03 已提交
305

M
Mugen87 已提交
306 307
			this.tempPulseColor1.copy( this.visibleEdgeColor );
			this.tempPulseColor2.copy( this.hiddenEdgeColor );
308

M
Mugen87 已提交
309
			if ( this.pulsePeriod > 0 ) {
310

M
Mugen87 已提交
311 312 313 314 315 316 317
				var scalar = ( 1 + 0.25 ) / 2 + Math.cos( performance.now() * 0.01 / this.pulsePeriod ) * ( 1.0 - 0.25 ) / 2;
				this.tempPulseColor1.multiplyScalar( scalar );
				this.tempPulseColor2.multiplyScalar( scalar );

			}

			// 3. Apply Edge Detection Pass
318
			this.fsQuad.material = this.edgeDetectionMaterial;
M
Mugen87 已提交
319
			this.edgeDetectionMaterial.uniforms[ "maskTexture" ].value = this.renderTargetMaskDownSampleBuffer.texture;
320
			this.edgeDetectionMaterial.uniforms[ "texSize" ].value.set( this.renderTargetMaskDownSampleBuffer.width, this.renderTargetMaskDownSampleBuffer.height );
M
Mugen87 已提交
321 322
			this.edgeDetectionMaterial.uniforms[ "visibleEdgeColor" ].value = this.tempPulseColor1;
			this.edgeDetectionMaterial.uniforms[ "hiddenEdgeColor" ].value = this.tempPulseColor2;
323 324
			renderer.setRenderTarget( this.renderTargetEdgeBuffer1 );
			renderer.clear();
325
			this.fsQuad.render( renderer );
M
Mugen87 已提交
326 327

			// 4. Apply Blur on Half res
328
			this.fsQuad.material = this.separableBlurMaterial1;
M
Mugen87 已提交
329 330 331
			this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture;
			this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX;
			this.separableBlurMaterial1.uniforms[ "kernelRadius" ].value = this.edgeThickness;
332 333
			renderer.setRenderTarget( this.renderTargetBlurBuffer1 );
			renderer.clear();
334
			this.fsQuad.render( renderer );
M
Mugen87 已提交
335 336
			this.separableBlurMaterial1.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer1.texture;
			this.separableBlurMaterial1.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY;
337 338
			renderer.setRenderTarget( this.renderTargetEdgeBuffer1 );
			renderer.clear();
339
			this.fsQuad.render( renderer );
M
Mugen87 已提交
340 341

			// Apply Blur on quarter res
342
			this.fsQuad.material = this.separableBlurMaterial2;
M
Mugen87 已提交
343 344
			this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetEdgeBuffer1.texture;
			this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionX;
345 346
			renderer.setRenderTarget( this.renderTargetBlurBuffer2 );
			renderer.clear();
347
			this.fsQuad.render( renderer );
M
Mugen87 已提交
348 349
			this.separableBlurMaterial2.uniforms[ "colorTexture" ].value = this.renderTargetBlurBuffer2.texture;
			this.separableBlurMaterial2.uniforms[ "direction" ].value = THREE.OutlinePass.BlurDirectionY;
350 351
			renderer.setRenderTarget( this.renderTargetEdgeBuffer2 );
			renderer.clear();
352
			this.fsQuad.render( renderer );
M
Mugen87 已提交
353 354

			// Blend it additively over the input texture
355
			this.fsQuad.material = this.overlayMaterial;
M
Mugen87 已提交
356 357 358 359 360 361 362 363 364
			this.overlayMaterial.uniforms[ "maskTexture" ].value = this.renderTargetMaskBuffer.texture;
			this.overlayMaterial.uniforms[ "edgeTexture1" ].value = this.renderTargetEdgeBuffer1.texture;
			this.overlayMaterial.uniforms[ "edgeTexture2" ].value = this.renderTargetEdgeBuffer2.texture;
			this.overlayMaterial.uniforms[ "patternTexture" ].value = this.patternTexture;
			this.overlayMaterial.uniforms[ "edgeStrength" ].value = this.edgeStrength;
			this.overlayMaterial.uniforms[ "edgeGlow" ].value = this.edgeGlow;
			this.overlayMaterial.uniforms[ "usePatternTexture" ].value = this.usePatternTexture;


W
WestLangley 已提交
365
			if ( maskActive ) renderer.state.buffers.stencil.setTest( true );
M
Mugen87 已提交
366

367
			renderer.setRenderTarget( readBuffer );
368
			this.fsQuad.render( renderer );
M
Mugen87 已提交
369 370 371

			renderer.setClearColor( this.oldClearColor, this.oldClearAlpha );
			renderer.autoClear = oldAutoClear;
372

S
spidersharma03 已提交
373 374
		}

M
Mugen87 已提交
375 376
		if ( this.renderToScreen ) {

377
			this.fsQuad.material = this.materialCopy;
M
Mugen87 已提交
378
			this.copyUniforms[ "tDiffuse" ].value = readBuffer.texture;
379
			renderer.setRenderTarget( null );
380
			this.fsQuad.render( renderer );
M
Mugen87 已提交
381 382

		}
383

S
spidersharma03 已提交
384 385
	},

386
	getPrepareMaskMaterial: function () {
S
spidersharma03 已提交
387 388 389 390 391 392

		return new THREE.ShaderMaterial( {

			uniforms: {
				"depthTexture": { value: null },
				"cameraNearFar": { value: new THREE.Vector2( 0.5, 0.5 ) },
393
				"textureMatrix": { value: null }
S
spidersharma03 已提交
394 395
			},

396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420
			vertexShader: [
				'varying vec4 projTexCoord;',
				'varying vec4 vPosition;',
				'uniform mat4 textureMatrix;',

				'void main() {',

				'	vPosition = modelViewMatrix * vec4( position, 1.0 );',
				'	vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',
				'	projTexCoord = textureMatrix * worldPosition;',
				'	gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',

				'}'
			].join( '\n' ),

			fragmentShader: [
				'#include <packing>',
				'varying vec4 vPosition;',
				'varying vec4 projTexCoord;',
				'uniform sampler2D depthTexture;',
				'uniform vec2 cameraNearFar;',

				'void main() {',

				'	float depth = unpackRGBAToDepth(texture2DProj( depthTexture, projTexCoord ));',
421
				'	float viewZ = - DEPTH_TO_VIEW_Z( depth, cameraNearFar.x, cameraNearFar.y );',
422 423 424 425 426
				'	float depthTest = (-vPosition.z > viewZ) ? 1.0 : 0.0;',
				'	gl_FragColor = vec4(0.0, depthTest, 1.0, 1.0);',

				'}'
			].join( '\n' )
S
spidersharma03 已提交
427 428

		} );
429

S
spidersharma03 已提交
430 431
	},

432
	getEdgeDetectionMaterial: function () {
S
spidersharma03 已提交
433 434 435 436 437 438 439

		return new THREE.ShaderMaterial( {

			uniforms: {
				"maskTexture": { value: null },
				"texSize": { value: new THREE.Vector2( 0.5, 0.5 ) },
				"visibleEdgeColor": { value: new THREE.Vector3( 1.0, 1.0, 1.0 ) },
440
				"hiddenEdgeColor": { value: new THREE.Vector3( 1.0, 1.0, 1.0 ) },
S
spidersharma03 已提交
441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469
			},

			vertexShader:
				"varying vec2 vUv;\n\
				void main() {\n\
					vUv = uv;\n\
					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
				}",

			fragmentShader:
				"varying vec2 vUv;\
				uniform sampler2D maskTexture;\
				uniform vec2 texSize;\
				uniform vec3 visibleEdgeColor;\
				uniform vec3 hiddenEdgeColor;\
				\
				void main() {\n\
					vec2 invSize = 1.0 / texSize;\
					vec4 uvOffset = vec4(1.0, 0.0, 0.0, 1.0) * vec4(invSize, invSize);\
					vec4 c1 = texture2D( maskTexture, vUv + uvOffset.xy);\
					vec4 c2 = texture2D( maskTexture, vUv - uvOffset.xy);\
					vec4 c3 = texture2D( maskTexture, vUv + uvOffset.yw);\
					vec4 c4 = texture2D( maskTexture, vUv - uvOffset.yw);\
					float diff1 = (c1.r - c2.r)*0.5;\
					float diff2 = (c3.r - c4.r)*0.5;\
					float d = length( vec2(diff1, diff2) );\
					float a1 = min(c1.g, c2.g);\
					float a2 = min(c3.g, c4.g);\
					float visibilityFactor = min(a1, a2);\
470
					vec3 edgeColor = 1.0 - visibilityFactor > 0.001 ? visibleEdgeColor : hiddenEdgeColor;\
S
spidersharma03 已提交
471 472 473
					gl_FragColor = vec4(edgeColor, 1.0) * vec4(d);\
				}"
		} );
474

S
spidersharma03 已提交
475 476
	},

477
	getSeperableBlurMaterial: function ( maxRadius ) {
S
spidersharma03 已提交
478 479 480 481

		return new THREE.ShaderMaterial( {

			defines: {
482
				"MAX_RADIUS": maxRadius,
S
spidersharma03 已提交
483 484 485 486
			},

			uniforms: {
				"colorTexture": { value: null },
487
				"texSize": { value: new THREE.Vector2( 0.5, 0.5 ) },
S
spidersharma03 已提交
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512
				"direction": { value: new THREE.Vector2( 0.5, 0.5 ) },
				"kernelRadius": { value: 1.0 }
			},

			vertexShader:
				"varying vec2 vUv;\n\
				void main() {\n\
					vUv = uv;\n\
					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
				}",

			fragmentShader:
				"#include <common>\
				varying vec2 vUv;\
				uniform sampler2D colorTexture;\
				uniform vec2 texSize;\
				uniform vec2 direction;\
				uniform float kernelRadius;\
				\
				float gaussianPdf(in float x, in float sigma) {\
					return 0.39894 * exp( -0.5 * x * x/( sigma * sigma))/sigma;\
				}\
				void main() {\
					vec2 invSize = 1.0 / texSize;\
					float weightSum = gaussianPdf(0.0, kernelRadius);\
513
					vec4 diffuseSum = texture2D( colorTexture, vUv) * weightSum;\
S
spidersharma03 已提交
514 515 516 517
					vec2 delta = direction * invSize * kernelRadius/float(MAX_RADIUS);\
					vec2 uvOffset = delta;\
					for( int i = 1; i <= MAX_RADIUS; i ++ ) {\
						float w = gaussianPdf(uvOffset.x, kernelRadius);\
518 519
						vec4 sample1 = texture2D( colorTexture, vUv + uvOffset);\
						vec4 sample2 = texture2D( colorTexture, vUv - uvOffset);\
S
spidersharma03 已提交
520 521 522 523
						diffuseSum += ((sample1 + sample2) * w);\
						weightSum += (2.0 * w);\
						uvOffset += delta;\
					}\
524
					gl_FragColor = diffuseSum/weightSum;\
S
spidersharma03 已提交
525 526
				}"
		} );
527

S
spidersharma03 已提交
528 529
	},

530
	getOverlayMaterial: function () {
S
spidersharma03 已提交
531 532 533 534 535 536 537 538

		return new THREE.ShaderMaterial( {

			uniforms: {
				"maskTexture": { value: null },
				"edgeTexture1": { value: null },
				"edgeTexture2": { value: null },
				"patternTexture": { value: null },
539 540
				"edgeStrength": { value: 1.0 },
				"edgeGlow": { value: 1.0 },
541
				"usePatternTexture": { value: 0.0 }
S
spidersharma03 已提交
542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566
			},

			vertexShader:
				"varying vec2 vUv;\n\
				void main() {\n\
					vUv = uv;\n\
					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\
				}",

			fragmentShader:
				"varying vec2 vUv;\
				uniform sampler2D maskTexture;\
				uniform sampler2D edgeTexture1;\
				uniform sampler2D edgeTexture2;\
				uniform sampler2D patternTexture;\
				uniform float edgeStrength;\
				uniform float edgeGlow;\
				uniform bool usePatternTexture;\
				\
				void main() {\
					vec4 edgeValue1 = texture2D(edgeTexture1, vUv);\
					vec4 edgeValue2 = texture2D(edgeTexture2, vUv);\
					vec4 maskColor = texture2D(maskTexture, vUv);\
					vec4 patternColor = texture2D(patternTexture, 6.0 * vUv);\
					float visibilityFactor = 1.0 - maskColor.g > 0.0 ? 1.0 : 0.5;\
567 568
					vec4 edgeValue = edgeValue1 + edgeValue2 * edgeGlow;\
					vec4 finalColor = edgeStrength * maskColor.r * edgeValue;\
S
spidersharma03 已提交
569 570 571 572
					if(usePatternTexture)\
						finalColor += + visibilityFactor * (1.0 - maskColor.r) * (1.0 - patternColor.r);\
					gl_FragColor = finalColor;\
				}",
573
			blending: THREE.AdditiveBlending,
574 575
			depthTest: false,
			depthWrite: false,
576
			transparent: true
S
spidersharma03 已提交
577
		} );
578

S
spidersharma03 已提交
579 580 581 582 583 584
	}

} );

THREE.OutlinePass.BlurDirectionX = new THREE.Vector2( 1.0, 0.0 );
THREE.OutlinePass.BlurDirectionY = new THREE.Vector2( 0.0, 1.0 );