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

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

10 11 12 13 14 15 16
var programIdCount = 0;

function getEncodingComponents( encoding ) {

	switch ( encoding ) {

		case LinearEncoding:
M
Mugen87 已提交
17
			return [ 'Linear', '( value )' ];
18
		case sRGBEncoding:
M
Mugen87 已提交
19
			return [ 'sRGB', '( value )' ];
20
		case RGBEEncoding:
M
Mugen87 已提交
21
			return [ 'RGBE', '( value )' ];
22
		case RGBM7Encoding:
M
Mugen87 已提交
23
			return [ 'RGBM', '( value, 7.0 )' ];
24
		case RGBM16Encoding:
M
Mugen87 已提交
25
			return [ 'RGBM', '( value, 16.0 )' ];
26
		case RGBDEncoding:
M
Mugen87 已提交
27
			return [ 'RGBD', '( value, 256.0 )' ];
28
		case GammaEncoding:
M
Mugen87 已提交
29
			return [ 'Gamma', '( value, float( GAMMA_FACTOR ) )' ];
30 31
		default:
			throw new Error( 'unsupported encoding: ' + encoding );
32

33 34
	}

35
}
36

37
function getTexelDecodingFunction( functionName, encoding ) {
38

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

42
}
43

44
function getTexelEncodingFunction( functionName, encoding ) {
45

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

49
}
B
Ben Houston 已提交
50

51
function getToneMappingFunction( functionName, toneMapping ) {
M
Mr.doob 已提交
52

53
	var toneMappingName;
M
Mr.doob 已提交
54

55
	switch ( toneMapping ) {
M
Mr.doob 已提交
56

57
		case LinearToneMapping:
M
Mr.doob 已提交
58
			toneMappingName = 'Linear';
59
			break;
M
Mr.doob 已提交
60

61
		case ReinhardToneMapping:
M
Mr.doob 已提交
62
			toneMappingName = 'Reinhard';
63
			break;
M
Mr.doob 已提交
64

65
		case Uncharted2ToneMapping:
M
Mr.doob 已提交
66
			toneMappingName = 'Uncharted2';
67
			break;
B
Ben Houston 已提交
68

69
		case CineonToneMapping:
M
Mr.doob 已提交
70
			toneMappingName = 'OptimizedCineon';
71
			break;
M
Mr.doob 已提交
72

73 74
		default:
			throw new Error( 'unsupported toneMapping: ' + toneMapping );
B
Ben Houston 已提交
75 76 77

	}

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

80
}
81

82
function generateExtensions( extensions, parameters, rendererExtensions ) {
83

84
	extensions = extensions || {};
85

86
	var chunks = [
W
WestLangley 已提交
87
		( extensions.derivatives || parameters.envMapCubeUV || parameters.bumpMap || ( parameters.normalMap && ! parameters.objectSpaceNormalMap ) || parameters.flatShading ) ? '#extension GL_OES_standard_derivatives : enable' : '',
88 89
		( 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' : '',
90
		( extensions.shaderTextureLOD || parameters.envMap ) && rendererExtensions.get( 'EXT_shader_texture_lod' ) ? '#extension GL_EXT_shader_texture_lod : enable' : ''
91
	];
92

93
	return chunks.filter( filterEmptyLine ).join( '\n' );
94

95
}
96

97
function generateDefines( defines ) {
98

99
	var chunks = [];
100

101
	for ( var name in defines ) {
102

103
		var value = defines[ name ];
104

105
		if ( value === false ) continue;
106

107
		chunks.push( '#define ' + name + ' ' + value );
108

M
Mr.doob 已提交
109
	}
110

111
	return chunks.join( '\n' );
112

113
}
114

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

117
	var attributes = {};
118

119
	var n = gl.getProgramParameter( program, gl.ACTIVE_ATTRIBUTES );
120

121
	for ( var i = 0; i < n; i ++ ) {
122

123 124
		var info = gl.getActiveAttrib( program, i );
		var name = info.name;
125

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

128
		attributes[ name ] = gl.getAttribLocation( program, name );
129

M
Mr.doob 已提交
130
	}
131

132
	return attributes;
133

134
}
M
Mr.doob 已提交
135

136
function filterEmptyLine( string ) {
137

138
	return string !== '';
139

140
}
141

