WebGLProgram.js 24.6 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
// Resolve Includes
M
Mr.doob 已提交
201

202
var includePattern = /^[ \t]*#include +<([\w\d./]+)>/gm;
203

204
function resolveIncludes( string ) {
205

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

208
}
209

210
function includeReplacer( match, include ) {
M
Mr.doob 已提交
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 resolveIncludes( string );
M
Mr.doob 已提交
221

222
}
M
Mr.doob 已提交
223

M
Mr.doob 已提交
224
// Unroll Loops
M
Mr.doob 已提交
225

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

M
Mr.doob 已提交
228
function unrollLoops( string ) {
M
Mr.doob 已提交
229

M
Mr.doob 已提交
230
	return string.replace( loopPattern, loopReplacer );
M
Mr.doob 已提交
231

M
Mr.doob 已提交
232
}
M
Mr.doob 已提交
233

M
Mr.doob 已提交
234
function loopReplacer( match, start, end, snippet ) {
M
Mr.doob 已提交
235

M
Mr.doob 已提交
236
	var string = '';
M
Mr.doob 已提交
237

M
Mr.doob 已提交
238 239 240 241 242
	for ( var i = parseInt( start ); i < parseInt( end ); i ++ ) {

		string += snippet
			.replace( /\[ i \]/g, '[ ' + i + ' ]' )
			.replace( /UNROLLED_LOOP_INDEX/g, i );
M
Mr.doob 已提交
243 244 245

	}

M
Mr.doob 已提交
246
	return string;
247

248
}
249

M
Mr.doob 已提交
250 251
//

G
gero3 已提交
252
function generatePrecision( parameters ) {
253

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

G
gero3 已提交
256
	if ( parameters.precision === "highp" ) {
257

258
		precisionstring += "\n#define HIGH_PRECISION";
G
gero3 已提交
259 260 261

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

262
		precisionstring += "\n#define MEDIUM_PRECISION";
G
gero3 已提交
263 264 265

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

266
		precisionstring += "\n#define LOW_PRECISION";
G
gero3 已提交
267 268 269 270 271 272 273 274

	}

	return precisionstring;

}

function generateShadowMapTypeDefine( parameters ) {
275

276
	var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
277

278
	if ( parameters.shadowMapType === PCFShadowMap ) {
279

280
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
281

282
	} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
283

284
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
285

S
supereggbert 已提交
286 287 288 289
	} else if ( parameters.shadowMapType === VSMShadowMap ) {

		shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';

290
	}
291

G
gero3 已提交
292 293 294 295
	return shadowMapTypeDefine;

}

G
gero3 已提交
296
function generateEnvMapTypeDefine( parameters ) {
G
gero3 已提交
297

298
	var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
299

300
	if ( parameters.envMap ) {
B
Ben Houston 已提交
301

G
gero3 已提交
302
		switch ( parameters.envMapMode ) {
303

304 305 306 307
			case CubeReflectionMapping:
			case CubeRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
				break;
308

309 310 311 312
			case CubeUVReflectionMapping:
			case CubeUVRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
				break;
313

314 315 316 317
			case EquirectangularReflectionMapping:
			case EquirectangularRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
				break;
M
Mr.doob 已提交
318

319 320 321
			case SphericalReflectionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
				break;
M
Mr.doob 已提交
322

323
		}
M
Mr.doob 已提交
324

G
gero3 已提交
325 326 327 328 329 330
	}

	return envMapTypeDefine;

}

G
gero3 已提交
331
function generateEnvMapModeDefine( parameters ) {
G
gero3 已提交
332 333 334 335 336

	var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';

	if ( parameters.envMap ) {

G
gero3 已提交
337
		switch ( parameters.envMapMode ) {
338

339 340 341 342
			case CubeRefractionMapping:
			case EquirectangularRefractionMapping:
				envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
				break;
343

344
		}
345

G
gero3 已提交
346 347 348 349 350 351
	}

	return envMapModeDefine;

}

G
gero3 已提交
352
function generateEnvMapBlendingDefine( parameters ) {
G
gero3 已提交
353

E
Emmett Lalish 已提交
354
	var envMapBlendingDefine = 'ENVMAP_BLENDING_NONE';
G
gero3 已提交
355 356 357

	if ( parameters.envMap ) {

G
gero3 已提交
358
		switch ( parameters.combine ) {
359

360 361 362
			case MultiplyOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
				break;
363

364 365 366
			case MixOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
				break;
367

368 369 370
			case AddOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
				break;
371

372
		}
373

374
	}
375

G
gero3 已提交
376 377 378 379
	return envMapBlendingDefine;

}

