WebGLProgram.js 23.8 KB
Newer Older
1 2 3 4
/**
 * @author mrdoob / http://mrdoob.com/
 */

B
bentok 已提交
5 6 7
import { WebGLUniforms } from './WebGLUniforms.js';
import { WebGLShader } from './WebGLShader.js';
import { ShaderChunk } from '../shaders/ShaderChunk.js';
S
supereggbert 已提交
8
import { NoToneMapping, AddOperation, MixOperation, MultiplyOperation, EquirectangularRefractionMapping, CubeRefractionMapping, SphericalReflectionMapping, EquirectangularReflectionMapping, CubeUVRefractionMapping, CubeUVReflectionMapping, CubeReflectionMapping, PCFSoftShadowMap, PCFShadowMap, VSMShadowMap, ACESFilmicToneMapping, CineonToneMapping, Uncharted2ToneMapping, ReinhardToneMapping, LinearToneMapping, GammaEncoding, RGBDEncoding, RGBM16Encoding, RGBM7Encoding, RGBEEncoding, sRGBEncoding, LinearEncoding, LogLuvEncoding } from '../../constants.js';
R
Rich Harris 已提交
9

10 11
var programIdCount = 0;

A
aardgoose 已提交
12 13 14 15 16 17 18 19 20 21 22 23 24 25
function addLineNumbers( string ) {

	var lines = string.split( '\n' );

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

		lines[ i ] = ( i + 1 ) + ': ' + lines[ i ];

	}

	return lines.join( '\n' );

}

26 27 28 29 30
function getEncodingComponents( encoding ) {

	switch ( encoding ) {

		case LinearEncoding:
M
Mugen87 已提交
31
			return [ 'Linear', '( value )' ];
32
		case sRGBEncoding:
M
Mugen87 已提交
33
			return [ 'sRGB', '( value )' ];
34
		case RGBEEncoding:
M
Mugen87 已提交
35
			return [ 'RGBE', '( value )' ];
36
		case RGBM7Encoding:
M
Mugen87 已提交
37
			return [ 'RGBM', '( value, 7.0 )' ];
38
		case RGBM16Encoding:
M
Mugen87 已提交
39
			return [ 'RGBM', '( value, 16.0 )' ];
40
		case RGBDEncoding:
M
Mugen87 已提交
41
			return [ 'RGBD', '( value, 256.0 )' ];
42
		case GammaEncoding:
M
Mugen87 已提交
43
			return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ];
A
angus 已提交
44
		case LogLuvEncoding:
A
angus 已提交
45
			return [ 'LogLuv', '( value )' ];
46 47
		default:
			throw new Error( 'unsupported encoding: ' + encoding );
48

49 50
	}

51
}
52

A
aardgoose 已提交
53
function getShaderErrors( gl, shader, type ) {
A
aardgoose 已提交
54 55 56 57 58 59 60 61 62

	var status = gl.getShaderParameter( shader, gl.COMPILE_STATUS );
	var log = gl.getShaderInfoLog( shader ).trim();

	if ( status && log === '' ) return '';

	// --enable-privileged-webgl-extension
	// console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) );

A
aardgoose 已提交
63 64 65
	var source = gl.getShaderSource( shader );

	return 'THREE.WebGLShader: gl.getShaderInfoLog() ' + type + '\n' + log + addLineNumbers( source );
A
aardgoose 已提交
66 67 68

}

69
function getTexelDecodingFunction( functionName, encoding ) {
70

71
	var components = getEncodingComponents( encoding );
M
Mr.doob 已提交
72
	return 'vec4 ' + functionName + '( vec4 value ) { return ' + components[ 0 ] + 'ToLinear' + components[ 1 ] + '; }';
73

74
}
75

76
function getTexelEncodingFunction( functionName, encoding ) {
77

78
	var components = getEncodingComponents( encoding );
M
Mr.doob 已提交
79
	return 'vec4 ' + functionName + '( vec4 value ) { return LinearTo' + components[ 0 ] + components[ 1 ] + '; }';
M
Mr.doob 已提交
80

81
}
B
Ben Houston 已提交
82

