CanvasRenderer.js 20.5 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4
/**
 * @author mr.doob / http://mrdoob.com/
 */

M
Mr.doob 已提交
5
THREE.CanvasRenderer = function () {
6

M
Mr.doob 已提交
7 8
	var _renderList = null,
	_projector = new THREE.Projector(),
9

M
Mr.doob 已提交
10
	_canvas = document.createElement( 'canvas' ),
11
	_canvasWidth, _canvasHeight, _canvasWidthHalf, _canvasHeightHalf,
12
	_context = _canvas.getContext( '2d' ),
M
Mr.doob 已提交
13 14

	_contextGlobalAlpha = 1,
15
	_contextGlobalCompositeOperation = 0,
16 17
	_contextStrokeStyle = null,
	_contextFillStyle = null,
M
Mr.doob 已提交
18 19
	_contextLineWidth = 1,

M
Mr.doob 已提交
20 21
	_min = Math.min, _max = Math.max,

22
	_v1, _v2, _v3,
M
Mr.doob 已提交
23 24
	_v1x, _v1y, _v2x, _v2y, _v3x, _v3y,

25 26 27 28 29
	_color = new THREE.Color(),
	_color1 = new THREE.Color(),
	_color2 = new THREE.Color(),
	_color3 = new THREE.Color(),
	_color4 = new THREE.Color(),
30 31
	_2near, _farPlusNear, _farMinusNear,

M
Mr.doob 已提交
32
	_bitmap,
33
	_uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y,
M
Mr.doob 已提交
34

35
	_clipRect = new THREE.Rectangle(),
36
	_clearRect = new THREE.Rectangle(),
37
	_bboxRect = new THREE.Rectangle(),
38

39
	_enableLighting = false,
40 41 42 43
	_light = new THREE.Color(),
	_ambientLight = new THREE.Color(),
	_directionalLights = new THREE.Color(),
	_pointLights = new THREE.Color(),
M
Mr.doob 已提交
44

45
	_pi2 = Math.PI * 2,
M
Mr.doob 已提交
46
	_vector3 = new THREE.Vector3(), // Needed for PointLight
47

48
	_pixelMap, _pixelMapContext, _pixelMapImage, _pixelMapData,
49
	_gradientMap, _gradientMapContext, _gradientMapQuality = 16;
50 51 52 53 54 55 56 57 58 59

	_pixelMap = document.createElement( 'canvas' );
	_pixelMap.width = _pixelMap.height = 2;

	_pixelMapContext = _pixelMap.getContext( '2d' );
	_pixelMapContext.fillStyle = 'rgba(0,0,0,1)';
	_pixelMapContext.fillRect( 0, 0, 2, 2 );

	_pixelMapImage = _pixelMapContext.getImageData( 0, 0, 2, 2 );
	_pixelMapData = _pixelMapImage.data;
60

61 62
	_gradientMap = document.createElement( 'canvas' );
	_gradientMap.width = _gradientMap.height = _gradientMapQuality;
63

64 65 66
	_gradientMapContext = _gradientMap.getContext( '2d' );
	_gradientMapContext.translate( - _gradientMapQuality / 2, - _gradientMapQuality / 2 );
	_gradientMapContext.scale( _gradientMapQuality, _gradientMapQuality );
67

68
	_gradientMapQuality --; // Fix UVs
69

70
	this.domElement = _canvas;
M
Mr.doob 已提交
71
	this.autoClear = true;
M
Mr.doob 已提交
72

73
	this.setSize = function ( width, height ) {
M
Mr.doob 已提交
74

M
Mr.doob 已提交
75 76 77 78
		_canvasWidth = width;
		_canvasHeight = height;
		_canvasWidthHalf = _canvasWidth / 2;
		_canvasHeightHalf = _canvasHeight / 2;
M
Mr.doob 已提交
79

80 81
		_canvas.width = _canvasWidth;
		_canvas.height = _canvasHeight;
M
Mr.doob 已提交
82

83
		_clipRect.set( - _canvasWidthHalf, - _canvasHeightHalf, _canvasWidthHalf, _canvasHeightHalf );
M
Mr.doob 已提交
84

M
Mr.doob 已提交
85
	};
86

M
Mr.doob 已提交
87 88
	this.clear = function () {

89 90 91 92 93 94 95 96
		if ( !_clearRect.isEmpty() ) {

			_clearRect.inflate( 1 );
			_clearRect.minSelf( _clipRect );

			_context.clearRect( _clearRect.getX(), _clearRect.getY(), _clearRect.getWidth(), _clearRect.getHeight() );

			_clearRect.empty();
M
Mr.doob 已提交
97

98
		}
M
Mr.doob 已提交
99 100
	};

101
	this.render = function ( scene, camera ) {
M
Mr.doob 已提交
102

103
		var e, el, element, m, ml, fm, fml, material;
104

M
Mr.doob 已提交
105
		_context.setTransform( 1, 0, 0, - 1, _canvasWidthHalf, _canvasHeightHalf );
106

M
Mr.doob 已提交
107
		this.autoClear && this.clear();
108

M
Mr.doob 已提交
109 110
		_renderList = _projector.projectScene( scene, camera );

111 112
		/* DEBUG
		_context.fillStyle = 'rgba(0, 255, 255, 0.5)';
113
		_context.fillRect( _clipRect.getX(), _clipRect.getY(), _clipRect.getWidth(), _clipRect.getHeight() );
114
		*/
M
Mr.doob 已提交
115

116 117 118 119 120 121 122
		_enableLighting = scene.lights.length > 0;

		if ( _enableLighting ) {

			 calculateLights( scene );

		}
M
Mr.doob 已提交
123

M
Mr.doob 已提交
124 125 126
		for ( e = 0, el = _renderList.length; e < el; e++ ) {

			element = _renderList[ e ];
M
Mr.doob 已提交
127

128
			_bboxRect.empty();
M
Mr.doob 已提交
129

130
			if ( element instanceof THREE.RenderableParticle ) {
131

132 133
				_v1 = element;
				_v1.x *= _canvasWidthHalf; _v1.y *= _canvasHeightHalf;
M
Mr.doob 已提交
134

135 136
				for ( m = 0, ml = element.material.length; m < ml; m++ ) {

M
Mr.doob 已提交
137
					renderParticle( _v1, element, element.material[ m ], scene );
138 139 140

				}

141
			} else if ( element instanceof THREE.RenderableLine ) {
M
Mr.doob 已提交
142

143 144 145 146
				_v1 = element.v1; _v2 = element.v2;

				_v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
				_v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
M
Mr.doob 已提交
147

148 149
				_bboxRect.addPoint( _v1.positionScreen.x, _v1.positionScreen.y );
				_bboxRect.addPoint( _v2.positionScreen.x, _v2.positionScreen.y );
150

M
Mr.doob 已提交
151
				if ( _clipRect.instersects( _bboxRect ) ) {
M
Mr.doob 已提交
152

M
Mr.doob 已提交
153
					m = 0; ml = element.material.length;
154

M
Mr.doob 已提交
155
					while ( m < ml ) {
156

M
Mr.doob 已提交
157
						renderLine( _v1, _v2, element, element.material[ m ++ ], scene );
158

M
Mr.doob 已提交
159
					}
160 161

				}
M
Mr.doob 已提交
162

M
Mr.doob 已提交
163

164
			} else if ( element instanceof THREE.RenderableFace3 ) {
165

166 167 168 169 170
				_v1 = element.v1; _v2 = element.v2; _v3 = element.v3;

				_v1.positionScreen.x *= _canvasWidthHalf; _v1.positionScreen.y *= _canvasHeightHalf;
				_v2.positionScreen.x *= _canvasWidthHalf; _v2.positionScreen.y *= _canvasHeightHalf;
				_v3.positionScreen.x *= _canvasWidthHalf; _v3.positionScreen.y *= _canvasHeightHalf;
M
Mr.doob 已提交
171

172
				if ( element.overdraw ) {
M
Mr.doob 已提交
173

174 175 176
					expand( _v1.positionScreen, _v2.positionScreen );
					expand( _v2.positionScreen, _v3.positionScreen );
					expand( _v3.positionScreen, _v1.positionScreen );
M
Mr.doob 已提交
177

178
				}
M
Mr.doob 已提交
179

180 181 182
				_bboxRect.add3Points( _v1.positionScreen.x, _v1.positionScreen.y,
						      _v2.positionScreen.x, _v2.positionScreen.y,
						      _v3.positionScreen.x, _v3.positionScreen.y );
M
Mr.doob 已提交
183

M
Mr.doob 已提交
184
				if ( _clipRect.instersects( _bboxRect ) ) {
M
Mr.doob 已提交
185

M
Mr.doob 已提交
186
					m = 0; ml = element.meshMaterial.length;
M
Mr.doob 已提交
187

M
Mr.doob 已提交
188
					while ( m < ml ) {
189

M
Mr.doob 已提交
190
						material = element.meshMaterial[ m ++ ];
191

M
Mr.doob 已提交
192
						if ( material instanceof THREE.MeshFaceMaterial ) {
193

M
Mr.doob 已提交
194
							fm = 0; fml = element.faceMaterial.length;
195

M
Mr.doob 已提交
196
							while ( fm < fml ) {
197

M
Mr.doob 已提交
198 199
								material = element.faceMaterial[ fm ++ ];
								material && renderFace3( _v1, _v2, _v3, element, material, scene );
200

M
Mr.doob 已提交
201
							}
202

M
Mr.doob 已提交
203
							continue;
204 205

						}
M
Mr.doob 已提交
206

M
Mr.doob 已提交
207
						renderFace3( _v1, _v2, _v3, element, material, scene );
208 209 210 211

					}

				}
M
Mr.doob 已提交
212

213
			}
214

M
Mr.doob 已提交
215
			/*
216 217 218 219
			_context.lineWidth = 1;
			_context.strokeStyle = 'rgba( 0, 255, 0, 0.5 )';
			_context.strokeRect( _bboxRect.getX(), _bboxRect.getY(), _bboxRect.getWidth(), _bboxRect.getHeight() );
			*/
M
Mr.doob 已提交
220

221
			_clearRect.addRectangle( _bboxRect );
M
Mr.doob 已提交
222

223

224
		}
M
Mr.doob 已提交
225

226 227 228 229 230
		/* DEBUG
		_context.lineWidth = 1;
		_context.strokeStyle = 'rgba( 255, 0, 0, 0.5 )';
		_context.strokeRect( _clearRect.getX(), _clearRect.getY(), _clearRect.getWidth(), _clearRect.getHeight() );
		*/
231

232 233
		_context.setTransform( 1, 0, 0, 1, 0, 0 );

234 235 236
		//

		function calculateLights( scene ) {
M
Mr.doob 已提交
237

238 239
			var l, ll, light, lightColor,
			lights = scene.lights;
M
Mr.doob 已提交
240

241 242 243
			_ambientLight.setRGB( 0, 0, 0 );
			_directionalLights.setRGB( 0, 0, 0 );
			_pointLights.setRGB( 0, 0, 0 );
M
Mr.doob 已提交
244

245
			for ( l = 0, ll = lights.length; l < ll; l ++ ) {
M
Mr.doob 已提交
246

247 248
				light = lights[ l ];
				lightColor = light.color;
M
Mr.doob 已提交
249

250
				if ( light instanceof THREE.AmbientLight ) {
M
Mr.doob 已提交
251

252 253 254
					_ambientLight.r += lightColor.r;
					_ambientLight.g += lightColor.g;
					_ambientLight.b += lightColor.b;
M
Mr.doob 已提交
255

256
				} else if ( light instanceof THREE.DirectionalLight ) {
M
Mr.doob 已提交
257

258 259 260
					_directionalLights.r += lightColor.r;
					_directionalLights.g += lightColor.g;
					_directionalLights.b += lightColor.b;
261

262
				} else if ( light instanceof THREE.PointLight ) {
263

264 265 266
					_pointLights.r += lightColor.r;
					_pointLights.g += lightColor.g;
					_pointLights.b += lightColor.b;
267

268
				}
269 270 271 272 273

			}

		}

274
		function calculateLight( scene, position, normal, color ) {
275

276 277
			var l, ll, light, lightColor, lightIntensity,
			amount, lights = scene.lights;
M
Mr.doob 已提交
278

279
			for ( l = 0, ll = lights.length; l < ll; l ++ ) {
M
Mr.doob 已提交
280

281 282 283
				light = lights[ l ];
				lightColor = light.color;
				lightIntensity = light.intensity;
M
Mr.doob 已提交
284

285
				if ( light instanceof THREE.DirectionalLight ) {
M
Mr.doob 已提交
286

287
					amount = normal.dot( light.position ) * lightIntensity;
M
Mr.doob 已提交
288

289
					if ( amount > 0 ) {
M
Mr.doob 已提交
290

291 292 293
						color.r += lightColor.r * amount;
						color.g += lightColor.g * amount;
						color.b += lightColor.b * amount;
M
Mr.doob 已提交
294

295
					}
M
Mr.doob 已提交
296

297
				} else if ( light instanceof THREE.PointLight ) {
M
Mr.doob 已提交
298

299 300
					_vector3.sub( light.position, position );
					_vector3.normalize();
M
Mr.doob 已提交
301

302
					amount = normal.dot( _vector3 ) * lightIntensity;
M
Mr.doob 已提交
303

304
					if ( amount > 0 ) {
M
Mr.doob 已提交
305

306 307 308
						color.r += lightColor.r * amount;
						color.g += lightColor.g * amount;
						color.b += lightColor.b * amount;
M
Mr.doob 已提交
309

310
					}
M
Mr.doob 已提交
311 312 313 314 315 316 317

				}

			}

		}

318
		function renderParticle ( v1, element, material, scene ) {
M
Mr.doob 已提交
319

320
			if ( material.opacity == 0 ) return;
M
Mr.doob 已提交
321

322 323
			setOpacity( material.opacity );
			setBlending( material.blending );
324

325 326
			var width, height, scaleX, scaleY,
			bitmap, bitmapWidth, bitmapHeight;
327

328
			if ( material instanceof THREE.ParticleBasicMaterial ) {
M
Mr.doob 已提交
329

330
				if ( material.map ) {
331

332 333 334
					bitmap = material.map;
					bitmapWidth = bitmap.width >> 1;
					bitmapHeight = bitmap.height >> 1;
335

336 337
					scaleX = element.scale.x * _canvasWidthHalf;
					scaleY = element.scale.y * _canvasHeightHalf;
338

339 340
					width = scaleX * bitmapWidth;
					height = scaleY * bitmapHeight;
341

342
					// TODO: Rotations break this...
343

344
					_bboxRect.set( v1.x - width, v1.y - height, v1.x  + width, v1.y + height );
345

346
					if ( !_clipRect.instersects( _bboxRect ) ) {
347

348
						return;
349

350
					}
351

352 353 354 355 356
					_context.save();
					_context.translate( v1.x, v1.y );
					_context.rotate( - element.rotation );
					_context.scale( scaleX, - scaleY );
					_context.translate( - bitmapWidth, - bitmapHeight );
357

358
					_context.drawImage( bitmap, 0, 0 );
359

360
					_context.restore();
361

362
				}
363

364 365 366 367 368 369 370 371 372 373
				/* DEBUG
				_context.beginPath();
				_context.moveTo( v1.x - 10, v1.y );
				_context.lineTo( v1.x + 10, v1.y );
				_context.moveTo( v1.x, v1.y - 10 );
				_context.lineTo( v1.x, v1.y + 10 );
				_context.closePath();
				_context.strokeStyle = 'rgb(255,255,0)';
				_context.stroke();
				*/
374

375
			} else if ( material instanceof THREE.ParticleCircleMaterial ) {
376

377
				if ( _enableLighting ) {
378

379 380 381
					_light.r = _ambientLight.r + _directionalLights.r + _pointLights.r;
					_light.g = _ambientLight.g + _directionalLights.g + _pointLights.g;
					_light.b = _ambientLight.b + _directionalLights.b + _pointLights.b;
382

383 384 385
					_color.r = material.color.r * _light.r;
					_color.g = material.color.g * _light.g;
					_color.b = material.color.b * _light.b;
386

387
					_color.updateStyleString();
388

389
				} else {
390

391
					_color.__styleString = material.color.__styleString;
392

393
				}
394

395 396
				width = element.scale.x * _canvasWidthHalf;
				height = element.scale.y * _canvasHeightHalf;
397

398
				_bboxRect.set( v1.x - width, v1.y - height, v1.x + width, v1.y + height );
399

400
				if ( !_clipRect.instersects( _bboxRect ) ) {
401

402
					return;
403

404
				}
405

406
				setFillStyle( _color.__styleString );
407

408 409 410 411
				_context.save();
				_context.translate( v1.x, v1.y );
				_context.rotate( - element.rotation );
				_context.scale( width, height );
412

413 414 415
				_context.beginPath();
				_context.arc( 0, 0, 1, 0, _pi2, true );
				_context.closePath();
416

417 418
				_context.fill();
				_context.restore();
419

420
			}
421

M
Mr.doob 已提交
422
		}
423

424
		function renderLine( v1, v2, element, material, scene ) {
425

426
			if ( material.opacity == 0 ) return;
427

428 429
			setOpacity( material.opacity );
			setBlending( material.blending );
M
Mr.doob 已提交
430

431 432 433 434
			_context.beginPath();
			_context.moveTo( v1.positionScreen.x, v1.positionScreen.y );
			_context.lineTo( v2.positionScreen.x, v2.positionScreen.y );
			_context.closePath();
435

436
			if ( material instanceof THREE.LineBasicMaterial ) {
437

438
				_color.__styleString = material.color.__styleString;
439

440 441
				setLineWidth( material.linewidth );
				setStrokeStyle( _color.__styleString );
442

443 444
				_context.stroke();
				_bboxRect.inflate( material.linewidth * 2 );
445

446
			}
447

M
Mr.doob 已提交
448
		}
449

450
		function renderFace3( v1, v2, v3, element, material, scene ) {
451

452
			if ( material.opacity == 0 ) return;
453

454 455
			setOpacity( material.opacity );
			setBlending( material.blending );
456

457 458 459
			_v1x = v1.positionScreen.x; _v1y = v1.positionScreen.y;
			_v2x = v2.positionScreen.x; _v2y = v2.positionScreen.y;
			_v3x = v3.positionScreen.x; _v3y = v3.positionScreen.y;
460

461
			drawTriangle( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y );
M
Mr.doob 已提交
462

463
			if ( material instanceof THREE.MeshBasicMaterial ) {
464

465
				if ( material.map/* && !material.wireframe*/ ) {
466

467
					if ( material.map.image.loaded ) {
M
Mr.doob 已提交
468

469 470 471 472 473
						if ( material.map.mapping instanceof THREE.UVMapping ) {

							texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, element.uvs[ 0 ].u, element.uvs[ 0 ].v, element.uvs[ 1 ].u, element.uvs[ 1 ].v, element.uvs[ 2 ].u, element.uvs[ 2 ].v );

						}
M
Mr.doob 已提交
474

475
					}
476

477
				} else if ( material.env_map ) {
478

479 480 481 482 483
					if ( material.env_map.image.loaded ) {

						if ( material.env_map.mapping instanceof THREE.SphericalReflectionMapping ) {

							var cameraMatrix = camera.matrix;
484

485 486 487
							_vector3.copy( element.vertexNormalsWorld[ 0 ] );
							_uv1x = ( _vector3.x * cameraMatrix.n11 + _vector3.y * cameraMatrix.n12 + _vector3.z * cameraMatrix.n13 ) * 0.5 + 0.5;
							_uv1y = - ( _vector3.x * cameraMatrix.n21 + _vector3.y * cameraMatrix.n22 + _vector3.z * cameraMatrix.n23 ) * 0.5 + 0.5;
488

489 490 491
							_vector3.copy( element.vertexNormalsWorld[ 1 ] );
							_uv2x = ( _vector3.x * cameraMatrix.n11 + _vector3.y * cameraMatrix.n12 + _vector3.z * cameraMatrix.n13 ) * 0.5 + 0.5;
							_uv2y = - ( _vector3.x * cameraMatrix.n21 + _vector3.y * cameraMatrix.n22 + _vector3.z * cameraMatrix.n23 ) * 0.5 + 0.5;
492

493 494 495
							_vector3.copy( element.vertexNormalsWorld[ 2 ] );
							_uv3x = ( _vector3.x * cameraMatrix.n11 + _vector3.y * cameraMatrix.n12 + _vector3.z * cameraMatrix.n13 ) * 0.5 + 0.5;
							_uv3y = - ( _vector3.x * cameraMatrix.n21 + _vector3.y * cameraMatrix.n22 + _vector3.z * cameraMatrix.n23 ) * 0.5 + 0.5;
M
Mr.doob 已提交
496

497
							texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.env_map.image, _uv1x, _uv1y, _uv2x, _uv2y, _uv3x, _uv3y );
M
Mr.doob 已提交
498

499
						}/* else if ( material.env_map.mapping == THREE.RefractionMapping ) {
M
Mr.doob 已提交
500

501
						
M
Mr.doob 已提交
502

503 504 505
						}*/

					}
506

507
				} else {
508

509
					material.wireframe ? strokePath( material.color.__styleString, material.wireframe_linewidth ) : fillPath( material.color.__styleString );
510

511
				}
512

513
			} else if ( material instanceof THREE.MeshLambertMaterial ) {
M
Mr.doob 已提交
514

515
				if ( material.map && !material.wireframe ) {
M
Mr.doob 已提交
516

517
					if ( material.map.mapping instanceof THREE.UVMapping ) {
518

519
						texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, material.map.image, element.uvs[ 0 ].u, element.uvs[ 0 ].v, element.uvs[ 1 ].u, element.uvs[ 1 ].v, element.uvs[ 2 ].u, element.uvs[ 2 ].v );
520

521
					}
522

523
					setBlending( THREE.SubtractiveBlending );
524

525
				}
526

527
				if ( _enableLighting ) {
528

529
					if ( !material.wireframe && material.shading == THREE.SmoothShading && element.vertexNormalsWorld.length == 3 ) {
M
Mr.doob 已提交
530

531 532 533
						_color1.r = _color2.r = _color3.r = _ambientLight.r;
						_color1.g = _color2.g = _color3.g = _ambientLight.g;
						_color1.b = _color2.b = _color3.b = _ambientLight.b;
M
Mr.doob 已提交
534

535 536 537
						calculateLight( scene, element.v1.positionWorld, element.vertexNormalsWorld[ 0 ], _color1 );
						calculateLight( scene, element.v2.positionWorld, element.vertexNormalsWorld[ 1 ], _color2 );
						calculateLight( scene, element.v3.positionWorld, element.vertexNormalsWorld[ 2 ], _color3 );
M
Mr.doob 已提交
538

539 540 541
						_color4.r = ( _color2.r + _color3.r ) * 0.5;
						_color4.g = ( _color2.g + _color3.g ) * 0.5;
						_color4.b = ( _color2.b + _color3.b ) * 0.5;
M
Mr.doob 已提交
542

543
						_bitmap = getGradientTexture( _color1, _color2, _color3, _color4 );
M
Mr.doob 已提交
544

545
						texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _bitmap, 0, 0, 1, 0, 0, 1 );
546

547
					} else {
548

549 550 551
						_light.r = _ambientLight.r;
						_light.g = _ambientLight.g;
						_light.b = _ambientLight.b;
M
Mr.doob 已提交
552

553
						calculateLight( scene, element.centroidWorld, element.normalWorld, _light );
554

555 556 557
						_color.r = material.color.r * _light.r;
						_color.g = material.color.g * _light.g;
						_color.b = material.color.b * _light.b;
558

559 560
						_color.updateStyleString();
						material.wireframe ? strokePath( _color.__styleString, material.wireframe_linewidth ) : fillPath( _color.__styleString );
561

562
					} 
563

564
				} else {
M
Mr.doob 已提交
565

566
					material.wireframe ? strokePath( material.color.__styleString, material.wireframe_linewidth ) : fillPath( material.color.__styleString );
M
Mr.doob 已提交
567

568 569 570
				}

			} else if ( material instanceof THREE.MeshDepthMaterial ) {
571

572 573 574 575 576 577 578 579
				/*
				_w = 1 - ( material.__2near / (material.__farPlusNear - element.z * material.__farMinusNear ) );
				_color.setRGB( _w, _w, _w );
				*/

				_2near = material.__2near;
				_farPlusNear = material.__farPlusNear;
				_farMinusNear = material.__farMinusNear;
580

581 582 583
				_color1.r = _color1.g = _color1.b = 1 - ( _2near / ( _farPlusNear - v1.positionScreen.z * _farMinusNear ) );
				_color2.r = _color2.g = _color2.b = 1 - ( _2near / ( _farPlusNear - v2.positionScreen.z * _farMinusNear ) );
				_color3.r = _color3.g = _color3.b = 1 - ( _2near / ( _farPlusNear - v3.positionScreen.z * _farMinusNear ) );
M
Mr.doob 已提交
584

585 586 587
				_color4.r = ( _color2.r + _color3.r ) * 0.5;
				_color4.g = ( _color2.g + _color3.g ) * 0.5;
				_color4.b = ( _color2.b + _color3.b ) * 0.5;
588

589
				_bitmap = getGradientTexture( _color1, _color2, _color3, _color4 );
M
Mr.doob 已提交
590

591
				texturePath( _v1x, _v1y, _v2x, _v2y, _v3x, _v3y, _bitmap, 0, 0, 1, 0, 0, 1 );
M
Mr.doob 已提交
592

593
			} else if ( material instanceof THREE.MeshNormalMaterial ) {
594

595 596 597 598 599 600
				_color.r = normalToComponent( element.normalWorld.x );
				_color.g = normalToComponent( element.normalWorld.y );
				_color.b = normalToComponent( element.normalWorld.z );
				_color.updateStyleString();

				material.wireframe ? strokePath( _color.__styleString, material.wireframe_linewidth ) : fillPath( _color.__styleString );
601

602
			}
