WebGLPrograms.js 9.1 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 = [
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 41
		"alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking", "dithering",
		"sheen"
M
Mr.doob 已提交
42
	];
G
gero3 已提交
43 44


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

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

		if ( capabilities.floatVertexTextures ) {

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

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

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

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

			}

			return maxBones;

		}

	}
G
gero3 已提交
80

81
	function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
82 83

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

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

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

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

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

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

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

98 99 100
		}

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

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

105 106 107
		}

		return encoding;
M
Mr.doob 已提交
108

109 110
	}

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

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

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

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

		if ( material.precision !== null ) {

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

			if ( precision !== material.precision ) {

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

			}

		}
M
Mr.doob 已提交
132

133
		var currentRenderTarget = renderer.getRenderTarget();
134

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

			shaderID: shaderID,
G
gero3 已提交
138 139

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

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

167
			sheen: !! material.sheen,
168

G
gero3 已提交
169 170
			combine: material.combine,

171
			vertexTangents: ( material.normalMap && material.vertexTangents ),
G
gero3 已提交
172
			vertexColors: material.vertexColors,
173
			vertexUvs: !! material.map || !! material.bumpMap || !! material.normalMap || !! material.specularMap || !! material.alphaMap || !! material.emissiveMap || !! material.roughnessMap || !! material.metalnessMap || !! material.clearcoatNormalMap,
G
gero3 已提交
174

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

179
			flatShading: material.flatShading,
G
gero3 已提交
180 181

			sizeAttenuation: material.sizeAttenuation,
182
			logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
G
gero3 已提交
183

M
Mr.doob 已提交
184
			skinning: material.skinning && maxBones > 0,
G
gero3 已提交
185
			maxBones: maxBones,
186
			useVertexTexture: capabilities.floatVertexTextures,
G
gero3 已提交
187 188 189

			morphTargets: material.morphTargets,
			morphNormals: material.morphNormals,
M
Mr.doob 已提交
190 191
			maxMorphTargets: renderer.maxMorphTargets,
			maxMorphNormals: renderer.maxMorphNormals,
G
gero3 已提交
192

193 194 195
			numDirLights: lights.directional.length,
			numPointLights: lights.point.length,
			numSpotLights: lights.spot.length,
196
			numRectAreaLights: lights.rectArea.length,
197
			numHemiLights: lights.hemi.length,
198

199 200 201 202
			numDirLightShadows: lights.directionalShadowMap.length,
			numPointLightShadows: lights.pointShadowMap.length,
			numSpotLightShadows: lights.spotShadowMap.length,

T
tschw 已提交
203
			numClippingPlanes: nClipPlanes,
204
			numClipIntersection: nClipIntersection,
T
tschw 已提交
205

206
			dithering: material.dithering,
207

208
			shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0,
M
Mr.doob 已提交
209
			shadowMapType: renderer.shadowMap.type,
G
gero3 已提交
210

W
WestLangley 已提交
211
			toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping,
212
			physicallyCorrectLights: renderer.physicallyCorrectLights,
B
Ben Houston 已提交
213

214 215
			premultipliedAlpha: material.premultipliedAlpha,

G
gero3 已提交
216
			alphaTest: material.alphaTest,
R
Rich Harris 已提交
217 218
			doubleSided: material.side === DoubleSide,
			flipSided: material.side === BackSide,
219

220
			depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false
G
gero3 已提交
221 222

		};
223

G
gero3 已提交
224
		return parameters;
G
gero3 已提交
225

G
gero3 已提交
226
	};
G
gero3 已提交
227

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

M
Mr.doob 已提交
230
		var array = [];
G
gero3 已提交
231 232 233

		if ( parameters.shaderID ) {

M
Mr.doob 已提交
234
			array.push( parameters.shaderID );
G
gero3 已提交
235 236 237

		} else {

M
Mr.doob 已提交
238 239
			array.push( material.fragmentShader );
			array.push( material.vertexShader );
G
gero3 已提交
240 241 242 243 244 245 246

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

M
Mr.doob 已提交
247 248
				array.push( name );
				array.push( material.defines[ name ] );
G
gero3 已提交
249 250 251 252 253

			}

		}

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

M
Mr.doob 已提交
256
			array.push( parameters[ parameterNames[ i ] ] );
G
gero3 已提交
257 258 259

		}

M
Mr.doob 已提交
260 261
		array.push( material.onBeforeCompile.toString() );

262 263
		array.push( renderer.gammaOutput );

W
WestLangley 已提交
264 265
		array.push( renderer.gammaFactor );

M
Mr.doob 已提交
266
		return array.join();
G
gero3 已提交
267 268 269

	};

270
	this.acquireProgram = function ( material, shader, parameters, code ) {
G
gero3 已提交
271 272 273 274

		var program;

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

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

				program = programInfo;
282
				++ program.usedTimes;
G
gero3 已提交
283 284 285 286 287 288 289 290

				break;

			}

		}

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

292
			program = new WebGLProgram( renderer, extensions, code, material, shader, parameters, capabilities );
G
gero3 已提交
293
			programs.push( program );
G
gero3 已提交
294

G
gero3 已提交
295
		}
G
gero3 已提交
296

297
		return program;
G
gero3 已提交
298

299 300
	};

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

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

317 318 319
	// Exposed for resource monitoring & error feedback via renderer.info:
	this.programs = programs;

M
Mr.doob 已提交
320
}
R
Rich Harris 已提交
321 322


323
export { WebGLPrograms };