WebGLPrograms.js 9.7 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 = [
G
gero3 已提交
38
		"precision", "isWebGL2", "supportsVertexTextures", "outputEncoding", "instancing", "numMultiviewViews",
G
gero3 已提交
39
		"map", "mapEncoding", "matcap", "matcapEncoding", "envMap", "envMapMode", "envMapEncoding", "envMapCubeUV",
40
		"lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "objectSpaceNormalMap", "tangentSpaceNormalMap", "clearcoatNormalMap", "displacementMap", "specularMap",
T
Takahiro 已提交
41
		"roughnessMap", "metalnessMap", "gradientMap",
G
gero3 已提交
42
		"alphaMap", "combine", "vertexColors", "vertexTangents", "vertexUvs", "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",
G
gero3 已提交
47
		"numDirLightShadows", "numPointLightShadows", "numSpotLightShadows",
48
		"shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
49 50
		"alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering",
		"sheen"
M
Mr.doob 已提交
51
	];
G
gero3 已提交
52 53


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

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

59
		if ( floatVertexTextures ) {
60

G
gero3 已提交
61 62 63 64 65 66 67 68 69 70 71
			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)

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

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

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

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

			}

			return maxBones;

		}

	}
G
gero3 已提交
89

90
	function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
91 92

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

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

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

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

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

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

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

107 108 109
		}

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

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

114 115 116
		}

		return encoding;
M
Mr.doob 已提交
117

118 119
	}

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

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

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

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

		if ( material.precision !== null ) {

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

			if ( precision !== material.precision ) {

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

			}

		}
M
Mr.doob 已提交
140

141
		var currentRenderTarget = renderer.getRenderTarget();
G
gero3 已提交
142
		var numMultiviewViews = currentRenderTarget && currentRenderTarget.isWebGLMultiviewRenderTarget ? currentRenderTarget.numViews : 0;
143

G
gero3 已提交
144
		var parameters = {
G
gero3 已提交
145

146
			isWebGL2: isWebGL2,
M
Mr.doob 已提交
147

G
gero3 已提交
148
			shaderID: shaderID,
G
gero3 已提交
149 150

			precision: precision,
M
Mr.doob 已提交
151 152 153

			instancing: object.isInstancedMesh === true,

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

T
Takahiro 已提交
180
			gradientMap: !! material.gradientMap,
T
Takahiro 已提交
181

182
			sheen: !! material.sheen,
183

G
gero3 已提交
184 185
			combine: material.combine,

186
			vertexTangents: ( material.normalMap && material.vertexTangents ),
G
gero3 已提交
187
			vertexColors: material.vertexColors,
188
			vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap || !! material.displacementMap,
G
gero3 已提交
189

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

194
			flatShading: material.flatShading,
G
gero3 已提交
195 196

			sizeAttenuation: material.sizeAttenuation,
197
			logarithmicDepthBuffer: logarithmicDepthBuffer,
G
gero3 已提交
198

M
Mr.doob 已提交
199
			skinning: material.skinning && maxBones > 0,
G
gero3 已提交
200
			maxBones: maxBones,
201
			useVertexTexture: floatVertexTextures,
G
gero3 已提交
202 203 204

			morphTargets: material.morphTargets,
			morphNormals: material.morphNormals,
M
Mr.doob 已提交
205 206
			maxMorphTargets: renderer.maxMorphTargets,
			maxMorphNormals: renderer.maxMorphNormals,
G
gero3 已提交
207

208 209 210
			numDirLights: lights.directional.length,
			numPointLights: lights.point.length,
			numSpotLights: lights.spot.length,
211
			numRectAreaLights: lights.rectArea.length,
212
			numHemiLights: lights.hemi.length,
213

214 215 216 217
			numDirLightShadows: lights.directionalShadowMap.length,
			numPointLightShadows: lights.pointShadowMap.length,
			numSpotLightShadows: lights.spotShadowMap.length,

T
tschw 已提交
218
			numClippingPlanes: nClipPlanes,
219
			numClipIntersection: nClipIntersection,
T
tschw 已提交
220

221
			dithering: material.dithering,
222

223
			shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
M
Mr.doob 已提交
224
			shadowMapType: renderer.shadowMap.type,
G
gero3 已提交
225

W
WestLangley 已提交
226
			toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,
227
			physicallyCorrectLights: renderer.physicallyCorrectLights,
B
Ben Houston 已提交
228

229 230
			premultipliedAlpha: material.premultipliedAlpha,

G
gero3 已提交
231
			alphaTest: material.alphaTest,
R
Rich Harris 已提交
232 233
			doubleSided: material.side === DoubleSide,
			flipSided: material.side === BackSide,
234

235
			depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false
G
gero3 已提交
236 237

		};
238

G
gero3 已提交
239
		return parameters;
G
gero3 已提交
240

G
gero3 已提交
241
	};
G
gero3 已提交
242

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

M
Mr.doob 已提交
245
		var array = [];
G
gero3 已提交
246 247 248

		if ( parameters.shaderID ) {

M
Mr.doob 已提交
249
			array.push( parameters.shaderID );
G
gero3 已提交
250 251 252

		} else {

M
Mr.doob 已提交
253 254
			array.push( material.fragmentShader );
			array.push( material.vertexShader );
G
gero3 已提交
255 256 257 258 259 260 261

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

M
Mr.doob 已提交
262 263
				array.push( name );
				array.push( material.defines[ name ] );
G
gero3 已提交
264 265 266 267 268

			}

		}

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

M
Mr.doob 已提交
271
			array.push( parameters[ parameterNames[ i ] ] );
G
gero3 已提交
272 273 274

		}

M
Mr.doob 已提交
275 276
		array.push( material.onBeforeCompile.toString() );

277 278
		array.push( renderer.gammaOutput );

W
WestLangley 已提交
279 280
		array.push( renderer.gammaFactor );

M
Mr.doob 已提交
281
		return array.join();
G
gero3 已提交
282 283 284

	};

285
	this.acquireProgram = function ( material, shader, parameters, code ) {
G
gero3 已提交
286 287 288 289

		var program;

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

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

				program = programInfo;
297
				++ program.usedTimes;
G
gero3 已提交
298 299 300 301 302 303 304 305

				break;

			}

		}

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

G
gero3 已提交
307
			program = new WebGLProgram( renderer, extensions, code, material, shader, parameters );
G
gero3 已提交
308
			programs.push( program );
G
gero3 已提交
309

G
gero3 已提交
310
		}
G
gero3 已提交
311

312
		return program;
G
gero3 已提交
313

314 315
	};

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

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

332 333 334
	// Exposed for resource monitoring & error feedback via renderer.info:
	this.programs = programs;

M
Mr.doob 已提交
335
}
R
Rich Harris 已提交
336 337


338
export { WebGLPrograms };