M
Mr.doob 已提交
603

M
Mr.doob 已提交
604 605
		}

606
		function drawTriangle( x0, y0, x1, y1, x2, y2 ) {
M
Mr.doob 已提交
607

608 609 610 611 612 613
			_context.beginPath();
			_context.moveTo( x0, y0 );
			_context.lineTo( x1, y1 );
			_context.lineTo( x2, y2 );
			_context.lineTo( x0, y0 );
			_context.closePath();
M
Mr.doob 已提交
614

615
		}
M
Mr.doob 已提交
616

617 618
		/*
		function drawQuad( x0, y0, x1, y1, x2, y2, x3, y3 ) {
M
Mr.doob 已提交
619

620 621 622 623 624 625 626
			_context.beginPath();
			_context.moveTo( x0, y0 );
			_context.lineTo( x1, y1 );
			_context.lineTo( x2, y2 );
			_context.lineTo( x3, y3 );
			_context.lineTo( x0, y0 );
			_context.closePath();
M
Mr.doob 已提交
627

628 629
		}
		*/
M
Mr.doob 已提交
630

631
		function strokePath( color, linewidth ) {
M
Mr.doob 已提交
632

633 634
			setStrokeStyle( color );
			setLineWidth( linewidth );
M
Mr.doob 已提交
635

636
			_context.stroke();
M
Mr.doob 已提交
637

638
			_bboxRect.inflate( linewidth * 2 );
M
Mr.doob 已提交
639

640
		}
