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

R
Rich Harris 已提交
5 6 7
import { WebGLProgram } from './WebGLProgram';
import { BackSide, DoubleSide, FlatShading, CubeUVRefractionMapping, CubeUVReflectionMapping, GammaEncoding, LinearEncoding } from '../../constants';

M
Mr.doob 已提交
8
function WebGLPrograms( renderer, capabilities ) {
G
gero3 已提交
9

10
	var programs = [];
G
gero3 已提交
11

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

M
Mr.doob 已提交
26
	var parameterNames = [
27 28
		"precision", "supportsVertexTextures", "map", "mapEncoding", "envMap", "envMapMode", "envMapEncoding",
		"lightMap", "aoMap", "emissiveMap", "emissiveMapEncoding", "bumpMap", "normalMap", "displacementMap", "specularMap",
T
Takahiro 已提交
29
		"roughnessMap", "metalnessMap", "gradientMap",
M
Mr.doob 已提交
30 31 32
		"alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp",
		"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
		"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
33
		"maxMorphTargets", "maxMorphNormals", "premultipliedAlpha",
34
		"numDirLights", "numPointLights", "numSpotLights", "numHemiLights", "numRectAreaLights",
35
		"shadowMapEnabled", "shadowMapType", "toneMapping", 'physicallyCorrectLights',
36
		"alphaTest", "doubleSided", "flipSided", "numClippingPlanes", "numClipIntersection", "depthPacking"
M
Mr.doob 已提交
37
	];
G
gero3 已提交
38 39


M
Mr.doob 已提交
40
	function allocateBones( object ) {
G
gero3 已提交
41

G
gero3 已提交
42
		if ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {
G
gero3 已提交
43 44 45 46 47 48 49 50 51 52 53 54

			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 已提交
55
			var nVertexUniforms = capabilities.maxVertexUniforms;
G
gero3 已提交
56 57 58 59
			var nVertexMatrices = Math.floor( ( nVertexUniforms - 20 ) / 4 );

			var maxBones = nVertexMatrices;

60
			if ( object && object.isSkinnedMesh ) {
G
gero3 已提交
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76

				maxBones = Math.min( object.skeleton.bones.length, maxBones );

				if ( maxBones < object.skeleton.bones.length ) {

					console.warn( 'WebGLRenderer: too many bones - ' + object.skeleton.bones.length + ', this GPU supports just ' + maxBones + ' (try OpenGL instead of ANGLE)' );

				}

			}

			return maxBones;

		}

	}
G
gero3 已提交
77

78
	function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
79 80

		var encoding;
M
Mr.doob 已提交
81 82

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

R
Rich Harris 已提交
84
			encoding = LinearEncoding;
M
Mr.doob 已提交
85

86
		} else if ( map.isTexture ) {
M
Mr.doob 已提交
87

88
			encoding = map.encoding;
M
Mr.doob 已提交
89

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

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

95 96 97
		}

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

R
Rich Harris 已提交
100
			encoding = GammaEncoding;
M
Mr.doob 已提交
101

102 103 104
		}

		return encoding;
M
Mr.doob 已提交
105

106 107
	}

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

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

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

		var maxBones = allocateBones( object );
M
Mr.doob 已提交
116
		var precision = renderer.getPrecision();
G
gero3 已提交
117 118 119

		if ( material.precision !== null ) {

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

			if ( precision !== material.precision ) {

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

			}

		}
M
Mr.doob 已提交
129

130 131
		var currentRenderTarget = renderer.getCurrentRenderTarget();

