WebGLPrograms.js 9.4 KB
Newer Older
M
Mr.doob 已提交
1 2 3 4
/**
 * @author mrdoob / http://mrdoob.com/
 */

5
import { BackSide, DoubleSide, CubeUVRefractionMapping, CubeUVReflectionMapping, GammaEncoding, LinearEncoding, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping } from '../../constants.js';
B
bentok 已提交
6
import { WebGLProgram } from './WebGLProgram.js';
R
Rich Harris 已提交
7

8
function WebGLPrograms( renderer, extensions, capabilities ) {
G
gero3 已提交
9

10
	var programs = [];
G
gero3 已提交
11

12 13 14 15 16 17 18
	var isWebGL2 = capabilities.isWebGL2;
	var logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer;
	var floatVertexTextures = capabilities.floatVertexTextures;
	var precision = capabilities.precision;
	var maxVertexUniforms = capabilities.maxVertexUniforms;
	var vertexTextures = capabilities.vertexTextures;

G
gero3 已提交
19 20
	var shaderIDs = {
		MeshDepthMaterial: 'depth',
W
WestLangley 已提交
21
		MeshDistanceMaterial: 'distanceRGBA',
G
gero3 已提交
22 23 24 25
		MeshNormalMaterial: 'normal',
		MeshBasicMaterial: 'basic',
		MeshLambertMaterial: 'lambert',
		MeshPhongMaterial: 'phong',
T
Takahiro 已提交
26
		MeshToonMaterial: 'phong',
27
		MeshStandardMaterial: 'physical',
W
WestLangley 已提交
28
		MeshPhysicalMaterial: 'physical',
W
WestLangley 已提交
29
		MeshMatcapMaterial: 'matcap',
G
gero3 已提交
30 31
		LineBasicMaterial: 'basic',
		LineDashedMaterial: 'dashed',
32
		PointsMaterial: 'points',
33 34
		ShadowMaterial: 'shadow',
		SpriteMaterial: 'sprite'
G
gero3 已提交
35
	};
G
gero3 已提交
36

M
Mr.doob 已提交
37
	var parameterNames = [
M
Mr.doob 已提交
38 39
		"precision", "supportsVertexTextures", "instancing",
		"map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding",
40
		"lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatNormalMap", "displacementMap", "specularMap",
T
Takahiro 已提交
41
		"roughnessMap", "metalnessMap", "gradientMap",
E
Elias Hasle 已提交
42
		"alphaMap", "combine", "vertexColors", "vertexTangents", "fog", "useFog", "fogExp2",
M
Mr.doob 已提交
43 44
		"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
		"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
45
		"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
46
		"numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
47
		"shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
48 49
		"alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering",
		"sheen"
M
Mr.doob 已提交
50
	];
G
gero3 已提交
51 52


M
Mr.doob 已提交
53
	function allocateBones( object ) {
G
gero3 已提交
54

55 56 57
		var skeleton = object.skeleton;
		var bones = skeleton.bones;

58
		if ( floatVertexTextures ) {
59

G
gero3 已提交
60 61 62 63 64 65 66 67 68 69 70
			return 1024;

		} else {

			// default for when object is not specified
			// ( for example when prebuilding shader to be used with multiple objects )
			//
			//  - leave some extra space for other uniforms
			//  - limit here is ANGLE's 254 max uniform vectors
			//    (up to 54 should be safe)

71
			var nVertexUniforms = maxVertexUniforms;
G
gero3 已提交
72 73
			var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );

74
			var maxBones = Math.min( nVertexMatrices, bones.length );
G
gero3 已提交
75

76
			if ( maxBones < bones.length ) {
G
gero3 已提交
77

78 79
				console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' );
				return 0;
G
gero3 已提交
80 81 82 83 84 85 86 87

			}

			return maxBones;

		}

	}
G
gero3 已提交
88

89
	function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
90 91

		var encoding;
M
Mr.doob 已提交
92 93

		if ( ! map ) {
M
Mr.doob 已提交
94

R
Rich Harris 已提交
95
			encoding = LinearEncoding;
M
Mr.doob 已提交
96

97
		} else if ( map.isTexture ) {
M
Mr.doob 已提交
98

99
			encoding = map.encoding;
M
Mr.doob 已提交
100

101
		} else if ( map.isWebGLRenderTarget ) {
M
Mr.doob 已提交
102

103
			console.warn( "THREE.WebGLPrograms.getTextureEncodingFromMap: don't use render targets as textures. Use their .texture property instead." );
104
			encoding = map.texture.encoding;
M
Mr.doob 已提交
105

106 107 108
		}

		// add backwards compatibility for WebGLRenderer.gammaInput/gammaOutput parameter, should probably be removed at some point.