142
function replaceLightNums( string, parameters ) {
143

144 145 146
	return string
		.replace( /NUM_DIR_LIGHTS/g, parameters.numDirLights )
		.replace( /NUM_SPOT_LIGHTS/g, parameters.numSpotLights )
147
		.replace( /NUM_RECT_AREA_LIGHTS/g, parameters.numRectAreaLights )
148 149
		.replace( /NUM_POINT_LIGHTS/g, parameters.numPointLights )
		.replace( /NUM_HEMI_LIGHTS/g, parameters.numHemiLights );
M
Mr.doob 已提交
150

151
}
M
Mr.doob 已提交
152

153 154 155 156 157 158 159 160
function replaceClippingPlaneNums( string, parameters ) {

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

}

161
function parseIncludes( string ) {
M
Mr.doob 已提交
162

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

165
	function replace( match, include ) {
166

167
		var replace = ShaderChunk[ include ];
168

169
		if ( replace === undefined ) {
170

171
			throw new Error( 'Can not resolve #include <' + include + '>' );
M
Mr.doob 已提交
172 173 174

		}

175
		return parseIncludes( replace );
M
Mr.doob 已提交
176 177 178

	}

179
	return string.replace( pattern, replace );
M
Mr.doob 已提交
180

181
}
M
Mr.doob 已提交
182

183
function unrollLoops( string ) {
M
Mr.doob 已提交
184

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

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

189
		var unroll = '';
M
Mr.doob 已提交
190

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

193
			unroll += snippet.replace( /\[ i \]/g, '[ ' + i + ' ]' );
M
Mr.doob 已提交
194 195 196

		}

197
		return unroll;
M
Mr.doob 已提交
198 199 200

	}

201
	return string.replace( pattern, replace );
202

203
}
204