380
function WebGLProgram( renderer, extensions, cacheKey, material, shader, parameters ) {
G
gero3 已提交
381 382 383 384

	var gl = renderer.getContext();

	var defines = material.defines;
385

G
gero3 已提交
386 387 388
	var vertexShader = shader.vertexShader;
	var fragmentShader = shader.fragmentShader;
	var shadowMapTypeDefine = generateShadowMapTypeDefine( parameters );
G
gero3 已提交
389 390
	var envMapTypeDefine = generateEnvMapTypeDefine( parameters );
	var envMapModeDefine = generateEnvMapModeDefine( parameters );
G
gero3 已提交
391
	var envMapBlendingDefine = generateEnvMapBlendingDefine( parameters );
392

G
gero3 已提交
393 394

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

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

398
	var customDefines = generateDefines( defines );
399

400
	var program = gl.createProgram();
401

402
	var prefixVertex, prefixFragment;
403

M
Mr.doob 已提交
404 405
	var numMultiviewViews = parameters.numMultiviewViews;

M
Mr.doob 已提交
406
	if ( material.isRawShaderMaterial ) {
407

408
		prefixVertex = [
409

410
			customDefines
411

412
		].filter( filterEmptyLine ).join( '\n' );
413

414 415 416 417 418 419
		if ( prefixVertex.length > 0 ) {

			prefixVertex += '\n';

		}

420
		prefixFragment = [
421

422
			customExtensions,
423
			customDefines
424

425
		].filter( filterEmptyLine ).join( '\n' );
426

427 428 429 430 431 432
		if ( prefixFragment.length > 0 ) {

			prefixFragment += '\n';

		}

433
	} else {
434

435
		prefixVertex = [
436

G
gero3 已提交
437
			generatePrecision( parameters ),
W
WestLangley 已提交
438

439
			'#define SHADER_NAME ' + shader.name,
440

441
			customDefines,
442

M
Mr.doob 已提交
443
			parameters.instancing ? '#define USE_INSTANCING' : '',
444
			parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
445

446
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
447

448
			'#define MAX_BONES ' + parameters.maxBones,
449
			( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
E
Elias Hasle 已提交
450
			( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
451

452 453 454 455 456 457 458 459
			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 已提交
460
			( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
461
			( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
A
arobertson0 已提交
462

463
			parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
464 465 466 467 468
			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 已提交
469 470

			parameters.vertexTangents ? '#define USE_TANGENT' : '',
471
			parameters.vertexColors ? '#define USE_COLOR' : '',
472
			parameters.vertexUvs ? '#define USE_UV' : '',
473
			parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
474

475
			parameters.flatShading ? '#define FLAT_SHADED' : '',
T
tschw 已提交
476

477 478
			parameters.skinning ? '#define USE_SKINNING' : '',
			parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
479

480 481 482 483
			parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
			parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
			parameters.flipSided ? '#define FLIP_SIDED' : '',
484

485 486
			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
487

488
			parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
489

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

493
			'uniform mat4 modelMatrix;',
494 495 496 497
			'uniform mat4 modelViewMatrix;',
			'uniform mat4 projectionMatrix;',
			'uniform mat4 viewMatrix;',
			'uniform mat3 normalMatrix;',
498
			'uniform vec3 cameraPosition;',
499
			'uniform bool isOrthographic;',
500

M
Mr.doob 已提交
501 502 503 504 505 506
			'#ifdef USE_INSTANCING',

			' attribute mat4 instanceMatrix;',

			'#endif',

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

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

			'	attribute vec4 tangent;',

			'#endif',

517
			'#ifdef USE_COLOR',
518

519
			'	attribute vec3 color;',
520

521
			'#endif',
522

523
			'#ifdef USE_MORPHTARGETS',
524

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

530
			'	#ifdef USE_MORPHNORMALS',
531

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

537
			'	#else',
538

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

544
			'	#endif',
545

546
			'#endif',
547

548
			'#ifdef USE_SKINNING',
549

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

553
			'#endif',
554

555
			'\n'
W
WestLangley 已提交
556

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

559
		prefixFragment = [
560

561
			customExtensions,
562

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

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

567
			customDefines,
568

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

571
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
572

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

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

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

D
Don McCurdy 已提交
597
			parameters.vertexTangents ? '#define USE_TANGENT' : '',
598
			parameters.vertexColors ? '#define USE_COLOR' : '',
599
			parameters.vertexUvs ? '#define USE_UV' : '',
600
			parameters.uvsVertexOnly ? '#define UVS_VERTEX_ONLY' : '',
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' : '',
G
gero3 已提交
617
			parameters.logarithmicDepthBuffer && ( parameters.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
618

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

621
			'uniform mat4 viewMatrix;',
622
			'uniform vec3 cameraPosition;',
623
			'uniform bool isOrthographic;',
624

M
Mr.doob 已提交
625
			( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '',
M
Mugen87 已提交
626
			( 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 已提交
627
			( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '',
628

629
			parameters.dithering ? '#define DITHERING' : '',
630

631
			( parameters.outputEncoding || parameters.mapEncoding || parameters.matcapEncoding || parameters.envMapEncoding || parameters.emissiveMapEncoding || parameters.lightMapEncoding ) ?
W
WestLangley 已提交
632
				ShaderChunk[ 'encodings_pars_fragment' ] : '', // this code is required here because it is used by the various encoding/decoding function defined below
633
			parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
W
WestLangley 已提交
634
			parameters.matcapEncoding ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '',
635 636
			parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
			parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
637
			parameters.lightMapEncoding ? getTexelDecodingFunction( 'lightMapTexelToLinear', parameters.lightMapEncoding ) : '',
M
Mr.doob 已提交
638
			parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '',
639

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

642
			'\n'
M
Mr.doob 已提交
643

644
		].filter( filterEmptyLine ).join( '\n' );
645

646
	}
M
Mr.doob 已提交
647

648
	vertexShader = resolveIncludes( vertexShader );
649
	vertexShader = replaceLightNums( vertexShader, parameters );
650
	vertexShader = replaceClippingPlaneNums( vertexShader, parameters );
651

652
	fragmentShader = resolveIncludes( fragmentShader );
653
	fragmentShader = replaceLightNums( fragmentShader, parameters );
654
	fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters );
655

656 657
	vertexShader = unrollLoops( vertexShader );
	fragmentShader = unrollLoops( fragmentShader );
658

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

661 662 663 664 665 666 667 668 669 670 671 672 673 674
		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 已提交
675

T
Takahiro 已提交
676
		// GLSL 3.0 conversion
677

T
Takahiro 已提交
678 679
		prefixVertex = [
			'#version 300 es\n',
T
Takahiro 已提交
680 681 682
			'#define attribute in',
			'#define varying out',
			'#define texture2D texture'
T
Takahiro 已提交
683
		].join( '\n' ) + '\n' + prefixVertex;
T
Takahiro 已提交
684

T
Takahiro 已提交
685 686
		prefixFragment = [
			'#version 300 es\n',
T
Takahiro 已提交
687
			'#define varying in',
T
Takahiro 已提交
688 689
			isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;',
			isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor',
T
Takahiro 已提交
690
			'#define gl_FragDepthEXT gl_FragDepth',
T
Takahiro 已提交
691 692 693 694 695 696 697 698 699
			'#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 已提交
700
		].join( '\n' ) + '\n' + prefixFragment;
T
Takahiro 已提交
701

702 703
		// Multiview

M
Mr.doob 已提交
704
		if ( numMultiviewViews > 0 ) {
705 706 707 708 709 710

			prefixVertex = prefixVertex.replace(
				'#version 300 es\n',
				[
					'#version 300 es\n',
					'#extension GL_OVR_multiview2 : require',
M
Mr.doob 已提交
711
					'layout(num_views = ' + numMultiviewViews + ') in;',
712 713 714 715 716 717 718 719 720 721 722 723
					'#define VIEW_ID gl_ViewID_OVR'
				].join( '\n' )
			);

			prefixVertex = prefixVertex.replace(
				[
					'uniform mat4 modelViewMatrix;',
					'uniform mat4 projectionMatrix;',
					'uniform mat4 viewMatrix;',
					'uniform mat3 normalMatrix;'
				].join( '\n' ),
				[
M
Mr.doob 已提交
724 725 726 727
					'uniform mat4 modelViewMatrices[' + numMultiviewViews + '];',
					'uniform mat4 projectionMatrices[' + numMultiviewViews + '];',
					'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
					'uniform mat3 normalMatrices[' + numMultiviewViews + '];',
728 729

					'#define modelViewMatrix modelViewMatrices[VIEW_ID]',
M
Mr.doob 已提交
730
					'#define projectionMatrix projectionMatrices[VIEW_ID]',
731
					'#define viewMatrix viewMatrices[VIEW_ID]',
M
Mr.doob 已提交
732
					'#define normalMatrix normalMatrices[VIEW_ID]'
733 734 735 736 737 738 739 740 741 742 743 744 745 746 747
				].join( '\n' )
			);

			prefixFragment = prefixFragment.replace(
				'#version 300 es\n',
				[
					'#version 300 es\n',
					'#extension GL_OVR_multiview2 : require',
					'#define VIEW_ID gl_ViewID_OVR'
				].join( '\n' )
			);

			prefixFragment = prefixFragment.replace(
				'uniform mat4 viewMatrix;',
				[
M
Mr.doob 已提交
748
					'uniform mat4 viewMatrices[' + numMultiviewViews + '];',
749 750 751 752 753 754
					'#define viewMatrix viewMatrices[VIEW_ID]'
				].join( '\n' )
			);

		}

T
Takahiro 已提交
755 756
	}

757 758
	var vertexGlsl = prefixVertex + vertexShader;
	var fragmentGlsl = prefixFragment + fragmentShader;
759

760 761 762 763 764
	// console.log( '*VERTEX*', vertexGlsl );
	// console.log( '*FRAGMENT*', fragmentGlsl );

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

766 767
	gl.attachShader( program, glVertexShader );
	gl.attachShader( program, glFragmentShader );
768

769
	// Force a particular attribute to index 0.
770

771
	if ( material.index0AttributeName !== undefined ) {
772

773
		gl.bindAttribLocation( program, 0, material.index0AttributeName );
774

775
	} else if ( parameters.morphTargets === true ) {
776

777 778
		// programs with morphTargets displace position out of attribute 0
		gl.bindAttribLocation( program, 0, 'position' );
779

780
	}
781

782
	gl.linkProgram( program );
M
Mr.doob 已提交
783

784 785
	// check for link errors
	if ( renderer.debug.checkShaderErrors ) {
786

787 788 789
		var programLog = gl.getProgramInfoLog( program ).trim();
		var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
		var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
790

791 792
		var runnable = true;
		var haveDiagnostics = true;
793

794
		if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
795

796
			runnable = false;
797

A
aardgoose 已提交
798 799
			var vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
			var fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
A
aardgoose 已提交
800

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

803
		} else if ( programLog !== '' ) {
804

805
			console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
806

807
		} else if ( vertexLog === '' || fragmentLog === '' ) {
808

809 810 811
			haveDiagnostics = false;

		}
812

813
		if ( haveDiagnostics ) {
814

815
			this.diagnostics = {
816

817 818
				runnable: runnable,
				material: material,
819

820
				programLog: programLog,
821

822
				vertexShader: {
823

824 825
					log: vertexLog,
					prefix: prefixVertex
826

827
				},
828

829
				fragmentShader: {
830

831 832
					log: fragmentLog,
					prefix: prefixFragment
833

834
				}
M
Mr.doob 已提交
835

836 837 838
			};

		}
M
Mr.doob 已提交
839

840
	}
841

842
	// clean up
843

844 845
	gl.deleteShader( glVertexShader );
	gl.deleteShader( glFragmentShader );
846

847
	// set up caching for uniform locations
848

849
	var cachedUniforms;
850

851
	this.getUniforms = function () {
852

853
		if ( cachedUniforms === undefined ) {
854

855
			cachedUniforms = new WebGLUniforms( gl, program );
856

857
		}
858

859
		return cachedUniforms;
860

861
	};
862

863
	// set up caching for attribute locations
864

865
	var cachedAttributes;
866

867
	this.getAttributes = function () {
868

869
		if ( cachedAttributes === undefined ) {
870

871
			cachedAttributes = fetchAttributeLocations( gl, program );
872

873
		}
874

875
		return cachedAttributes;
876

877
	};
878

879
	// free resource
880

M
Mugen87 已提交
881
	this.destroy = function () {
882

883 884
		gl.deleteProgram( program );
		this.program = undefined;
885

886
	};
887

888 889
	//

W
WestLangley 已提交
890
	this.name = shader.name;
891
	this.id = programIdCount ++;
892
	this.cacheKey = cacheKey;
893 894 895 896
	this.usedTimes = 1;
	this.program = program;
	this.vertexShader = glVertexShader;
	this.fragmentShader = glFragmentShader;
M
Mr.doob 已提交
897
	this.numMultiviewViews = numMultiviewViews;
898

899
	return this;
R
Rich Harris 已提交
900

901
}
R
Rich Harris 已提交
902

903
export { WebGLProgram };