R
Rich Harris 已提交
109
		if ( encoding === LinearEncoding && gammaOverrideLinear ) {
M
Mr.doob 已提交
110

R
Rich Harris 已提交
111
			encoding = GammaEncoding;
M
Mr.doob 已提交
112

113 114 115
		}

		return encoding;
M
Mr.doob 已提交
116

117 118
	}

119
	this.getParameters = function ( material, lights, shadows, fog, nClipPlanes, nClipIntersection, object ) {
M
Mr.doob 已提交
120

G
gero3 已提交
121
		var shaderID = shaderIDs[ material.type ];
M
Mr.doob 已提交
122

G
gero3 已提交
123
		// heuristics to create shader parameters according to lights in the scene
G
gero3 已提交
124 125
		// (not to blow over maxLights budget)

126
		var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0;
G
gero3 已提交
127 128 129

		if ( material.precision !== null ) {

G
gero3 已提交
130
			precision = capabilities.getMaxPrecision( material.precision );
G
gero3 已提交
131 132 133

			if ( precision !== material.precision ) {

134
				console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
G
gero3 已提交
135 136 137 138

			}

		}
M
Mr.doob 已提交
139

140
		var currentRenderTarget = renderer.getRenderTarget();
141

G
gero3 已提交
142
		var parameters = {
G
gero3 已提交
143

144
			isWebGL2: isWebGL2,
M
Mr.doob 已提交
145

G
gero3 已提交
146
			shaderID: shaderID,
G
gero3 已提交
147 148

			precision: precision,
M
Mr.doob 已提交
149 150 151

			instancing: object.isInstancedMesh === true,

152
			supportsVertexTextures: vertexTextures,
153
			outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),
G
gero3 已提交
154
			map: !! material.map,
155
			mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),
W
WestLangley 已提交
156 157
			matcap: !! material.matcap,
			matcapEncoding: getTextureEncodingFromMap( material.matcap, renderer.gammaInput ),
G
gero3 已提交
158 159
			envMap: !! material.envMap,
			envMapMode: material.envMap && material.envMap.mapping,
160
			envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),
R
Rich Harris 已提交
161
			envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),
G
gero3 已提交
162 163 164
			lightMap: !! material.lightMap,
			aoMap: !! material.aoMap,
			emissiveMap: !! material.emissiveMap,
165
			emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),
G
gero3 已提交
166 167
			bumpMap: !! material.bumpMap,
			normalMap: !! material.normalMap,
W
WestLangley 已提交
168
			objectSpaceNormalMap: material.normalMapType === ObjectSpaceNormalMap,
169
			tangentSpaceNormalMap: material.normalMapType === TangentSpaceNormalMap,
170
			clearcoatNormalMap: !! material.clearcoatNormalMap,
171
			displacementMap: !! material.displacementMap,
W
WestLangley 已提交
172 173
			roughnessMap: !! material.roughnessMap,
			metalnessMap: !! material.metalnessMap,
G
gero3 已提交
174 175 176
			specularMap: !! material.specularMap,
			alphaMap: !! material.alphaMap,

T
Takahiro 已提交
177
			gradientMap: !! material.gradientMap,
T
Takahiro 已提交
178

179
			sheen: !! material.sheen,
180

G
gero3 已提交
181 182
			combine: material.combine,

183
			vertexTangents: ( material.normalMap && material.vertexTangents ),
G
gero3 已提交
184
			vertexColors: material.vertexColors,
185
			vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap,
G
gero3 已提交
186

M
Mr.doob 已提交
187
			fog: !! fog,
G
gero3 已提交
188
			useFog: material.fog,
E
Elias Hasle 已提交
189
			fogExp2: ( fog && fog.isFogExp2 ),
G
gero3 已提交
190

191
			flatShading: material.flatShading,
G
gero3 已提交
192 193

			sizeAttenuation: material.sizeAttenuation,
194
			logarithmicDepthBuffer: logarithmicDepthBuffer,
G
gero3 已提交
195

M
Mr.doob 已提交
196
			skinning: material.skinning && maxBones > 0,
G
gero3 已提交
197
			maxBones: maxBones,
198
			useVertexTexture: floatVertexTextures,
G
gero3 已提交
199 200 201

			morphTargets: material.morphTargets,
			morphNormals: material.morphNormals,