M
Mr.doob 已提交
641

642
		function fillPath( color ) {
M
Mr.doob 已提交
643

644 645
			setFillStyle( color );
			_context.fill();
M
Mr.doob 已提交
646

647
		}
648

649
		function texturePath( x0, y0, x1, y1, x2, y2, bitmap, u0, v0, u1, v1, u2, v2 ) {
650

651
			// http://extremelysatisfactorytotalitarianism.com/blog/?p=2120
M
Mr.doob 已提交
652

653 654 655
			var a, b, c, d, e, f, det,
			width = bitmap.width - 1,
			height = bitmap.height - 1;
656

657 658 659
			u0 *= width; v0 *= height;
			u1 *= width; v1 *= height;
			u2 *= width; v2 *= height;
660

661 662
			x1 -= x0; y1 -= y0;
			x2 -= x0; y2 -= y0;
M
Mr.doob 已提交
663

664 665
			u1 -= u0; v1 -= v0;
			u2 -= u0; v2 -= v0;
M
Mr.doob 已提交
666

667
			det = 1 / ( u1 * v2 - u2 * v1 ),
668

669 670 671 672
			a = ( v2 * x1 - v1 * x2 ) * det,
			b = ( v2 * y1 - v1 * y2 ) * det,
			c = ( u1 * x2 - u2 * x1 ) * det,
			d = ( u1 * y2 - u2 * y1 ) * det,
673

674 675
			e = x0 - a * u0 - c * v0,
			f = y0 - b * u0 - d * v0;
676

677 678 679 680 681
			_context.save();
			_context.transform( a, b, c, d, e, f );
			_context.clip();
			_context.drawImage( bitmap, 0, 0 );
			_context.restore();
682

683
		}
