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

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

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

42 43 44 45 46
		var skeleton = object.skeleton;
		var bones = skeleton.bones;

		if ( capabilities.floatVertexTextures ) {

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

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

63
			if ( maxBones < bones.length ) {
G
gero3 已提交
64

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

			}

			return maxBones;

		}

	}
G
gero3 已提交
75

76
	function getTextureEncodingFromMap( map, gammaOverrideLinear ) {
77 78

		var encoding;
M
Mr.doob 已提交
79 80

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

R
Rich Harris 已提交
82
			encoding = LinearEncoding;
M
Mr.doob 已提交
83

84
		} else if ( map.isTexture ) {
M
Mr.doob 已提交
85

86
			encoding = map.encoding;
M
Mr.doob 已提交
87

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

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

93 94 95
		}

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

R
Rich Harris 已提交
98
			encoding = GammaEncoding;
M
Mr.doob 已提交
99

100 101 102
		}

		return encoding;
M
Mr.doob 已提交
103

104 105
	}

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

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

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

113
		var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0;
M
Mr.doob 已提交
114
		var precision = renderer.getPrecision();
G
gero3 已提交
115 116 117

		if ( material.precision !== null ) {

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

			if ( precision !== material.precision ) {

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

			}

		}
M
Mr.doob 已提交
127

128 129
		var currentRenderTarget = renderer.getCurrentRenderTarget();

G
gero3 已提交
130
		var parameters = {
G
gero3 已提交
131 132

			shaderID: shaderID,
G
gero3 已提交
133 134

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

T
Takahiro 已提交
155
			gradientMap: !! material.gradientMap,
T
Takahiro 已提交
156

G
gero3 已提交
157 158 159 160
			combine: material.combine,

			vertexColors: material.vertexColors,

M
Mr.doob 已提交
161
			fog: !! fog,
G
gero3 已提交
162
			useFog: material.fog,
M
Mr.doob 已提交
163
			fogExp: ( fog && fog.isFogExp2 ),
G
gero3 已提交
164

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

			sizeAttenuation: material.sizeAttenuation,
168
			logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
G
gero3 已提交
169

M
Mr.doob 已提交
170
			skinning: material.skinning && maxBones > 0,
G
gero3 已提交
171
			maxBones: maxBones,
172
			useVertexTexture: capabilities.floatVertexTextures,
G
gero3 已提交
173 174 175

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

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

T
tschw 已提交
185
			numClippingPlanes: nClipPlanes,
186
			numClipIntersection: nClipIntersection,
T
tschw 已提交
187

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

B
Ben Houston 已提交
191
			toneMapping: renderer.toneMapping,
192
			physicallyCorrectLights: renderer.physicallyCorrectLights,
B
Ben Houston 已提交
193

194 195
			premultipliedAlpha: material.premultipliedAlpha,

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

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

		};
203

G
gero3 已提交
204
		return parameters;
G
gero3 已提交
205

G
gero3 已提交
206
	};
G
gero3 已提交
207

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

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

		if ( parameters.shaderID ) {

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

		} else {

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

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

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

			}

		}

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

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

		}

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

	};

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

		var program;

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

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

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

				break;

			}

		}

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

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

G
gero3 已提交
269
		}
G
gero3 已提交
270

271
		return program;
G
gero3 已提交
272

273 274
	};

M
Mr.doob 已提交
275
	this.releaseProgram = function ( program ) {
276 277 278 279 280 281 282 283 284 285 286 287 288 289

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

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

M
Mr.doob 已提交
294
}
R
Rich Harris 已提交
295 296


297
export { WebGLPrograms };