83
function getToneMappingFunction( functionName, toneMapping ) {
M
Mr.doob 已提交
84

85
	var toneMappingName;
M
Mr.doob 已提交
86

87
	switch ( toneMapping ) {
M
Mr.doob 已提交
88

89
		case LinearToneMapping:
M
Mr.doob 已提交
90
			toneMappingName = 'Linear';
91
			break;
M
Mr.doob 已提交
92

93
		case ReinhardToneMapping:
M
Mr.doob 已提交
94
			toneMappingName = 'Reinhard';
95
			break;
M
Mr.doob 已提交
96

97
		case Uncharted2ToneMapping:
M
Mr.doob 已提交
98
			toneMappingName = 'Uncharted2';
99
			break;
B
Ben Houston 已提交
100

101
		case CineonToneMapping:
M
Mr.doob 已提交
102
			toneMappingName = 'OptimizedCineon';
103
			break;
M
Mr.doob 已提交
104

C
ChenX 已提交
105 106
		case ACESFilmicToneMapping:
			toneMappingName = 'ACESFilmic';
C
ChenX 已提交
107 108
			break;

109 110
		default:
			throw new Error( 'unsupported toneMapping: ' + toneMapping );
B
Ben Houston 已提交
111 112 113

	}

M
Mr.doob 已提交
114
	return 'vec3 ' + functionName + '( vec3 color ) { return ' + toneMappingName + 'ToneMapping( color ); }';
115

116
}
117

118
function generateExtensions( extensions, parameters, rendererExtensions ) {
119

120
	extensions = extensions || {};
121

122
	var chunks = [
123
		( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || parameters.tangentSpaceNormalMap || parameters.clearcoatNormalMap || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',
124 125
		( extensions.fragDepth || parameters.logarithmicDepthBuffer ) && rendererExtensions.get( 'EXT_frag_depth' ) ? '#extension GL_EXT_frag_depth : enable' : '',
		( extensions.drawBuffers ) && rendererExtensions.get( 'WEBGL_draw_buffers' ) ? '#extension GL_EXT_draw_buffers : require' : '',
126
		( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''
127
	];
128

129
	return chunks.filter( filterEmptyLine ).join( '\n' );
130

131
}
132

133
function generateDefines( defines ) {
134

135
	var chunks = [];
136

137
	for ( var name in defines ) {
138

139
		var value = defines[ name ];
140

141
		if ( value === false ) continue;
142

143
		chunks.push( '#define ' + name + ' ' + value );
144

M
Mr.doob 已提交
145
	}
146

147
	return chunks.join( '\n' );
148

149
}
150

M
Mugen87 已提交
151
function fetchAttributeLocations( gl, program ) {
M
Mr.doob 已提交
152

153
	var attributes = {};
154

155
	var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );
156

157
	for ( var i = 0; i < n; i ++ ) {
158

159 160
		var info = gl.getActiveAttrib( program, i );
		var name = info.name;
161

M
Mugen87 已提交
162
		// console.log( 'THREE.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i );
163

164
		attributes[ name ] = gl.getAttribLocation( program, name );
165

M
Mr.doob 已提交
166
	}
167

168
	return attributes;
169

170
}
M
Mr.doob 已提交
171

172
function filterEmptyLine( string ) {
173

174
	return string !== '';
175

176
}
177

178
function replaceLightNums( string, parameters ) {
179

180 181 182
	return string
		.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
		.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
183
		.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )
184
		.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
185 186 187 188
		.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights )
		.replace( /NUM_DIR_LIGHT_SHADOWS/g, parameters.numDirLightShadows )
		.replace( /NUM_SPOT_LIGHT_SHADOWS/g, parameters.numSpotLightShadows )
		.replace( /NUM_POINT_LIGHT_SHADOWS/g, parameters.numPointLightShadows );
M
Mr.doob 已提交
189

190
}
M
Mr.doob 已提交
191

192 193 194 195 196 197 198 199
function replaceClippingPlaneNums( string, parameters ) {

	return string
		.replace( /NUM_CLIPPING_PLANES/g, parameters.numClippingPlanes )
		.replace( /UNION_CLIPPING_PLANES/g, ( parameters.numClippingPlanes - parameters.numClipIntersection ) );

}

200 201 202
// Resolve Includes

var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm;
M
Mr.doob 已提交
203

204
function parseIncludes( string ) {
205

206
	return string.replace( includePattern, includeReplacer );
207

208
}
209