M
Mr.doob 已提交
684

685
		//
686

687
		function setOpacity( value ) {
M
Mr.doob 已提交
688

689
			if ( _contextGlobalAlpha != value ) {
M
Mr.doob 已提交
690

691
				_context.globalAlpha = _contextGlobalAlpha = value;
692

693
			}
694

M
Mr.doob 已提交
695 696
		}

697 698 699
		function setBlending( value ) {

			if ( _contextGlobalCompositeOperation != value ) {
700

701
				switch ( value ) {
702

703
					case THREE.NormalBlending:
704

705
						_context.globalCompositeOperation = 'source-over';
706

707
						break;
708

709
					case THREE.AdditiveBlending:
710

711
						_context.globalCompositeOperation = 'lighter';
712

713
						break;
714

715
					case THREE.SubtractiveBlending:
M
Mr.doob 已提交
716

717
						_context.globalCompositeOperation = 'darker';
M
Mr.doob 已提交
718

719
						break;
M
Mr.doob 已提交
720

721
				}
M
Mr.doob 已提交
722

723
				_contextGlobalCompositeOperation = value;
M
Mr.doob 已提交
724 725 726 727 728

			}

		}

729
		function setLineWidth( value ) {
M
Mr.doob 已提交
730

731
			if ( _contextLineWidth != value ) {
M
Mr.doob 已提交
732

733
				_context.lineWidth = _contextLineWidth = value;
M
Mr.doob 已提交
734

735
			}
M
Mr.doob 已提交
736 737 738

		}

