WebGLProgram.js 22.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
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

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

248
	var gl = renderer.getContext();
249

250
	var defines = material.defines;
251

252 253
	var vertexShader = shader.vertexShader;
	var fragmentShader = shader.fragmentShader;
254

255
	var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
256

257
	if ( parameters.shadowMapType === PCFShadowMap ) {
258

259
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
260

261
	} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
262

263
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
264

S
supereggbert 已提交
265 266 267 268
	} else if ( parameters.shadowMapType === VSMShadowMap ) {

		shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM';

269
	}
270

271 272 273
	var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
	var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
	var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
274

275
	if ( parameters.envMap ) {
B
Ben Houston 已提交
276

277
		switch ( material.envMap.mapping ) {
278

279 280 281 282
			case CubeReflectionMapping:
			case CubeRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
				break;
283

284 285 286 287
			case CubeUVReflectionMapping:
			case CubeUVRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
				break;
288

289 290 291 292
			case EquirectangularReflectionMapping:
			case EquirectangularRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
				break;
M
Mr.doob 已提交
293

294 295 296
			case SphericalReflectionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
				break;
M
Mr.doob 已提交
297

298
		}
M
Mr.doob 已提交
299

300
		switch ( material.envMap.mapping ) {
301

302 303 304 305
			case CubeRefractionMapping:
			case EquirectangularRefractionMapping:
				envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
				break;
306

307
		}
308

309
		switch ( material.combine ) {
310

311 312 313
			case MultiplyOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
				break;
314

315 316 317
			case MixOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
				break;
318

319 320 321
			case AddOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
				break;
322

323
		}
324

325
	}
326

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

329
	// console.log( 'building new program ' );
330

331
	//
332

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

335
	var customDefines = generateDefines( defines );
336

337
	//
338

339
	var program = gl.createProgram();
340

341
	var prefixVertex, prefixFragment;
342