210
function includeReplacer( match, include ) {
211

212
	var string = ShaderChunk[ include ];
M
Mr.doob 已提交
213

214
	if ( string === undefined ) {
M
Mr.doob 已提交
215

216
		throw new Error( 'Can not resolve #include <' + include + '>' );
M
Mr.doob 已提交
217 218 219

	}

220
	return parseIncludes( string );
M
Mr.doob 已提交
221

222
}
M
Mr.doob 已提交
223

224
function unrollLoops( string ) {
M
Mr.doob 已提交
225

226
	var pattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
M
Mr.doob 已提交
227

228
	function replace( match, start, end, snippet ) {
M
Mr.doob 已提交
229

230
		var unroll = '';
M
Mr.doob 已提交
231

232
		for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {
M
Mr.doob 已提交
233

234 235 236
			unroll += snippet
				.replace( /\[ i \]/g, '[ ' + i + ' ]' )
				.replace( /UNROLLED_LOOP_INDEX/g, i );
M
Mr.doob 已提交
237 238 239

		}

240
		return unroll;
M
Mr.doob 已提交
241 242 243

	}

244
	return string.replace( pattern, replace );
245

246
}
247

G
gero3 已提交
248
function generatePrecision( parameters ) {
249

G
gero3 已提交
250
	var precisionstring = "precision " + parameters.precision + " float;\nprecision " + parameters.precision + " int;";
251

G
gero3 已提交
252
	if ( parameters.precision === "highp" ) {
253

G
gero3 已提交
254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
		precisionstring += "\n#define HIGH_PRECISION;";

	} else if ( parameters.precision === "mediump" ) {

		precisionstring += "\n#define MEDIUM_PRECISION;";

	} else if ( parameters.precision === "lowp" ) {

		precisionstring += "\n#define LOW_PRECISION;";

	}

	return precisionstring;

}

function generateShadowMapTypeDefine( parameters ) {
271

272
	var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
273

274
	if ( parameters.shadowMapType === PCFShadowMap ) {
275

276
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
277

278
	} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
279

280
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
281

S
supereggbert 已提交
282 283 284 285
	} else if ( parameters.shadowMapType === VSMShadowMap ) {

		shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';

286
	}
287

G
gero3 已提交
288 289 290 291 292 293
	return shadowMapTypeDefine;

}

function generateEnvMapTypeDefine( parameters, material ) {

294
	var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
295

296
	if ( parameters.envMap ) {
B
Ben Houston 已提交
297

298
		switch ( material.envMap.mapping ) {
299

300 301 302 303
			case CubeReflectionMapping:
			case CubeRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
				break;
304

305 306 307 308
			case CubeUVReflectionMapping:
			case CubeUVRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
				break;
309

310 311 312 313
			case EquirectangularReflectionMapping:
			case EquirectangularRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
				break;
M
Mr.doob 已提交
314

315 316 317
			case SphericalReflectionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
				break;
M
Mr.doob 已提交
318

319
		}
M
Mr.doob 已提交
320

G
gero3 已提交
321 322 323 324 325 326 327 328 329 330 331 332
	}

	return envMapTypeDefine;

}

function generateEnvMapModeDefine( parameters, material ) {

	var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';

	if ( parameters.envMap ) {

333
		switch ( material.envMap.mapping ) {
334

335 336 337 338
			case CubeRefractionMapping:
			case EquirectangularRefractionMapping:
				envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
				break;
339

340
		}
341

G
gero3 已提交
342 343 344 345 346 347 348 349 350 351 352 353
	}

	return envMapModeDefine;

}

function generateEnvMapBlendingDefine( parameters, material ) {

	var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';

	if ( parameters.envMap ) {

354
		switch ( material.combine ) {
355

356 357 358
			case MultiplyOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
				break;
359

360 361 362
			case MixOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
				break;
363

364 365 366
			case AddOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
				break;
367

368
		}
369

370
	}
371

G
gero3 已提交
372 373 374 375
	return envMapBlendingDefine;

}

