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
function parseIncludes( string ) {
M
Mr.doob 已提交
201

M
Mathieu Brédif 已提交
202
	var pattern = /^[ \t]*#include +<([\w\d./]+)>/gm;
203

204
	function replace( match, include ) {
205

206
		var replace = ShaderChunk[ include ];
207

208
		if ( replace === undefined ) {
209

210
			throw new Error( 'Can not resolve #include <' + include + '>' );
M
Mr.doob 已提交
211 212 213

		}

214
		return parseIncludes( replace );
M
Mr.doob 已提交
215 216 217

	}

218
	return string.replace( pattern, replace );
M
Mr.doob 已提交
219

220
}
M
Mr.doob 已提交
221

222
function unrollLoops( string ) {
M
Mr.doob 已提交
223

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

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

228
		var unroll = '';
M
Mr.doob 已提交
229

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

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

		}

238
		return unroll;
M
Mr.doob 已提交
239 240 241

	}

242
	return string.replace( pattern, replace );
243

244
}
245

G
gero3 已提交
246
function generatePrecision( parameters ) {
247

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

G
gero3 已提交
250
	if ( parameters.precision === "highp" ) {
251

G
gero3 已提交
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268
		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 ) {
269

270
	var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
271

272
	if ( parameters.shadowMapType === PCFShadowMap ) {
273

274
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
275

276
	} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
277

278
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
279

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

		shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';

284
	}
285

G
gero3 已提交
286 287 288 289 290 291
	return shadowMapTypeDefine;

}