M
Mr.doob 已提交
343
	if ( material.isRawShaderMaterial ) {
344

345
		prefixVertex = [
346

347
			customDefines
348

349
		].filter( filterEmptyLine ).join( '\n' );
350

351 352 353 354 355 356
		if ( prefixVertex.length > 0 ) {

			prefixVertex += '\n';

		}

357
		prefixFragment = [
358

359
			customExtensions,
360
			customDefines
361

362
		].filter( filterEmptyLine ).join( '\n' );
363

364 365 366 367 368 369
		if ( prefixFragment.length > 0 ) {

			prefixFragment += '\n';

		}

370
	} else {
371

372
		prefixVertex = [
373

374 375
			'precision ' + parameters.precision + ' float;',
			'precision ' + parameters.precision + ' int;',
376

W
WestLangley 已提交
377 378
			( parameters.precision === 'highp' ) ? '#define HIGH_PRECISION' : '',

379
			'#define SHADER_NAME ' + shader.name,
380

381
			customDefines,
382

383
			parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
384

385
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
386

387
			'#define MAX_BONES ' + parameters.maxBones,
388
			( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
E
Elias Hasle 已提交
389
			( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
390

391 392 393 394 395 396 397 398
			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 已提交
399
			( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
400
			( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
A
arobertson0 已提交
401

402
			parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
403 404 405 406 407
			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 已提交
408 409

			parameters.vertexTangents ? '#define USE_TANGENT' : '',
410
			parameters.vertexColors ? '#define USE_COLOR' : '',
411
			parameters.vertexUvs ? '#define USE_UV' : '',
412

413
			parameters.flatShading ? '#define FLAT_SHADED' : '',
T
tschw 已提交
414

415 416
			parameters.skinning ? '#define USE_SKINNING' : '',
			parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
417

418 419 420 421
			parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
			parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
			parameters.flipSided ? '#define FLIP_SIDED' : '',
422

423 424
			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
425

426
			parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
427

428
			parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
T
Takahiro 已提交
429
			parameters.logarithmicDepthBuffer && ( capabilities.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
430 431
			'uniform mat4 modelMatrix;',
			'uniform vec3 cameraPosition;',
432

433
			material.supportsMultiview && renderer.multiview.isEnabled() ? [
434 435 436
				'uniform mat4 modelViewMatrix;',
				'uniform mat3 normalMatrix;',
				'uniform mat4 viewMatrices[2];',
437 438
				'uniform mat4 projectionMatrices[2];',

439 440 441 442 443 444 445 446 447 448 449 450
				'#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' ),

451 452 453
			'attribute vec3 position;',
			'attribute vec3 normal;',
			'attribute vec2 uv;',
454

D
Don McCurdy 已提交
455 456 457 458 459 460
			'#ifdef USE_TANGENT',

			'	attribute vec4 tangent;',

			'#endif',

461
			'#ifdef USE_COLOR',
462

463
			'	attribute vec3 color;',
464

465
			'#endif',
466

467
			'#ifdef USE_MORPHTARGETS',
468

469 470 471 472
			'	attribute vec3 morphTarget0;',
			'	attribute vec3 morphTarget1;',
			'	attribute vec3 morphTarget2;',
			'	attribute vec3 morphTarget3;',
473

474
			'	#ifdef USE_MORPHNORMALS',
475

476 477 478 479
			'		attribute vec3 morphNormal0;',
			'		attribute vec3 morphNormal1;',
			'		attribute vec3 morphNormal2;',
			'		attribute vec3 morphNormal3;',
480

481
			'	#else',
482

483 484 485 486
			'		attribute vec3 morphTarget4;',
			'		attribute vec3 morphTarget5;',
			'		attribute vec3 morphTarget6;',
			'		attribute vec3 morphTarget7;',
487

488
			'	#endif',
489

490
			'#endif',
491

492
			'#ifdef USE_SKINNING',
493

494 495
			'	attribute vec4 skinIndex;',
			'	attribute vec4 skinWeight;',
496

497
			'#endif',
498

499
			'\n'
W
WestLangley 已提交
500

501
		].filter( filterEmptyLine ).join( '\n' );
502

503
		prefixFragment = [
504

505
			customExtensions,
506

507 508
			'precision ' + parameters.precision + ' float;',
			'precision ' + parameters.precision + ' int;',
509

W
WestLangley 已提交
510 511
			( parameters.precision === 'highp' ) ? '#define HIGH_PRECISION' : '',

512
			'#define SHADER_NAME ' + shader.name,
513

514
			customDefines,
515

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

518
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
519

520
			( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
E
Elias Hasle 已提交
521
			( parameters.useFog && parameters.fogExp2 ) ? '#define FOG_EXP2' : '',
522

523
			parameters.map ? '#define USE_MAP' : '',
524
			parameters.matcap ? '#define USE_MATCAP' : '',
525 526 527 528 529 530 531 532 533
			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 已提交
534
			( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
535
			( parameters.normalMap && parameters.tangentSpaceNormalMap ) ? '#define TANGENTSPACE_NORMALMAP' : '',
536
			parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '',
537 538 539 540
			parameters.specularMap ? '#define USE_SPECULARMAP' : '',
			parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
			parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
D
Don McCurdy 已提交
541

542 543
			parameters.sheen ? '#define USE_SHEEN' : '',

D
Don McCurdy 已提交
544
			parameters.vertexTangents ? '#define USE_TANGENT' : '',
545
			parameters.vertexColors ? '#define USE_COLOR' : '',
546
			parameters.vertexUvs ? '#define USE_UV' : '',
T
tschw 已提交
547

T
Takahiro 已提交
548
			parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
T
Takahiro 已提交
549

550
			parameters.flatShading ? '#define FLAT_SHADED' : '',
551

552 553
			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
			parameters.flipSided ? '#define FLIP_SIDED' : '',
554

555 556
			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
557

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

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

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

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

567
			'uniform vec3 cameraPosition;',
568

569
			material.supportsMultiview && renderer.multiview.isEnabled() ? [
570 571 572 573 574 575

				'uniform mat4 viewMatrices[2];',
				'#define viewMatrix viewMatrices[VIEW_ID]'

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

M
Mr.doob 已提交
576
			( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '',
M
Mugen87 已提交
577
			( 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 已提交
578
			( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '',
579

580
			parameters.dithering ? '#define DITHERING' : '',
581

W
WestLangley 已提交
582 583
			( 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
584
			parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
W
WestLangley 已提交
585
			parameters.matcapEncoding ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '',
586 587
			parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
			parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
M
Mr.doob 已提交
588
			parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '',
589

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

592
			'\n'
M
Mr.doob 已提交
593

594
		].filter( filterEmptyLine ).join( '\n' );
595

596
	}
M
Mr.doob 已提交
597

M
Mr.doob 已提交
598
	vertexShader = parseIncludes( vertexShader );
599
	vertexShader = replaceLightNums( vertexShader, parameters );
600
	vertexShader = replaceClippingPlaneNums( vertexShader, parameters );
601

M
Mr.doob 已提交
602
	fragmentShader = parseIncludes( fragmentShader );
603
	fragmentShader = replaceLightNums( fragmentShader, parameters );
604
	fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters );
605

606 607
	vertexShader = unrollLoops( vertexShader );
	fragmentShader = unrollLoops( fragmentShader );
608

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

611 612 613 614 615 616 617 618 619 620 621 622 623 624
		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 已提交
625

T
Takahiro 已提交
626
		// GLSL 3.0 conversion
T
Takahiro 已提交
627 628
		prefixVertex = [
			'#version 300 es\n',
629

630
			material.supportsMultiview && renderer.multiview.isEnabled() ? [
631 632 633 634 635 636 637

				'#extension GL_OVR_multiview2 : require',
				'layout(num_views = 2) in;',
				'#define VIEW_ID gl_ViewID_OVR'

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

T
Takahiro 已提交
638 639 640
			'#define attribute in',
			'#define varying out',
			'#define texture2D texture'
T
Takahiro 已提交
641
		].join( '\n' ) + '\n' + prefixVertex;
T
Takahiro 已提交
642

T
Takahiro 已提交
643 644
		prefixFragment = [
			'#version 300 es\n',
645
			material.supportsMultiview && renderer.multiview.isEnabled() ? [
646 647 648 649 650

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

			].join( '\n' ) : '',
T
Takahiro 已提交
651
			'#define varying in',
T
Takahiro 已提交
652 653
			isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;',
			isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor',
T
Takahiro 已提交
654
			'#define gl_FragDepthEXT gl_FragDepth',
T
Takahiro 已提交
655 656 657 658 659 660 661 662 663
			'#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 已提交
664
		].join( '\n' ) + '\n' + prefixFragment;
T
Takahiro 已提交
665 666 667

	}

668 669
	var vertexGlsl = prefixVertex + vertexShader;
	var fragmentGlsl = prefixFragment + fragmentShader;
670

671 672
	var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl, renderer.debug.checkShaderErrors );
	var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl, renderer.debug.checkShaderErrors );
673

674 675
	gl.attachShader( program, glVertexShader );
	gl.attachShader( program, glFragmentShader );
676

677
	// Force a particular attribute to index 0.
678

679
	if ( material.index0AttributeName !== undefined ) {
680

681
		gl.bindAttribLocation( program, 0, material.index0AttributeName );
682

683
	} else if ( parameters.morphTargets === true ) {
684

685 686
		// programs with morphTargets displace position out of attribute 0
		gl.bindAttribLocation( program, 0, 'position' );
687

688
	}
689

690
	gl.linkProgram( program );
M
Mr.doob 已提交
691

692 693
	// check for link errors
	if ( renderer.debug.checkShaderErrors ) {
694

695 696 697
		var programLog = gl.getProgramInfoLog( program ).trim();
		var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
		var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
698

699 700
		var runnable = true;
		var haveDiagnostics = true;
701

702
		if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
703

704
			runnable = false;
705

A
aardgoose 已提交
706 707
			var vertexErrors = getShaderErrors( gl, glVertexShader, 'vertex' );
			var fragmentErrors = getShaderErrors( gl, glFragmentShader, 'fragment' );
A
aardgoose 已提交
708

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

711
		} else if ( programLog !== '' ) {
712

713
			console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
714

715
		} else if ( vertexLog === '' || fragmentLog === '' ) {
716

717 718 719
			haveDiagnostics = false;

		}
720

721
		if ( haveDiagnostics ) {
722

723
			this.diagnostics = {
724

725 726
				runnable: runnable,
				material: material,
727

728
				programLog: programLog,
729

730
				vertexShader: {
731

732 733
					log: vertexLog,
					prefix: prefixVertex
734

735
				},
736

737
				fragmentShader: {
738

739 740
					log: fragmentLog,
					prefix: prefixFragment
741

742
				}
M
Mr.doob 已提交
743

744 745 746
			};

		}
M
Mr.doob 已提交
747

748
	}
749

750
	// clean up
751

752 753
	gl.deleteShader( glVertexShader );
	gl.deleteShader( glFragmentShader );
754

755
	// set up caching for uniform locations
756

757
	var cachedUniforms;
758

759
	this.getUniforms = function () {
760

761
		if ( cachedUniforms === undefined ) {
762

763
			cachedUniforms = new WebGLUniforms( gl, program );
764

765
		}
766

767
		return cachedUniforms;
768

769
	};
770

771
	// set up caching for attribute locations
772

773
	var cachedAttributes;
774

775
	this.getAttributes = function () {
776

777
		if ( cachedAttributes === undefined ) {
778

779
			cachedAttributes = fetchAttributeLocations( gl, program );
780

781
		}
782

783
		return cachedAttributes;
784

785
	};
786

787
	// free resource
788

M
Mugen87 已提交
789
	this.destroy = function () {
790

791 792
		gl.deleteProgram( program );
		this.program = undefined;
793

794
	};
795

796 797
	//

W
WestLangley 已提交
798
	this.name = shader.name;
799 800 801 802 803 804
	this.id = programIdCount ++;
	this.code = code;
	this.usedTimes = 1;
	this.program = program;
	this.vertexShader = glVertexShader;
	this.fragmentShader = glFragmentShader;
805

806
	return this;
R
Rich Harris 已提交
807

808
}
R
Rich Harris 已提交
809

810
export { WebGLProgram };