G
gero3 已提交
376
function WebGLProgram( renderer, extensions, code, material, shader, parameters ) {
G
gero3 已提交
377 378 379 380

	var gl = renderer.getContext();

	var defines = material.defines;
381

G
gero3 已提交
382 383 384 385 386 387
	var vertexShader = shader.vertexShader;
	var fragmentShader = shader.fragmentShader;
	var shadowMapTypeDefine = generateShadowMapTypeDefine( parameters );
	var envMapTypeDefine = generateEnvMapTypeDefine( parameters, material );
	var envMapModeDefine = generateEnvMapModeDefine( parameters, material );
	var envMapBlendingDefine = generateEnvMapBlendingDefine( parameters, material );
388

G
gero3 已提交
389 390

	var gammaFactorDefine = ( renderer.gammaFactor > 0 ) ? renderer.gammaFactor : 1.0;
391

G
gero3 已提交
392
	var customExtensions = parameters.isWebGL2 ? '' : generateExtensions( material.extensions, parameters, extensions );
393

394
	var customDefines = generateDefines( defines );
395

396
	var program = gl.createProgram();
397

398
	var prefixVertex, prefixFragment;
399

400
	var renderTarget = renderer.getRenderTarget();
401
	var numMultiviewViews = renderTarget && renderTarget.isWebGLMultiviewRenderTarget ? renderTarget.numViews : 0;
402

M
Mr.doob 已提交
403
	if ( material.isRawShaderMaterial ) {
404

405
		prefixVertex = [
406

407
			customDefines
408

409
		].filter( filterEmptyLine ).join( '\n' );
410

411 412 413 414 415 416
		if ( prefixVertex.length > 0 ) {

			prefixVertex += '\n';

		}

417
		prefixFragment = [
418

419
			customExtensions,
420
			customDefines
421

422
		].filter( filterEmptyLine ).join( '\n' );
423

424 425 426 427 428 429
		if ( prefixFragment.length > 0 ) {

			prefixFragment += '\n';

		}

430
	} else {
431

432
		prefixVertex = [
433

G
gero3 已提交
434
			generatePrecision( parameters ),
W
WestLangley 已提交
435

436
			'#define SHADER_NAME ' + shader.name,
437

438
			customDefines,
439

440
			parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
441

442
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
443

444
			'#define MAX_BONES ' + parameters.maxBones,
445
			( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
E
Elias Hasle 已提交
446
			( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
447

448 449 450 451 452 453 454 455
			parameters.map ? '#define USE_MAP' : '',
			parameters.envMap ? '#define USE_ENVMAP' : '',
			parameters.envMap ? '#define ' + envMapModeDefine : '',
			parameters.lightMap ? '#define USE_LIGHTMAP' : '',
			parameters.aoMap ? '#define USE_AOMAP' : '',
			parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
			parameters.bumpMap ? '#define USE_BUMPMAP' : '',
			parameters.normalMap ? '#define USE_NORMALMAP' : '',
W
WestLangley 已提交
456
			( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
457
			( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
A
arobertson0 已提交
458

459
			parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
460 461 462 463 464
			parameters.displacementMap && parameters.supportsVertexTextures ? '#define USE_DISPLACEMENTMAP' : '',
			parameters.specularMap ? '#define USE_SPECULARMAP' : '',
			parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
			parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
D
Don McCurdy 已提交
465 466

			parameters.vertexTangents ? '#define USE_TANGENT' : '',
467
			parameters.vertexColors ? '#define USE_COLOR' : '',
468
			parameters.vertexUvs ? '#define USE_UV' : '',
469

470
			parameters.flatShading ? '#define FLAT_SHADED' : '',
T
tschw 已提交
471

472 473
			parameters.skinning ? '#define USE_SKINNING' : '',
			parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
474

475 476 477 478
			parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
			parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
			parameters.flipSided ? '#define FLIP_SIDED' : '',
479

480 481
			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
482

483
			parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
484

485
			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
G
gero3 已提交
486
			parameters.logarithmicDepthBuffer && ( parameters.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
487 488
			'uniform mat4 modelMatrix;',
			'uniform vec3 cameraPosition;',
489

490
			numMultiviewViews > 0 ? [
491 492 493 494
				'uniform mat4 modelViewMatrices[' + numMultiviewViews + '];',
				'uniform mat3 normalMatrices[' + numMultiviewViews + '];',
				'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
				'uniform mat4 projectionMatrices[' + numMultiviewViews + '];',
495

496 497
				'#define modelViewMatrix modelViewMatrices[VIEW_ID]',
				'#define normalMatrix normalMatrices[VIEW_ID]',
498 499 500 501 502 503 504 505 506 507 508 509
				'#define viewMatrix viewMatrices[VIEW_ID]',
				'#define projectionMatrix projectionMatrices[VIEW_ID]'

			].join( '\n' ) : [

				'uniform mat4 modelViewMatrix;',
				'uniform mat4 projectionMatrix;',
				'uniform mat4 viewMatrix;',
				'uniform mat3 normalMatrix;',

			].join( '\n' ),

510 511 512
			'attribute vec3 position;',
			'attribute vec3 normal;',
			'attribute vec2 uv;',
513

D
Don McCurdy 已提交
514 515 516 517 518 519
			'#ifdef USE_TANGENT',

			'	attribute vec4 tangent;',

			'#endif',

520
			'#ifdef USE_COLOR',
521

522
			'	attribute vec3 color;',
523

524
			'#endif',
525

526
			'#ifdef USE_MORPHTARGETS',
527

528 529 530 531
			'	attribute vec3 morphTarget0;',
			'	attribute vec3 morphTarget1;',
			'	attribute vec3 morphTarget2;',
			'	attribute vec3 morphTarget3;',
532

533
			'	#ifdef USE_MORPHNORMALS',
534

535 536 537 538
			'		attribute vec3 morphNormal0;',
			'		attribute vec3 morphNormal1;',
			'		attribute vec3 morphNormal2;',
			'		attribute vec3 morphNormal3;',
539

540
			'	#else',
541

542 543 544 545
			'		attribute vec3 morphTarget4;',
			'		attribute vec3 morphTarget5;',
			'		attribute vec3 morphTarget6;',
			'		attribute vec3 morphTarget7;',
546

547
			'	#endif',
548

549
			'#endif',
550

551
			'#ifdef USE_SKINNING',
552

553 554
			'	attribute vec4 skinIndex;',
			'	attribute vec4 skinWeight;',
555

556
			'#endif',
557

558
			'\n'
W
WestLangley 已提交
559

560
		].filter( filterEmptyLine ).join( '\n' );
561

562
		prefixFragment = [
563

564
			customExtensions,
565

G
gero3 已提交
566
			generatePrecision( parameters ),
W
WestLangley 已提交
567

568
			'#define SHADER_NAME ' + shader.name,
569

570
			customDefines,
571

572
			parameters.alphaTest ? '#define ALPHATEST ' + parameters.alphaTest + ( parameters.alphaTest % 1 ? '' : '.0' ) : '', // add '.0' if integer
573

574
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
575

576
			( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
E
Elias Hasle 已提交
577
			( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
578

579
			parameters.map ? '#define USE_MAP' : '',
580
			parameters.matcap ? '#define USE_MATCAP' : '',
581 582 583 584 585 586 587 588 589
			parameters.envMap ? '#define USE_ENVMAP' : '',
			parameters.envMap ? '#define ' + envMapTypeDefine : '',
			parameters.envMap ? '#define ' + envMapModeDefine : '',
			parameters.envMap ? '#define ' + envMapBlendingDefine : '',
			parameters.lightMap ? '#define USE_LIGHTMAP' : '',
			parameters.aoMap ? '#define USE_AOMAP' : '',
			parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
			parameters.bumpMap ? '#define USE_BUMPMAP' : '',
			parameters.normalMap ? '#define USE_NORMALMAP' : '',
W
WestLangley 已提交
590
			( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
591
			( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
592
			parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
593 594 595 596
			parameters.specularMap ? '#define USE_SPECULARMAP' : '',
			parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
			parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
D
Don McCurdy 已提交
597

598 599
			parameters.sheen ? '#define USE_SHEEN' : '',

D
Don McCurdy 已提交
600
			parameters.vertexTangents ? '#define USE_TANGENT' : '',
601
			parameters.vertexColors ? '#define USE_COLOR' : '',
602
			parameters.vertexUvs ? '#define USE_UV' : '',
T
tschw 已提交
603

T
Takahiro 已提交
604
			parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
T
Takahiro 已提交
605

606
			parameters.flatShading ? '#define FLAT_SHADED' : '',
607

608 609
			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
			parameters.flipSided ? '#define FLIP_SIDED' : '',
610

611 612
			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
613

M
Mr.doob 已提交
614
			parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '',
W
WestLangley 已提交
615

M
Mr.doob 已提交
616
			parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '',
617

618
			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
G
gero3 已提交
619
			parameters.logarithmicDepthBuffer && ( parameters.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
620

G
gero3 已提交
621
			( ( material.extensions ? material.extensions.shaderTextureLOD : false ) || parameters.envMap ) && ( parameters.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '',
622

623
			'uniform vec3 cameraPosition;',
624

625
			numMultiviewViews > 0 ? [
626

627
				'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
628 629 630 631
				'#define viewMatrix viewMatrices[VIEW_ID]'

			].join( '\n' ) : 'uniform mat4 viewMatrix;',

M
Mr.doob 已提交
632
			( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '',
M
Mugen87 已提交
633
			( parameters.toneMapping !== NoToneMapping ) ? ShaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below
M
Mr.doob 已提交
634
			( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '',
635

636
			parameters.dithering ? '#define DITHERING' : '',
637

W
WestLangley 已提交
638 639
			( parameters.outputEncoding || parameters.mapEncoding || parameters.matcapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding ) ?
				ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below
640
			parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
W
WestLangley 已提交
641
			parameters.matcapEncoding ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '',
642 643
			parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
			parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
M
Mr.doob 已提交
644
			parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '',
645

M
Mr.doob 已提交
646
			parameters.depthPacking ? '#define DEPTH_PACKING ' + material.depthPacking : '',
647

648
			'\n'
M
Mr.doob 已提交
649

650
		].filter( filterEmptyLine ).join( '\n' );
651

652
	}
M
Mr.doob 已提交
653

M
Mr.doob 已提交
654
	vertexShader = parseIncludes( vertexShader );
655
	vertexShader = replaceLightNums( vertexShader, parameters );
656
	vertexShader = replaceClippingPlaneNums( vertexShader, parameters );
657

M
Mr.doob 已提交
658
	fragmentShader = parseIncludes( fragmentShader );
659
	fragmentShader = replaceLightNums( fragmentShader, parameters );
660
	fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters );
661

662 663
	vertexShader = unrollLoops( vertexShader );
	fragmentShader = unrollLoops( fragmentShader );
664

G
gero3 已提交
665
	if ( parameters.isWebGL2 && ! material.isRawShaderMaterial ) {
T
Takahiro 已提交
666

667 668 669 670 671 672 673 674 675 676 677 678 679 680
		var isGLSL3ShaderMaterial = false;

		var versionRegex = /^\s*#version\s+300\s+es\s*\n/;

		if ( material.isShaderMaterial &&
			vertexShader.match( versionRegex ) !== null &&
			fragmentShader.match( versionRegex ) !== null ) {

			isGLSL3ShaderMaterial = true;

			vertexShader = vertexShader.replace( versionRegex, '' );
			fragmentShader = fragmentShader.replace( versionRegex, '' );

		}
T
Takahiro 已提交
681

T
Takahiro 已提交
682
		// GLSL 3.0 conversion
T
Takahiro 已提交
683 684
		prefixVertex = [
			'#version 300 es\n',
685

686
			numMultiviewViews > 0 ? [
687 688

				'#extension GL_OVR_multiview2 : require',
689
				'layout(num_views = ' + numMultiviewViews + ') in;',
690 691 692 693
				'#define VIEW_ID gl_ViewID_OVR'

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

T
Takahiro 已提交
694 695 696
			'#define attribute in',
			'#define varying out',
			'#define texture2D texture'
T
Takahiro 已提交
697
		].join( '\n' ) + '\n' + prefixVertex;
T
Takahiro 已提交
698

T
Takahiro 已提交
699 700
		prefixFragment = [
			'#version 300 es\n',
701
			numMultiviewViews > 0 ? [
702 703 704 705 706

				'#extension GL_OVR_multiview2 : require',
				'#define VIEW_ID gl_ViewID_OVR'

			].join( '\n' ) : '',
T
Takahiro 已提交
707
			'#define varying in',
T
Takahiro 已提交
708 709
			isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;',
			isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor',
T
Takahiro 已提交
710
			'#define gl_FragDepthEXT gl_FragDepth',
T
Takahiro 已提交
711 712 713 714 715 716 717 718 719
			'#define texture2D texture',
			'#define textureCube texture',
			'#define texture2DProj textureProj',
			'#define texture2DLodEXT textureLod',
			'#define texture2DProjLodEXT textureProjLod',
			'#define textureCubeLodEXT textureLod',
			'#define texture2DGradEXT textureGrad',
			'#define texture2DProjGradEXT textureProjGrad',
			'#define textureCubeGradEXT textureGrad'
T
Takahiro 已提交
720
		].join( '\n' ) + '\n' + prefixFragment;
T
Takahiro 已提交
721 722 723

	}

724 725
	var vertexGlsl = prefixVertex + vertexShader;
	var fragmentGlsl = prefixFragment + fragmentShader;
726

727 728 729 730 731
	// console.log( '*VERTEX*', vertexGlsl );
	// console.log( '*FRAGMENT*', fragmentGlsl );

	var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
	var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
732

733 734
	gl.attachShader( program, glVertexShader );
	gl.attachShader( program, glFragmentShader );
735

736
	// Force a particular attribute to index 0.
737

738
	if ( material.index0AttributeName !== undefined ) {
739

740
		gl.bindAttribLocation( program, 0, material.index0AttributeName );
741

742
	} else if ( parameters.morphTargets === true ) {
743

744 745
		// programs with morphTargets displace position out of attribute 0
		gl.bindAttribLocation( program, 0, 'position' );
746

747
	}
748

749
	gl.linkProgram( program );
M
Mr.doob 已提交
750

751 752
	// check for link errors
	if ( renderer.debug.checkShaderErrors ) {
753

754 755 756
		var programLog = gl.getProgramInfoLog( program ).trim();
		var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
		var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
757

758 759
		var runnable = true;
		var haveDiagnostics = true;
760

761
		if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
762

763
			runnable = false;
764

A
aardgoose 已提交
765 766
			var vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
			var fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
A
aardgoose 已提交
767

A
aardgoose 已提交
768
			console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexErrors, fragmentErrors );
769

770
		} else if ( programLog !== '' ) {
771

772
			console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
773

774
		} else if ( vertexLog === '' || fragmentLog === '' ) {
775

776 777 778
			haveDiagnostics = false;

		}
779

780
		if ( haveDiagnostics ) {
781

782
			this.diagnostics = {
783

784 785
				runnable: runnable,
				material: material,
786

787
				programLog: programLog,
788

789
				vertexShader: {
790

791 792
					log: vertexLog,
					prefix: prefixVertex
793

794
				},
795

796
				fragmentShader: {
797

798 799
					log: fragmentLog,
					prefix: prefixFragment
800

801
				}
M
Mr.doob 已提交
802

803 804 805
			};

		}
M
Mr.doob 已提交
806

807
	}
808

809
	// clean up
810

811 812
	gl.deleteShader( glVertexShader );
	gl.deleteShader( glFragmentShader );
813

814
	// set up caching for uniform locations
815

816
	var cachedUniforms;
817

818
	this.getUniforms = function () {
819

820
		if ( cachedUniforms === undefined ) {
821

822
			cachedUniforms = new WebGLUniforms( gl, program );
823

824
		}
825

826
		return cachedUniforms;
827

828
	};
829

830
	// set up caching for attribute locations
831

832
	var cachedAttributes;
833

834
	this.getAttributes = function () {
835

836
		if ( cachedAttributes === undefined ) {
837

838
			cachedAttributes = fetchAttributeLocations( gl, program );
839

840
		}
841

842
		return cachedAttributes;
843

844
	};
845

846
	// free resource
847

M
Mugen87 已提交
848
	this.destroy = function () {
849

850 851
		gl.deleteProgram( program );
		this.program = undefined;
852

853
	};
854

855 856
	//

W
WestLangley 已提交
857
	this.name = shader.name;
858 859 860 861 862 863
	this.id = programIdCount ++;
	this.code = code;
	this.usedTimes = 1;
	this.program = program;
	this.vertexShader = glVertexShader;
	this.fragmentShader = glFragmentShader;
864
	this.numMultiviewViews = numMultiviewViews;
865

866
	return this;
R
Rich Harris 已提交
867

868
}
R
Rich Harris 已提交
869

870
export { WebGLProgram };