739
		function setStrokeStyle( value ) {
M
Mr.doob 已提交
740

741
			if ( _contextStrokeStyle != value ) {
M
Mr.doob 已提交
742

743
				_context.strokeStyle = _contextStrokeStyle  = value;
M
Mr.doob 已提交
744

745
			}
746 747 748

		}

749
		function setFillStyle( value ) {
M
Mr.doob 已提交
750

751
			if ( _contextFillStyle != value ) {
M
Mr.doob 已提交
752

753
				_context.fillStyle = _contextFillStyle = value;
M
Mr.doob 已提交
754

755
			}
M
Mr.doob 已提交
756 757

		}
758

759
		function getGradientTexture( color1, color2, color3, color4 ) {
760

761
			// http://mrdoob.com/blog/post/710
762

763 764 765
			_pixelMapData[ 0 ] = _max( 0, _min( 255, ~~ ( color1.r * 255 ) ) );
			_pixelMapData[ 1 ] = _max( 0, _min( 255, ~~ ( color1.g * 255 ) ) );
			_pixelMapData[ 2 ] = _max( 0, _min( 255, ~~ ( color1.b * 255 ) ) );
766

767 768 769
			_pixelMapData[ 4 ] = _max( 0, _min( 255, ~~ ( color2.r * 255 ) ) );
			_pixelMapData[ 5 ] = _max( 0, _min( 255, ~~ ( color2.g * 255 ) ) );
			_pixelMapData[ 6 ] = _max( 0, _min( 255, ~~ ( color2.b * 255 ) ) );
770

771 772 773
			_pixelMapData[ 8 ] = _max( 0, _min( 255, ~~ ( color3.r * 255 ) ) );
			_pixelMapData[ 9 ] = _max( 0, _min( 255, ~~ ( color3.g * 255 ) ) );
			_pixelMapData[ 10 ] = _max( 0, _min( 255, ~~ ( color3.b * 255 ) ) );
774

775 776 777
			_pixelMapData[ 12 ] = _max( 0, _min( 255, ~~ ( color4.r * 255 ) ) );
			_pixelMapData[ 13 ] = _max( 0, _min( 255, ~~ ( color4.g * 255 ) ) );
			_pixelMapData[ 14 ] = _max( 0, _min( 255, ~~ ( color4.b * 255 ) ) );
778

779 780
			_pixelMapContext.putImageData( _pixelMapImage, 0, 0 );
			_gradientMapContext.drawImage( _pixelMap, 0, 0 );
781

782
			return _gradientMap;
783

784
		}
785

786
		function normalToComponent( normal ) {
787

788 789
			var component = ( normal + 1 ) * 0.5;
			return component < 0 ? 0 : ( component > 1 ? 1 : component );
790

791
		}
792

793
		// Hide anti-alias gaps
794

795
		function expand( v1, v2 ) {
M
Mr.doob 已提交
796

797 798
			var x = v2.x - v1.x, y =  v2.y - v1.y,
			unit = 1 / Math.sqrt( x * x + y * y );
799

800
			x *= unit; y *= unit;
801

802 803
			v2.x += x; v2.y += y;
			v1.x -= x; v1.y -= y;
804

805
		}
806

807
	};
808

M
Mr.doob 已提交
809
};