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


M
Mr.doob 已提交
44
	function allocateBones( object ) {
G
gero3 已提交
45

46 47 48 49 50
		var skeleton = object.skeleton;
		var bones = skeleton.bones;

		if ( capabilities.floatVertexTextures ) {

G
gero3 已提交
51 52 53 54 55 56 57 58 59 60 61
			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 已提交
62
			var nVertexUniforms = capabilities.maxVertexUniforms;
G
gero3 已提交
63 64
			var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );

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

67
			if ( maxBones < bones.length ) {
G
gero3 已提交
68

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

			}

			return maxBones;

		}

	}
G
gero3 已提交
79

80
	function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
81 82

		var encoding;
M
Mr.doob 已提交
83 84

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

R
Rich Harris 已提交
86
			encoding = LinearEncoding;
M
Mr.doob 已提交
87

88
		} else if ( map.isTexture ) {
M
Mr.doob 已提交
89

90
			encoding = map.encoding;
M
Mr.doob 已提交
91

92
		} else if ( map.isWebGLRenderTarget ) {
M
Mr.doob 已提交
93

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

97 98 99
		}

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

R
Rich Harris 已提交
102
			encoding = GammaEncoding;
M
Mr.doob 已提交
103

104 105 106
		}

		return encoding;
M
Mr.doob 已提交
107

108 109
	}

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

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

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

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

		if ( material.precision !== null ) {

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

			if ( precision !== material.precision ) {

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

			}

		}
M
Mr.doob 已提交
131

132
		var currentRenderTarget = renderer.getRenderTarget();
133

G
gero3 已提交
134
		var parameters = {
G
gero3 已提交
135 136

			shaderID: shaderID,
G
gero3 已提交
137 138

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

T
Takahiro 已提交
164
			gradientMap: !! material.gradientMap,
T
Takahiro 已提交
165

G
gero3 已提交
166 167
			combine: material.combine,

168
			vertexTangents: ( material.normalMap && material.vertexTangents ),
G
gero3 已提交
169
			vertexColors: material.vertexColors,
170
			vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearCoatNormalMap,
G
gero3 已提交
171

M
Mr.doob 已提交
172
			fog: !! fog,
G
gero3 已提交
173
			useFog: material.fog,
E
Elias Hasle 已提交
174
			fogExp2: ( fog && fog.isFogExp2 ),
G
gero3 已提交
175

176
			flatShading: material.flatShading,
G
gero3 已提交
177 178

			sizeAttenuation: material.sizeAttenuation,
179
			logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
G
gero3 已提交
180

M
Mr.doob 已提交
181
			skinning: material.skinning && maxBones > 0,
G
gero3 已提交
182
			maxBones: maxBones,
183
			useVertexTexture: capabilities.floatVertexTextures,
G
gero3 已提交
184 185 186

			morphTargets: material.morphTargets,
			morphNormals: material.morphNormals,
M
Mr.doob 已提交
187 188
			maxMorphTargets: renderer.maxMorphTargets,
			maxMorphNormals: renderer.maxMorphNormals,
G
gero3 已提交
189

190 191 192
			numDirLights: lights.directional.length,
			numPointLights: lights.point.length,
			numSpotLights: lights.spot.length,
193
			numRectAreaLights: lights.rectArea.length,
194
			numHemiLights: lights.hemi.length,
195

196 197 198 199
			numDirLightShadows: lights.directionalShadowMap.length,
			numPointLightShadows: lights.pointShadowMap.length,
			numSpotLightShadows: lights.spotShadowMap.length,

T
tschw 已提交
200
			numClippingPlanes: nClipPlanes,
201
			numClipIntersection: nClipIntersection,
T
tschw 已提交
202

203
			dithering: material.dithering,
204

205
			shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && shadows.length > 0,
M
Mr.doob 已提交
206
			shadowMapType: renderer.shadowMap.type,
G
gero3 已提交
207

B
Ben Houston 已提交
208
			toneMapping: renderer.toneMapping,
209
			physicallyCorrectLights: renderer.physicallyCorrectLights,
B
Ben Houston 已提交
210

211 212
			premultipliedAlpha: material.premultipliedAlpha,

G
gero3 已提交
213
			alphaTest: material.alphaTest,
R
Rich Harris 已提交
214 215
			doubleSided: material.side === DoubleSide,
			flipSided: material.side === BackSide,
216

217
			depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false
G
gero3 已提交
218 219

		};
220

G
gero3 已提交
221
		return parameters;
G
gero3 已提交
222

G
gero3 已提交
223
	};
G
gero3 已提交
224

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

M
Mr.doob 已提交
227
		var array = [];
G
gero3 已提交
228 229 230

		if ( parameters.shaderID ) {

M
Mr.doob 已提交
231
			array.push( parameters.shaderID );
G
gero3 已提交
232 233 234

		} else {

M
Mr.doob 已提交
235 236
			array.push( material.fragmentShader );
			array.push( material.vertexShader );
G
gero3 已提交
237 238 239 240 241 242 243

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

M
Mr.doob 已提交
244 245
				array.push( name );
				array.push( material.defines[ name ] );
G
gero3 已提交
246 247 248 249 250

			}

		}

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

M
Mr.doob 已提交
253
			array.push( parameters[ parameterNames[ i ] ] );
G
gero3 已提交
254 255 256

		}

M
Mr.doob 已提交
257 258
		array.push( material.onBeforeCompile.toString() );

259 260
		array.push( renderer.gammaOutput );

W
WestLangley 已提交
261 262
		array.push( renderer.gammaFactor );

M
Mr.doob 已提交
263
		return array.join();
G
gero3 已提交
264 265 266

	};

267
	this.acquireProgram = function ( material, shader, parameters, code ) {
G
gero3 已提交
268 269 270 271

		var program;

		// Check if code has been already compiled
G
gero3 已提交
272 273 274 275 276 277 278
		for ( var p = 0, pl = programs.length; p < pl; p ++ ) {

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

				program = programInfo;
279
				++ program.usedTimes;
G
gero3 已提交
280 281 282 283 284 285 286 287

				break;

			}

		}

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

289
			program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities );
G
gero3 已提交
290
			programs.push( program );
G
gero3 已提交
291

G
gero3 已提交
292
		}
G
gero3 已提交
293

294
		return program;
G
gero3 已提交
295

296 297
	};

M
Mr.doob 已提交
298
	this.releaseProgram = function ( program ) {
299 300 301 302 303 304 305 306 307 308 309 310 311 312

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

314 315 316
	// Exposed for resource monitoring & error feedback via renderer.info:
	this.programs = programs;

M
Mr.doob 已提交
317
}
R
Rich Harris 已提交
318 319


320
export { WebGLPrograms };