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

W
WestLangley 已提交
5
import { BackSide, DoubleSide, CubeUVRefractionMapping, CubeUVReflectionMapping, GammaEncoding, LinearEncoding, ObjectSpaceNormalMap } 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", "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
			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

166
			sheen: !! material.sheen,
167

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

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

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

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

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

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

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

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

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

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

205
			dithering: material.dithering,
206

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

B
Ben Houston 已提交
210
			toneMapping: renderer.toneMapping,
211
			physicallyCorrectLights: renderer.physicallyCorrectLights,
B
Ben Houston 已提交
212

213 214
			premultipliedAlpha: material.premultipliedAlpha,

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

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

		};
222

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

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

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

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

		if ( parameters.shaderID ) {

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

		} else {

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

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

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

			}

		}

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

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

		}

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

261 262
		array.push( renderer.gammaOutput );

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

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

	};

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

		var program;

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

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

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

				break;

			}

		}

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

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

G
gero3 已提交
294
		}
G
gero3 已提交
295

296
		return program;
G
gero3 已提交
297

298 299
	};

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

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

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

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


322
export { WebGLPrograms };