T
Takahiro 已提交
205
function WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities ) {
206

207
	var gl = renderer.context;
208

209
	var defines = material.defines;
210

211 212
	var vertexShader = shader.vertexShader;
	var fragmentShader = shader.fragmentShader;
213

214
	var shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC';
215

216
	if ( parameters.shadowMapType === PCFShadowMap ) {
217

218
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF';
219

220
	} else if ( parameters.shadowMapType === PCFSoftShadowMap ) {
221

222
		shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT';
223

224
	}
225

226 227 228
	var envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
	var envMapModeDefine = 'ENVMAP_MODE_REFLECTION';
	var envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
229

230
	if ( parameters.envMap ) {
B
Ben Houston 已提交
231

232
		switch ( material.envMap.mapping ) {
233

234 235 236 237
			case CubeReflectionMapping:
			case CubeRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE';
				break;
238

239 240 241 242
			case CubeUVReflectionMapping:
			case CubeUVRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV';
				break;
243

244 245 246 247
			case EquirectangularReflectionMapping:
			case EquirectangularRefractionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_EQUIREC';
				break;
M
Mr.doob 已提交
248

249 250 251
			case SphericalReflectionMapping:
				envMapTypeDefine = 'ENVMAP_TYPE_SPHERE';
				break;
M
Mr.doob 已提交
252

253
		}
M
Mr.doob 已提交
254

255
		switch ( material.envMap.mapping ) {
256

257 258 259 260
			case CubeRefractionMapping:
			case EquirectangularRefractionMapping:
				envMapModeDefine = 'ENVMAP_MODE_REFRACTION';
				break;
261

262
		}
263

264
		switch ( material.combine ) {
265

266 267 268
			case MultiplyOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY';
				break;
269

270 271 272
			case MixOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_MIX';
				break;
273

274 275 276
			case AddOperation:
				envMapBlendingDefine = 'ENVMAP_BLENDING_ADD';
				break;
277

278
		}
279

280
	}
281

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

284
	// console.log( 'building new program ' );
285

286
	//
287

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

290
	var customDefines = generateDefines( defines );
291

292
	//
293

294
	var program = gl.createProgram();
295

296
	var prefixVertex, prefixFragment;
297

M
Mr.doob 已提交
298
	if ( material.isRawShaderMaterial ) {
299

300
		prefixVertex = [
301

302
			customDefines
303

304
		].filter( filterEmptyLine ).join( '\n' );
305

306 307 308 309 310 311
		if ( prefixVertex.length > 0 ) {

			prefixVertex += '\n';

		}

312
		prefixFragment = [
313

314
			customExtensions,
315
			customDefines
316

317
		].filter( filterEmptyLine ).join( '\n' );
318

319 320 321 322 323 324
		if ( prefixFragment.length > 0 ) {

			prefixFragment += '\n';

		}

325
	} else {
326

327
		prefixVertex = [
328

329 330
			'precision ' + parameters.precision + ' float;',
			'precision ' + parameters.precision + ' int;',
331

332
			'#define SHADER_NAME ' + shader.name,
333

334
			customDefines,
335

336
			parameters.supportsVertexTextures ? '#define VERTEX_TEXTURES' : '',
337

338
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
339

340
			'#define MAX_BONES ' + parameters.maxBones,
341 342 343
			( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
			( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',

344 345 346 347 348 349 350 351
			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 已提交
352
			( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
353 354 355 356 357 358
			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' : '',
			parameters.vertexColors ? '#define USE_COLOR' : '',
359

360
			parameters.flatShading ? '#define FLAT_SHADED' : '',
T
tschw 已提交
361

362 363
			parameters.skinning ? '#define USE_SKINNING' : '',
			parameters.useVertexTexture ? '#define BONE_TEXTURE' : '',
364

365 366 367 368
			parameters.morphTargets ? '#define USE_MORPHTARGETS' : '',
			parameters.morphNormals && parameters.flatShading === false ? '#define USE_MORPHNORMALS' : '',
			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
			parameters.flipSided ? '#define FLIP_SIDED' : '',
369

370 371
			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
372

373
			parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',
374

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

378 379 380 381 382 383
			'uniform mat4 modelMatrix;',
			'uniform mat4 modelViewMatrix;',
			'uniform mat4 projectionMatrix;',
			'uniform mat4 viewMatrix;',
			'uniform mat3 normalMatrix;',
			'uniform vec3 cameraPosition;',
384

385 386 387
			'attribute vec3 position;',
			'attribute vec3 normal;',
			'attribute vec2 uv;',
388

389
			'#ifdef USE_COLOR',
390

391
			'	attribute vec3 color;',
392

393
			'#endif',
394

395
			'#ifdef USE_MORPHTARGETS',
396

397 398 399 400
			'	attribute vec3 morphTarget0;',
			'	attribute vec3 morphTarget1;',
			'	attribute vec3 morphTarget2;',
			'	attribute vec3 morphTarget3;',
401

402
			'	#ifdef USE_MORPHNORMALS',
403

404 405 406 407
			'		attribute vec3 morphNormal0;',
			'		attribute vec3 morphNormal1;',
			'		attribute vec3 morphNormal2;',
			'		attribute vec3 morphNormal3;',
408

409
			'	#else',
410

411 412 413 414
			'		attribute vec3 morphTarget4;',
			'		attribute vec3 morphTarget5;',
			'		attribute vec3 morphTarget6;',
			'		attribute vec3 morphTarget7;',
415

416
			'	#endif',
417

418
			'#endif',
419

420
			'#ifdef USE_SKINNING',
421

422 423
			'	attribute vec4 skinIndex;',
			'	attribute vec4 skinWeight;',
424

425
			'#endif',
426

427
			'\n'
W
WestLangley 已提交
428

429
		].filter( filterEmptyLine ).join( '\n' );
430

431
		prefixFragment = [
432

433
			customExtensions,
434

435 436
			'precision ' + parameters.precision + ' float;',
			'precision ' + parameters.precision + ' int;',
437

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

440
			customDefines,
441

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

444
			'#define GAMMA_FACTOR ' + gammaFactorDefine,
445

446 447
			( parameters.useFog && parameters.fog ) ? '#define USE_FOG' : '',
			( parameters.useFog && parameters.fogExp ) ? '#define FOG_EXP2' : '',
448

449 450 451 452 453 454 455 456 457 458
			parameters.map ? '#define USE_MAP' : '',
			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 已提交
459
			( parameters.normalMap && parameters.objectSpaceNormalMap ) ? '#define OBJECTSPACE_NORMALMAP' : '',
460 461 462 463 464
			parameters.specularMap ? '#define USE_SPECULARMAP' : '',
			parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '',
			parameters.metalnessMap ? '#define USE_METALNESSMAP' : '',
			parameters.alphaMap ? '#define USE_ALPHAMAP' : '',
			parameters.vertexColors ? '#define USE_COLOR' : '',
T
tschw 已提交
465

T
Takahiro 已提交
466
			parameters.gradientMap ? '#define USE_GRADIENTMAP' : '',
T
Takahiro 已提交
467

468
			parameters.flatShading ? '#define FLAT_SHADED' : '',
469

470 471
			parameters.doubleSided ? '#define DOUBLE_SIDED' : '',
			parameters.flipSided ? '#define FLIP_SIDED' : '',
472

473 474
			parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '',
			parameters.shadowMapEnabled ? '#define ' + shadowMapTypeDefine : '',
475

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

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

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

T
Takahiro 已提交
483
			parameters.envMap && ( capabilities.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '',
484

485 486
			'uniform mat4 viewMatrix;',
			'uniform vec3 cameraPosition;',
487

M
Mr.doob 已提交
488
			( parameters.toneMapping !== NoToneMapping ) ? '#define TONE_MAPPING' : '',
M
Mugen87 已提交
489
			( 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 已提交
490
			( parameters.toneMapping !== NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '',
491

492
			parameters.dithering ? '#define DITHERING' : '',
493

W
WestLangley 已提交
494 495
			( 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
496
			parameters.mapEncoding ? getTexelDecodingFunction( 'mapTexelToLinear', parameters.mapEncoding ) : '',
W
WestLangley 已提交
497
			parameters.matcapEncoding ? getTexelDecodingFunction( 'matcapTexelToLinear', parameters.matcapEncoding ) : '',
498 499
			parameters.envMapEncoding ? getTexelDecodingFunction( 'envMapTexelToLinear', parameters.envMapEncoding ) : '',
			parameters.emissiveMapEncoding ? getTexelDecodingFunction( 'emissiveMapTexelToLinear', parameters.emissiveMapEncoding ) : '',
M
Mr.doob 已提交
500
			parameters.outputEncoding ? getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputEncoding ) : '',
501

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

504
			'\n'
M
Mr.doob 已提交
505

506
		].filter( filterEmptyLine ).join( '\n' );
507

508
	}
M
Mr.doob 已提交
509

M
Mr.doob 已提交
510
	vertexShader = parseIncludes( vertexShader );
511
	vertexShader = replaceLightNums( vertexShader, parameters );
512
	vertexShader = replaceClippingPlaneNums( vertexShader, parameters );
513

M
Mr.doob 已提交
514
	fragmentShader = parseIncludes( fragmentShader );
515
	fragmentShader = replaceLightNums( fragmentShader, parameters );
516
	fragmentShader = replaceClippingPlaneNums( fragmentShader, parameters );
517

518 519
	vertexShader = unrollLoops( vertexShader );
	fragmentShader = unrollLoops( fragmentShader );
520

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

523 524 525 526 527 528 529 530 531 532 533 534 535 536
		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 已提交
537

T
Takahiro 已提交
538
		// GLSL 3.0 conversion
T
Takahiro 已提交
539 540
		prefixVertex = [
			'#version 300 es\n',
T
Takahiro 已提交
541 542 543
			'#define attribute in',
			'#define varying out',
			'#define texture2D texture'
T
Takahiro 已提交
544
		].join( '\n' ) + '\n' + prefixVertex;
T
Takahiro 已提交
545

T
Takahiro 已提交
546 547
		prefixFragment = [
			'#version 300 es\n',
T
Takahiro 已提交
548
			'#define varying in',
T
Takahiro 已提交
549 550
			isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;',
			isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor',
T
Takahiro 已提交
551
			'#define gl_FragDepthEXT gl_FragDepth',
T
Takahiro 已提交
552 553 554 555 556 557 558 559 560
			'#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 已提交
561
		].join( '\n' ) + '\n' + prefixFragment;
T
Takahiro 已提交
562 563 564

	}

565 566
	var vertexGlsl = prefixVertex + vertexShader;
	var fragmentGlsl = prefixFragment + fragmentShader;
567

568 569
	// console.log( '*VERTEX*', vertexGlsl );
	// console.log( '*FRAGMENT*', fragmentGlsl );
570

571 572
	var glVertexShader = WebGLShader( gl, gl.VERTEX_SHADER, vertexGlsl );
	var glFragmentShader = WebGLShader( gl, gl.FRAGMENT_SHADER, fragmentGlsl );
573

574 575
	gl.attachShader( program, glVertexShader );
	gl.attachShader( program, glFragmentShader );
576

577
	// Force a particular attribute to index 0.
578

579
	if ( material.index0AttributeName !== undefined ) {
580

581
		gl.bindAttribLocation( program, 0, material.index0AttributeName );
582

583
	} else if ( parameters.morphTargets === true ) {
584

585 586
		// programs with morphTargets displace position out of attribute 0
		gl.bindAttribLocation( program, 0, 'position' );
587

588
	}
589

590
	gl.linkProgram( program );
M
Mr.doob 已提交
591

M
Mugen87 已提交
592 593 594
	var programLog = gl.getProgramInfoLog( program ).trim();
	var vertexLog = gl.getShaderInfoLog( glVertexShader ).trim();
	var fragmentLog = gl.getShaderInfoLog( glFragmentShader ).trim();
595

596 597
	var runnable = true;
	var haveDiagnostics = true;
598

599 600
	// console.log( '**VERTEX**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glVertexShader ) );
	// console.log( '**FRAGMENT**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( glFragmentShader ) );
601

602
	if ( gl.getProgramParameter( program, gl.LINK_STATUS ) === false ) {
603

604
		runnable = false;
605

606
		console.error( 'THREE.WebGLProgram: shader error: ', gl.getError(), 'gl.VALIDATE_STATUS', gl.getProgramParameter( program, gl.VALIDATE_STATUS ), 'gl.getProgramInfoLog', programLog, vertexLog, fragmentLog );
607

608
	} else if ( programLog !== '' ) {
609

610
		console.warn( 'THREE.WebGLProgram: gl.getProgramInfoLog()', programLog );
611

612
	} else if ( vertexLog === '' || fragmentLog === '' ) {
613

614
		haveDiagnostics = false;
615

616
	}
617

618
	if ( haveDiagnostics ) {
619

620
		this.diagnostics = {
621

622 623
			runnable: runnable,
			material: material,
624

625
			programLog: programLog,
626

627
			vertexShader: {
628

629 630
				log: vertexLog,
				prefix: prefixVertex
631

632
			},
633

634
			fragmentShader: {
635

636 637
				log: fragmentLog,
				prefix: prefixFragment
638

639
			}
M
Mr.doob 已提交
640

641
		};
M
Mr.doob 已提交
642

643
	}
644

645
	// clean up
646

647 648
	gl.deleteShader( glVertexShader );
	gl.deleteShader( glFragmentShader );
649

650
	// set up caching for uniform locations
651

652
	var cachedUniforms;
653

654
	this.getUniforms = function () {
655

656
		if ( cachedUniforms === undefined ) {
657

658
			cachedUniforms = new WebGLUniforms( gl, program, renderer );
659

660
		}
661

662
		return cachedUniforms;
663

664
	};
665

666
	// set up caching for attribute locations
667

668
	var cachedAttributes;
669

670
	this.getAttributes = function () {
671

672
		if ( cachedAttributes === undefined ) {
673

674
			cachedAttributes = fetchAttributeLocations( gl, program );
675

676
		}
677

678
		return cachedAttributes;
679

680
	};
681

682
	// free resource
683

M
Mugen87 已提交
684
	this.destroy = function () {
685

686 687
		gl.deleteProgram( program );
		this.program = undefined;
688

689
	};
690

691
	// DEPRECATED
692

693
	Object.defineProperties( this, {
694

695
		uniforms: {
M
Mugen87 已提交
696
			get: function () {
697

698 699
				console.warn( 'THREE.WebGLProgram: .uniforms is now .getUniforms().' );
				return this.getUniforms();
700 701

			}
702
		},
M
Mr.doob 已提交
703

704
		attributes: {
M
Mugen87 已提交
705
			get: function () {
706

707 708
				console.warn( 'THREE.WebGLProgram: .attributes is now .getAttributes().' );
				return this.getAttributes();
709

710 711
			}
		}
712

713
	} );
714 715


716 717
	//

W
WestLangley 已提交
718
	this.name = shader.name;
719 720 721 722 723 724
	this.id = programIdCount ++;
	this.code = code;
	this.usedTimes = 1;
	this.program = program;
	this.vertexShader = glVertexShader;
	this.fragmentShader = glFragmentShader;
725

726
	return this;
R
Rich Harris 已提交
727

728
}
R
Rich Harris 已提交
729

730
export { WebGLProgram };