function generateEnvMapTypeDefine( parameters, material ) {

292
	var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
293

294
	if ( parameters.envMap ) {
B
Ben Houston 已提交
295

296
		switch ( material.envMap.mapping ) {
297

298 299 300 301
			case CubeReflectionMapping:
			case CubeRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
				break;
302

303 304 305 306
			case CubeUVReflectionMapping:
			case CubeUVRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
				break;
307

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

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

317
		}
M
Mr.doob 已提交
318

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

	return envMapTypeDefine;

}

function generateEnvMapModeDefine( parameters, material ) {

	var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';

	if ( parameters.envMap ) {

331
		switch ( material.envMap.mapping ) {
332

333 334 335 336
			case CubeRefractionMapping:
			case EquirectangularRefractionMapping:
				envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
				break;
337

338
		}
339

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

	return envMapModeDefine;

}

function generateEnvMapBlendingDefine( parameters, material ) {

	var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';

	if ( parameters.envMap ) {

352
		switch ( material.combine ) {
353

354 355 356
			case MultiplyOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
				break;
357

358 359 360
			case MixOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
				break;
361

362 363 364
			case AddOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
				break;
365

366
		}
367

368
	}
369

G
gero3 已提交
370 371 372 373 374 375 376 377 378
	return envMapBlendingDefine;

}

function WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ) {

	var gl = renderer.getContext();

	var defines = material.defines;
379

G
gero3 已提交
380 381 382 383 384 385
	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 );
386

G
gero3 已提交
387 388

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

T
Takahiro 已提交
390
	var customExtensions = capabilities.isWebGL2 ? '' : generateExtensions( material.extensions, parameters, extensions );
391

392
	var customDefines = generateDefines( defines );
393

394
	var program = gl.createProgram();
395

396
	var prefixVertex, prefixFragment;
397

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

M
Mr.doob 已提交
401
	if ( material.isRawShaderMaterial ) {
402

403
		prefixVertex = [
404

405
			customDefines
406

407
		].filter( filterEmptyLine ).join( '\n' );
408

409 410 411 412 413 414
		if ( prefixVertex.length > 0 ) {

			prefixVertex += '\n';

		}

415
		prefixFragment = [
416

417
			customExtensions,
418
			customDefines
419

420
		].filter( filterEmptyLine ).join( '\n' );
421

422 423 424 425 426 427
		if ( prefixFragment.length > 0 ) {

			prefixFragment += '\n';

		}

428
	} else {
429

430
		prefixVertex = [
431

G
gero3 已提交
432
			generatePrecision( parameters ),
W
WestLangley 已提交
433

434
			'#define SHADER_NAME ' + shader.name,
435

436
			customDefines,
437

438
			parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
439

440
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
441

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

446 447 448 449 450 451 452 453
			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 已提交
454
			( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
455
			( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
A
arobertson0 已提交
456

457
			parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
458 459 460 461 462
			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 已提交
463 464

			parameters.vertexTangents ? '#define USE_TANGENT' : '',
465
			parameters.vertexColors ? '#define USE_COLOR' : '',
466
			parameters.vertexUvs ? '#define USE_UV' : '',
467

468
			parameters.flatShading ? '#define FLAT_SHADED' : '',
T
tschw 已提交
469

470 471
			parameters.skinning ? '#define USE_SKINNING' : '',
			parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
472

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

478 479
			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
480

481
			parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
482

483
			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
T
Takahiro 已提交
484
			parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
485 486
			'uniform mat4 modelMatrix;',
			'uniform vec3 cameraPosition;',
487

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

494 495
				'#define modelViewMatrix modelViewMatrices[VIEW_ID]',
				'#define normalMatrix normalMatrices[VIEW_ID]',
496 497 498 499 500 501 502 503 504 505 506 507
				'#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' ),

508 509 510
			'attribute vec3 position;',
			'attribute vec3 normal;',
			'attribute vec2 uv;',
511

D
Don McCurdy 已提交
512 513 514 515 516 517
			'#ifdef USE_TANGENT',

			'	attribute vec4 tangent;',

			'#endif',

518
			'#ifdef USE_COLOR',
519

520
			'	attribute vec3 color;',
521

522
			'#endif',
523

524
			'#ifdef USE_MORPHTARGETS',
525

526 527 528 529
			'	attribute vec3 morphTarget0;',
			'	attribute vec3 morphTarget1;',
			'	attribute vec3 morphTarget2;',
			'	attribute vec3 morphTarget3;',
530

531
			'	#ifdef USE_MORPHNORMALS',
532

533 534 535 536
			'		attribute vec3 morphNormal0;',
			'		attribute vec3 morphNormal1;',
			'		attribute vec3 morphNormal2;',
			'		attribute vec3 morphNormal3;',
537

538
			'	#else',
539

540 541 542 543
			'		attribute vec3 morphTarget4;',
			'		attribute vec3 morphTarget5;',
			'		attribute vec3 morphTarget6;',
			'		attribute vec3 morphTarget7;',
544

545
			'	#endif',
546

547
			'#endif',
548

549
			'#ifdef USE_SKINNING',
550

551 552
			'	attribute vec4 skinIndex;',
			'	attribute vec4 skinWeight;',
553

554
			'#endif',
555

556
			'\n'
W
WestLangley 已提交
557

558
		].filter( filterEmptyLine ).join( '\n' );
559

560
		prefixFragment = [
561

562
			customExtensions,
563

G
gero3 已提交
564
			generatePrecision( parameters ),
W
WestLangley 已提交
565

566
			'#define SHADER_NAME ' + shader.name,
567

568
			customDefines,
569

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

572
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
573

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

577
			parameters.map ? '#define USE_MAP' : '',
578
			parameters.matcap ? '#define USE_MATCAP' : '',
579 580 581 582 583 584 585 586 587
			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 已提交
588
			( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
589
			( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
590
			parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
591 592 593 594
			parameters.specularMap ? '#define USE_SPECULARMAP' : '',
			parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
			parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
D
Don McCurdy 已提交
595

596 597
			parameters.sheen ? '#define USE_SHEEN' : '',

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

T
Takahiro 已提交
602
			parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
T
Takahiro 已提交
603

604
			parameters.flatShading ? '#define FLAT_SHADED' : '',
605

606 607
			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
			parameters.flipSided ? '#define FLIP_SIDED' : '',
608

609 610
			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
611

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

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

616
			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
T
Takahiro 已提交
617
			parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
618

619
			( ( material.extensions ? material.extensions.shaderTextureLOD : false ) || parameters.envMap ) && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '',
620

621
			'uniform vec3 cameraPosition;',
622

623
			numMultiviewViews > 0 ? [
624

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

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

M
Mr.doob 已提交
630
			( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '',
M
Mugen87 已提交
631
			( 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 已提交
632
			( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '',
633

634
			parameters.dithering ? '#define DITHERING' : '',
635

W
WestLangley 已提交
636 637
			( 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
638
			parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
W
WestLangley 已提交
639
			parameters.matcapEncoding ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '',
640 641
			parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
			parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
M
Mr.doob 已提交
642
			parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '',
643

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

646
			'\n'
M
Mr.doob 已提交
647

648
		].filter( filterEmptyLine ).join( '\n' );
649

650
	}
M
Mr.doob 已提交
651

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

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

660 661
	vertexShader = unrollLoops( vertexShader );
	fragmentShader = unrollLoops( fragmentShader );
662

T
Takahiro 已提交
663
	if ( capabilities.isWebGL2 && ! material.isRawShaderMaterial ) {
T
Takahiro 已提交
664

665 666 667 668 669 670 671 672 673 674 675 676 677 678
		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 已提交
679

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

684
			numMultiviewViews > 0 ? [
685 686

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

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

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

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

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

			].join( '\n' ) : '',
T
Takahiro 已提交
705
			'#define varying in',
T
Takahiro 已提交
706 707
			isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;',
			isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor',
T
Takahiro 已提交
708
			'#define gl_FragDepthEXT gl_FragDepth',
T
Takahiro 已提交
709 710 711 712 713 714 715 716 717
			'#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 已提交
718
		].join( '\n' ) + '\n' + prefixFragment;
T
Takahiro 已提交
719 720 721

	}

722 723
	var vertexGlsl = prefixVertex + vertexShader;
	var fragmentGlsl = prefixFragment + fragmentShader;
724

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

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

731 732
	gl.attachShader( program, glVertexShader );
	gl.attachShader( program, glFragmentShader );
733

734
	// Force a particular attribute to index 0.
735

736
	if ( material.index0AttributeName !== undefined ) {
737

738
		gl.bindAttribLocation( program, 0, material.index0AttributeName );
739

740
	} else if ( parameters.morphTargets === true ) {
741

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

745
	}
746

747
	gl.linkProgram( program );
M
Mr.doob 已提交
748

749 750
	// check for link errors
	if ( renderer.debug.checkShaderErrors ) {
751

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

756 757
		var runnable = true;
		var haveDiagnostics = true;
758

759
		if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
760

761
			runnable = false;
762

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

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

768
		} else if ( programLog !== '' ) {
769

770
			console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
771

772
		} else if ( vertexLog === '' || fragmentLog === '' ) {
773

774 775 776
			haveDiagnostics = false;

		}
777

778
		if ( haveDiagnostics ) {
779

780
			this.diagnostics = {
781

782 783
				runnable: runnable,
				material: material,
784

785
				programLog: programLog,
786

787
				vertexShader: {
788

789 790
					log: vertexLog,
					prefix: prefixVertex
791

792
				},
793

794
				fragmentShader: {
795

796 797
					log: fragmentLog,
					prefix: prefixFragment
798

799
				}
M
Mr.doob 已提交
800

801 802 803
			};

		}
M
Mr.doob 已提交
804

805
	}
806

807
	// clean up
808

809 810
	gl.deleteShader( glVertexShader );
	gl.deleteShader( glFragmentShader );
811

812
	// set up caching for uniform locations
813

814
	var cachedUniforms;
815

816
	this.getUniforms = function () {
817

818
		if ( cachedUniforms === undefined ) {
819

820
			cachedUniforms = new WebGLUniforms( gl, program );
821

822
		}
823

824
		return cachedUniforms;
825

826
	};
827

828
	// set up caching for attribute locations
829

830
	var cachedAttributes;
831

832
	this.getAttributes = function () {
833

834
		if ( cachedAttributes === undefined ) {
835

836
			cachedAttributes = fetchAttributeLocations( gl, program );
837

838
		}
839

840
		return cachedAttributes;
841

842
	};
843

844
	// free resource
845

M
Mugen87 已提交
846
	this.destroy = function () {
847

848 849
		gl.deleteProgram( program );
		this.program = undefined;
850

851
	};
852

853 854
	//

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

864
	return this;
R
Rich Harris 已提交
865

866
}
R
Rich Harris 已提交
867

868
export { WebGLProgram };