G
gero3 已提交
132
		var parameters = {
G
gero3 已提交
133 134

			shaderID: shaderID,
G
gero3 已提交
135 136

			precision: precision,
G
gero3 已提交
137
			supportsVertexTextures: capabilities.vertexTextures,
138
			outputEncoding: getTextureEncodingFromMap( ( ! currentRenderTarget ) ? null : currentRenderTarget.texture, renderer.gammaOutput ),
G
gero3 已提交
139
			map: !! material.map,
140
			mapEncoding: getTextureEncodingFromMap( material.map, renderer.gammaInput ),
G
gero3 已提交
141 142
			envMap: !! material.envMap,
			envMapMode: material.envMap && material.envMap.mapping,
143
			envMapEncoding: getTextureEncodingFromMap( material.envMap, renderer.gammaInput ),
R
Rich Harris 已提交
144
			envMapCubeUV: ( !! material.envMap ) && ( ( material.envMap.mapping === CubeUVReflectionMapping ) || ( material.envMap.mapping === CubeUVRefractionMapping ) ),
G
gero3 已提交
145 146 147
			lightMap: !! material.lightMap,
			aoMap: !! material.aoMap,
			emissiveMap: !! material.emissiveMap,
148
			emissiveMapEncoding: getTextureEncodingFromMap( material.emissiveMap, renderer.gammaInput ),
G
gero3 已提交
149 150
			bumpMap: !! material.bumpMap,
			normalMap: !! material.normalMap,
151
			displacementMap: !! material.displacementMap,
W
WestLangley 已提交
152 153
			roughnessMap: !! material.roughnessMap,
			metalnessMap: !! material.metalnessMap,
G
gero3 已提交
154 155 156
			specularMap: !! material.specularMap,
			alphaMap: !! material.alphaMap,

T
Takahiro 已提交
157
			gradientMap: !! material.gradientMap,
T
Takahiro 已提交
158

G
gero3 已提交
159 160 161 162
			combine: material.combine,

			vertexColors: material.vertexColors,

M
Mr.doob 已提交
163
			fog: !! fog,
G
gero3 已提交
164
			useFog: material.fog,
R
Rich Harris 已提交
165
			fogExp: (fog && fog.isFogExp2),
G
gero3 已提交
166

R
Rich Harris 已提交
167
			flatShading: material.shading === FlatShading,
G
gero3 已提交
168 169

			sizeAttenuation: material.sizeAttenuation,
170
			logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
G
gero3 已提交
171

172
			skinning: ( object && object.isSkinnedMesh ),
G
gero3 已提交
173
			maxBones: maxBones,
G
gero3 已提交
174
			useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,
G
gero3 已提交
175 176 177

			morphTargets: material.morphTargets,
			morphNormals: material.morphNormals,
M
Mr.doob 已提交
178 179
			maxMorphTargets: renderer.maxMorphTargets,
			maxMorphNormals: renderer.maxMorphNormals,
G
gero3 已提交
180

181 182 183
			numDirLights: lights.directional.length,
			numPointLights: lights.point.length,
			numSpotLights: lights.spot.length,
184
			numRectAreaLights: lights.rectArea.length,
185
			numHemiLights: lights.hemi.length,
186

T
tschw 已提交
187
			numClippingPlanes: nClipPlanes,
188
			numClipIntersection: nClipIntersection,
T
tschw 已提交
189

190
			shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,
M
Mr.doob 已提交
191
			shadowMapType: renderer.shadowMap.type,
G
gero3 已提交
192

B
Ben Houston 已提交
193
			toneMapping: renderer.toneMapping,
194
			physicallyCorrectLights: renderer.physicallyCorrectLights,
B
Ben Houston 已提交
195

196 197
			premultipliedAlpha: material.premultipliedAlpha,

G
gero3 已提交
198
			alphaTest: material.alphaTest,
R
Rich Harris 已提交
199 200
			doubleSided: material.side === DoubleSide,
			flipSided: material.side === BackSide,
201

202
			depthPacking: ( material.depthPacking !== undefined ) ? material.depthPacking : false
G
gero3 已提交
203 204

		};
205

G
gero3 已提交
206
		return parameters;
G
gero3 已提交
207

G
gero3 已提交
208
	};
G
gero3 已提交
209

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

M
Mr.doob 已提交
212
		var array = [];
G
gero3 已提交
213 214 215

		if ( parameters.shaderID ) {

M
Mr.doob 已提交
216
			array.push( parameters.shaderID );
G
gero3 已提交
217 218 219

		} else {

M
Mr.doob 已提交
220 221
			array.push( material.fragmentShader );
			array.push( material.vertexShader );
G
gero3 已提交
222 223 224 225 226 227 228

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

M
Mr.doob 已提交
229 230
				array.push( name );
				array.push( material.defines[ name ] );
G
gero3 已提交
231 232 233 234 235

			}

		}

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

M
Mr.doob 已提交
238
			array.push( parameters[ parameterNames[ i ] ] );
G
gero3 已提交
239 240 241

		}

M
Mr.doob 已提交
242
		return array.join();
G
gero3 已提交
243 244 245

	};

246
	this.acquireProgram = function ( material, parameters, code ) {
G
gero3 已提交
247 248 249 250

		var program;

		// Check if code has been already compiled
G
gero3 已提交
251 252 253 254 255 256 257
		for ( var p = 0, pl = programs.length; p < pl; p ++ ) {

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

				program = programInfo;
258
				++ program.usedTimes;
G
gero3 已提交
259 260 261 262 263 264 265 266

				break;

			}

		}

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

R
Rich Harris 已提交
268
			program = new WebGLProgram( renderer, code, material, parameters );
G
gero3 已提交
269
			programs.push( program );
G
gero3 已提交
270

G
gero3 已提交
271
		}
G
gero3 已提交
272

273
		return program;
G
gero3 已提交
274

275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291
	};

	this.releaseProgram = function( program ) {

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

293 294 295
	// Exposed for resource monitoring & error feedback via renderer.info:
	this.programs = programs;

M
Mr.doob 已提交
296
}
R
Rich Harris 已提交
297 298


299
export { WebGLPrograms };