WebGLPrograms.js 9.2 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

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

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


M
Mr.doob 已提交
46
	function allocateBones( object ) {
G
gero3 已提交
47

48 49 50 51 52
		var skeleton = object.skeleton;
		var bones = skeleton.bones;

		if ( capabilities.floatVertexTextures ) {

G
gero3 已提交
53 54 55 56 57 58 59 60 61 62 63
			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)

G
gero3 已提交
64
			var nVertexUniforms = capabilities.maxVertexUniforms;
G
gero3 已提交
65 66
			var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );

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

69
			if ( maxBones < bones.length ) {
G
gero3 已提交
70

71 72
				console.warn( 'THREE.WebGLRenderer: Skeleton has ' + bones.length + ' bones. This GPU supports ' + maxBones + '.' );
				return 0;
G
gero3 已提交
73 74 75 76 77 78 79 80

			}

			return maxBones;

		}

	}
G
gero3 已提交
81

82
	function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
83 84

		var encoding;
M
Mr.doob 已提交
85 86

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

R
Rich Harris 已提交
88
			encoding = LinearEncoding;
M
Mr.doob 已提交
89

90
		} else if ( map.isTexture ) {
M
Mr.doob 已提交
91

92
			encoding = map.encoding;
M
Mr.doob 已提交
93

94
		} else if ( map.isWebGLRenderTarget ) {
M
Mr.doob 已提交
95

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

99 100 101
		}

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

R
Rich Harris 已提交
104
			encoding = GammaEncoding;
M
Mr.doob 已提交
105

106 107 108
		}

		return encoding;
M
Mr.doob 已提交
109

110 111
	}

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

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

G
gero3 已提交
116
		// heuristics to create shader parameters according to lights in the scene
G
gero3 已提交
117 118
		// (not to blow over maxLights budget)

119
		var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0;
120
		var precision = capabilities.precision;
G
gero3 已提交
121 122 123

		if ( material.precision !== null ) {

G
gero3 已提交
124
			precision = capabilities.getMaxPrecision( material.precision );
G
gero3 已提交
125 126 127

			if ( precision !== material.precision ) {

128
				console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
G
gero3 已提交
129 130 131 132

			}

		}
M
Mr.doob 已提交
133

134
		var currentRenderTarget = renderer.getRenderTarget();
135

G
gero3 已提交
136
		var parameters = {
G
gero3 已提交
137 138

			shaderID: shaderID,
G
gero3 已提交
139 140

			precision: precision,
M
Mr.doob 已提交
141 142 143

			instancing: object.isInstancedMesh === true,

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

T
Takahiro 已提交
169
			gradientMap: !! material.gradientMap,
T
Takahiro 已提交
170

171
			sheen: !! material.sheen,
172

G
gero3 已提交
173 174
			combine: material.combine,

175
			vertexTangents: ( material.normalMap && material.vertexTangents ),
G
gero3 已提交
176
			vertexColors: material.vertexColors,
177
			vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap,
G
gero3 已提交
178

M
Mr.doob 已提交
179
			fog: !! fog,
G
gero3 已提交
180
			useFog: material.fog,
E
Elias Hasle 已提交
181
			fogExp2: ( fog && fog.isFogExp2 ),
G
gero3 已提交
182

183
			flatShading: material.flatShading,
G
gero3 已提交
184 185

			sizeAttenuation: material.sizeAttenuation,
186
			logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
G
gero3 已提交
187

M
Mr.doob 已提交
188
			skinning: material.skinning && maxBones > 0,
G
gero3 已提交
189
			maxBones: maxBones,
190
			useVertexTexture: capabilities.floatVertexTextures,
G
gero3 已提交
191 192 193

			morphTargets: material.morphTargets,
			morphNormals: material.morphNormals,
M
Mr.doob 已提交
194 195
			maxMorphTargets: renderer.maxMorphTargets,
			maxMorphNormals: renderer.maxMorphNormals,
G
gero3 已提交
196

197 198 199
			numDirLights: lights.directional.length,
			numPointLights: lights.point.length,
			numSpotLights: lights.spot.length,
200
			numRectAreaLights: lights.rectArea.length,
201
			numHemiLights: lights.hemi.length,
202

203 204 205 206
			numDirLightShadows: lights.directionalShadowMap.length,
			numPointLightShadows: lights.pointShadowMap.length,
			numSpotLightShadows: lights.spotShadowMap.length,

T
tschw 已提交
207
			numClippingPlanes: nClipPlanes,
208
			numClipIntersection: nClipIntersection,
T
tschw 已提交
209

210
			dithering: material.dithering,
211

212
			shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
M
Mr.doob 已提交
213
			shadowMapType: renderer.shadowMap.type,
G
gero3 已提交
214

W
WestLangley 已提交
215
			toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,
216
			physicallyCorrectLights: renderer.physicallyCorrectLights,
B
Ben Houston 已提交
217

218 219
			premultipliedAlpha: material.premultipliedAlpha,

G
gero3 已提交
220
			alphaTest: material.alphaTest,
R
Rich Harris 已提交
221 222
			doubleSided: material.side === DoubleSide,
			flipSided: material.side === BackSide,
223

224
			depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false
G
gero3 已提交
225 226

		};
227

G
gero3 已提交
228
		return parameters;
G
gero3 已提交
229

G
gero3 已提交
230
	};
G
gero3 已提交
231

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

M
Mr.doob 已提交
234
		var array = [];
G
gero3 已提交
235 236 237

		if ( parameters.shaderID ) {

M
Mr.doob 已提交
238
			array.push( parameters.shaderID );
G
gero3 已提交
239 240 241

		} else {

M
Mr.doob 已提交
242 243
			array.push( material.fragmentShader );
			array.push( material.vertexShader );
G
gero3 已提交
244 245 246 247 248 249 250

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

M
Mr.doob 已提交
251 252
				array.push( name );
				array.push( material.defines[ name ] );
G
gero3 已提交
253 254 255 256 257

			}

		}

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

M
Mr.doob 已提交
260
			array.push( parameters[ parameterNames[ i ] ] );
G
gero3 已提交
261 262 263

		}

M
Mr.doob 已提交
264 265
		array.push( material.onBeforeCompile.toString() );

266 267
		array.push( renderer.gammaOutput );

W
WestLangley 已提交
268 269
		array.push( renderer.gammaFactor );

M
Mr.doob 已提交
270
		return array.join();
G
gero3 已提交
271 272 273

	};

274
	this.acquireProgram = function ( material, shader, parameters, code ) {
G
gero3 已提交
275 276 277 278

		var program;

		// Check if code has been already compiled
G
gero3 已提交
279 280 281 282 283 284 285
		for ( var p = 0, pl = programs.length; p < pl; p ++ ) {

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

				program = programInfo;
286
				++ program.usedTimes;
G
gero3 已提交
287 288 289 290 291 292 293 294

				break;

			}

		}

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

296
			program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities );
G
gero3 已提交
297
			programs.push( program );
G
gero3 已提交
298

G
gero3 已提交
299
		}
G
gero3 已提交
300

301
		return program;
G
gero3 已提交
302

303 304
	};

M
Mr.doob 已提交
305
	this.releaseProgram = function ( program ) {
306 307 308 309 310 311 312 313 314 315 316 317 318 319

		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 已提交
320

321 322 323
	// Exposed for resource monitoring & error feedback via renderer.info:
	this.programs = programs;

M
Mr.doob 已提交
324
}
R
Rich Harris 已提交
325 326


327
export { WebGLPrograms };