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

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

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',
G
gero3 已提交
22 23
		LineBasicMaterial: 'basic',
		LineDashedMaterial: 'dashed',
24 25
		PointsMaterial: 'points',
		ShadowMaterial: 'shadow'
G
gero3 已提交
26
	};
G
gero3 已提交
27

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


M
Mr.doob 已提交
42
	function allocateBones( object ) {
G
gero3 已提交
43

44 45 46 47 48
		var skeleton = object.skeleton;
		var bones = skeleton.bones;

		if ( capabilities.floatVertexTextures ) {

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

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

65
			if ( maxBones < bones.length ) {
G
gero3 已提交
66

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

			}

			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, shadows, 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
		// (not to blow over maxLights budget)

115
		var maxBones = object.isSkinnedMesh ? allocateBones( object ) : 0;
116
		var precision = capabilities.precision;
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
		var currentRenderTarget = renderer.getRenderTarget();
131

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,
M
Mr.doob 已提交
165
			fogExp: ( fog && fog.isFogExp2 ),
G
gero3 已提交
166

167
			flatShading: material.flatShading,
G
gero3 已提交
168 169

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

M
Mr.doob 已提交
172
			skinning: material.skinning && maxBones > 0,
G
gero3 已提交
173
			maxBones: maxBones,
174
			useVertexTexture: capabilities.floatVertexTextures,
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
			dithering: material.dithering,
191

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

B
Ben Houston 已提交
195
			toneMapping: renderer.toneMapping,
196
			physicallyCorrectLights: renderer.physicallyCorrectLights,
B
Ben Houston 已提交
197

198 199
			premultipliedAlpha: material.premultipliedAlpha,

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

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

		};
207

G
gero3 已提交
208
		return parameters;
G
gero3 已提交
209

G
gero3 已提交
210
	};
G
gero3 已提交
211

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

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

		if ( parameters.shaderID ) {

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

		} else {

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

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

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

			}

		}

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

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

		}

M
Mr.doob 已提交
244 245
		array.push( material.onBeforeCompile.toString() );

246 247
		array.push( renderer.gammaOutput );

M
Mr.doob 已提交
248
		return array.join();
G
gero3 已提交
249 250 251

	};

252
	this.acquireProgram = function ( material, shader, parameters, code ) {
G
gero3 已提交
253 254 255 256

		var program;

		// Check if code has been already compiled
G
gero3 已提交
257 258 259 260 261 262 263
		for ( var p = 0, pl = programs.length; p < pl; p ++ ) {

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

				program = programInfo;
264
				++ program.usedTimes;
G
gero3 已提交
265 266 267 268 269 270 271 272

				break;

			}

		}

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

274
			program = new WebGLProgram( renderer, extensions, code, material, shader, parameters );
G
gero3 已提交
275
			programs.push( program );
G
gero3 已提交
276

G
gero3 已提交
277
		}
G
gero3 已提交
278

279
		return program;
G
gero3 已提交
280

281 282
	};

M
Mr.doob 已提交
283
	this.releaseProgram = function ( program ) {
284 285 286 287 288 289 290 291 292 293 294 295 296 297

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

299 300 301
	// Exposed for resource monitoring & error feedback via renderer.info:
	this.programs = programs;

M
Mr.doob 已提交
302
}
R
Rich Harris 已提交
303 304


305
export { WebGLPrograms };