M
Mr.doob 已提交
202 203
			maxMorphTargets: renderer.maxMorphTargets,
			maxMorphNormals: renderer.maxMorphNormals,
G
gero3 已提交
204

205 206 207
			numDirLights: lights.directional.length,
			numPointLights: lights.point.length,
			numSpotLights: lights.spot.length,
208
			numRectAreaLights: lights.rectArea.length,
209
			numHemiLights: lights.hemi.length,
210

211 212 213 214
			numDirLightShadows: lights.directionalShadowMap.length,
			numPointLightShadows: lights.pointShadowMap.length,
			numSpotLightShadows: lights.spotShadowMap.length,

T
tschw 已提交
215
			numClippingPlanes: nClipPlanes,
216
			numClipIntersection: nClipIntersection,
T
tschw 已提交
217

218
			dithering: material.dithering,
219

220
			shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
M
Mr.doob 已提交
221
			shadowMapType: renderer.shadowMap.type,
G
gero3 已提交
222

W
WestLangley 已提交
223
			toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,
224
			physicallyCorrectLights: renderer.physicallyCorrectLights,
B
Ben Houston 已提交
225

226 227
			premultipliedAlpha: material.premultipliedAlpha,

G
gero3 已提交
228
			alphaTest: material.alphaTest,
R
Rich Harris 已提交
229 230
			doubleSided: material.side === DoubleSide,
			flipSided: material.side === BackSide,
231

232
			depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false
G
gero3 已提交
233 234

		};
235

G
gero3 已提交
236
		return parameters;
G
gero3 已提交
237

G
gero3 已提交
238
	};
G
gero3 已提交
239

M
Mr.doob 已提交
240
	this.getProgramCode = function ( material, parameters ) {
G
gero3 已提交
241

M
Mr.doob 已提交
242
		var array = [];
G
gero3 已提交
243 244 245

		if ( parameters.shaderID ) {

M
Mr.doob 已提交
246
			array.push( parameters.shaderID );
G
gero3 已提交
247 248 249

		} else {

M
Mr.doob 已提交
250 251
			array.push( material.fragmentShader );
			array.push( material.vertexShader );
G
gero3 已提交
252 253 254 255 256 257 258

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

M
Mr.doob 已提交
259 260
				array.push( name );
				array.push( material.defines[ name ] );
G
gero3 已提交
261 262 263 264 265

			}

		}

G
gero3 已提交
266 267
		for ( var i = 0; i < parameterNames.length; i ++ ) {

M
Mr.doob 已提交
268
			array.push( parameters[ parameterNames[ i ] ] );
G
gero3 已提交
269 270 271

		}

M
Mr.doob 已提交
272 273
		array.push( material.onBeforeCompile.toString() );

274 275
		array.push( renderer.gammaOutput );

W
WestLangley 已提交
276 277
		array.push( renderer.gammaFactor );

M
Mr.doob 已提交
278
		return array.join();
G
gero3 已提交
279 280 281

	};

282
	this.acquireProgram = function ( material, shader, parameters, code ) {
G
gero3 已提交
283 284 285 286

		var program;

		// Check if code has been already compiled
G
gero3 已提交
287 288 289 290 291 292 293
		for ( var p = 0, pl = programs.length; p < pl; p ++ ) {

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

				program = programInfo;
294
				++ program.usedTimes;
G
gero3 已提交
295 296 297 298 299 300 301 302

				break;

			}

		}

		if ( program === undefined ) {
G
gero3 已提交
303

G
gero3 已提交
304
			program = new WebGLProgram( renderer, extensions, code, material, shader, parameters );
G
gero3 已提交
305
			programs.push( program );
G
gero3 已提交
306

G
gero3 已提交
307
		}
G
gero3 已提交
308

309
		return program;
G
gero3 已提交
310

311 312
	};

M
Mr.doob 已提交
313
	this.releaseProgram = function ( program ) {
314 315 316 317 318 319 320 321 322 323 324 325 326 327

		if ( -- program.usedTimes === 0 ) {

			// Remove from unordered set
			var i = programs.indexOf( program );
			programs[ i ] = programs[ programs.length - 1 ];
			programs.pop();

			// Free WebGL resources
			program.destroy();

		}

	};
G
gero3 已提交
328

329 330 331
	// Exposed for resource monitoring & error feedback via renderer.info:
	this.programs = programs;

M
Mr.doob 已提交
332
}
R
Rich Harris 已提交
333 334


335
export { WebGLPrograms };