WebGLPrograms.js 6.1 KB
Newer Older
M
Mr.doob 已提交
1
THREE.WebGLPrograms = function ( renderer, capabilities ) {
G
gero3 已提交
2

3
	var programs = [];
G
gero3 已提交
4

G
gero3 已提交
5 6 7 8 9 10
	var shaderIDs = {
		MeshDepthMaterial: 'depth',
		MeshNormalMaterial: 'normal',
		MeshBasicMaterial: 'basic',
		MeshLambertMaterial: 'lambert',
		MeshPhongMaterial: 'phong',
11
		MeshStandardMaterial: 'standard',
G
gero3 已提交
12 13
		LineBasicMaterial: 'basic',
		LineDashedMaterial: 'dashed',
14
		PointsMaterial: 'points'
G
gero3 已提交
15
	};
G
gero3 已提交
16

M
Mr.doob 已提交
17 18
	var parameterNames = [
		"precision", "supportsVertexTextures", "map", "envMap", "envMapMode",
M
Mr.doob 已提交
19
		"lightMap", "aoMap", "emissiveMap", "bumpMap", "normalMap", "displacementMap", "specularMap",
W
WestLangley 已提交
20
		"roughnessMap", "reflectivityMap", "metalnessMap",
M
Mr.doob 已提交
21 22 23
		"alphaMap", "combine", "vertexColors", "fog", "useFog", "fogExp",
		"flatShading", "sizeAttenuation", "logarithmicDepthBuffer", "skinning",
		"maxBones", "useVertexTexture", "morphTargets", "morphNormals",
24
		"maxMorphTargets", "maxMorphNormals", "numDirLights", "numPointLights",
25
		"numSpotLights", "numHemiLights", "numShadows", "shadowMapEnabled", "pointLightShadows",
26
		"shadowMapType", "shadowMapDebug", "alphaTest", "doubleSided",
M
Mr.doob 已提交
27 28
		"flipSided"
	];
G
gero3 已提交
29 30


G
gero3 已提交
31 32
	function allocateBones ( object ) {

G
gero3 已提交
33
		if ( capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {
G
gero3 已提交
34 35 36 37 38 39 40 41 42 43 44 45

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

			var maxBones = nVertexMatrices;

			if ( object !== undefined && object instanceof THREE.SkinnedMesh ) {

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

M
Mr.doob 已提交
69
	this.getParameters = function ( material, lights, fog, object ) {
G
gero3 已提交
70 71 72

		var shaderID = shaderIDs[ material.type ];
		// heuristics to create shader parameters according to lights in the scene
G
gero3 已提交
73 74 75
		// (not to blow over maxLights budget)

		var maxBones = allocateBones( object );
M
Mr.doob 已提交
76
		var precision = renderer.getPrecision();
G
gero3 已提交
77 78 79

		if ( material.precision !== null ) {

G
gero3 已提交
80
			precision = capabilities.getMaxPrecision( material.precision );
G
gero3 已提交
81 82 83

			if ( precision !== material.precision ) {

84
				console.warn( 'THREE.WebGLProgram.getParameters:', material.precision, 'not supported, using', precision, 'instead.' );
G
gero3 已提交
85 86 87 88 89 90

			}

		}

		var parameters = {
G
gero3 已提交
91 92

			shaderID: shaderID,
G
gero3 已提交
93 94

			precision: precision,
G
gero3 已提交
95
			supportsVertexTextures: capabilities.vertexTextures,
G
gero3 已提交
96 97 98 99 100 101 102 103 104

			map: !! material.map,
			envMap: !! material.envMap,
			envMapMode: material.envMap && material.envMap.mapping,
			lightMap: !! material.lightMap,
			aoMap: !! material.aoMap,
			emissiveMap: !! material.emissiveMap,
			bumpMap: !! material.bumpMap,
			normalMap: !! material.normalMap,
105
			displacementMap: !! material.displacementMap,
W
WestLangley 已提交
106 107 108
			roughnessMap: !! material.roughnessMap,
			reflectivityMap: !! material.reflectivityMap,
			metalnessMap: !! material.metalnessMap,
G
gero3 已提交
109 110 111 112 113 114 115 116 117 118 119 120 121 122
			specularMap: !! material.specularMap,
			alphaMap: !! material.alphaMap,

			combine: material.combine,

			vertexColors: material.vertexColors,

			fog: fog,
			useFog: material.fog,
			fogExp: fog instanceof THREE.FogExp2,

			flatShading: material.shading === THREE.FlatShading,

			sizeAttenuation: material.sizeAttenuation,
123
			logarithmicDepthBuffer: capabilities.logarithmicDepthBuffer,
G
gero3 已提交
124 125 126

			skinning: material.skinning,
			maxBones: maxBones,
G
gero3 已提交
127
			useVertexTexture: capabilities.floatVertexTextures && object && object.skeleton && object.skeleton.useVertexTexture,
G
gero3 已提交
128 129 130

			morphTargets: material.morphTargets,
			morphNormals: material.morphNormals,
M
Mr.doob 已提交
131 132
			maxMorphTargets: renderer.maxMorphTargets,
			maxMorphNormals: renderer.maxMorphNormals,
G
gero3 已提交
133

134 135 136 137
			numDirLights: lights.directional.length,
			numPointLights: lights.point.length,
			numSpotLights: lights.spot.length,
			numHemiLights: lights.hemi.length,
138

139
			numShadows: lights.shadows.length,
140
			pointLightShadows: lights.shadowsPointLight,
G
gero3 已提交
141

142
			shadowMapEnabled: renderer.shadowMap.enabled && object.receiveShadow && lights.shadows.length > 0,
M
Mr.doob 已提交
143 144
			shadowMapType: renderer.shadowMap.type,
			shadowMapDebug: renderer.shadowMap.debug,
G
gero3 已提交
145 146 147 148 149 150

			alphaTest: material.alphaTest,
			doubleSided: material.side === THREE.DoubleSide,
			flipSided: material.side === THREE.BackSide

		};
G
gero3 已提交
151

G
gero3 已提交
152
		return parameters;
G
gero3 已提交
153

G
gero3 已提交
154
	};
G
gero3 已提交
155

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

G
gero3 已提交
158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
		var chunks = [];

		if ( parameters.shaderID ) {

			chunks.push( parameters.shaderID );

		} else {

			chunks.push( material.fragmentShader );
			chunks.push( material.vertexShader );

		}

		if ( material.defines !== undefined ) {

			for ( var name in material.defines ) {

				chunks.push( name );
				chunks.push( material.defines[ name ] );

			}

		}

G
gero3 已提交
182 183 184
		for ( var i = 0; i < parameterNames.length; i ++ ) {

			var parameterName = parameterNames[ i ];
G
gero3 已提交
185 186 187 188 189 190
			chunks.push( parameterName );
			chunks.push( parameters[ parameterName ] );

		}

		return chunks.join();
G
gero3 已提交
191 192 193

	};

194
	this.acquireProgram = function ( material, parameters, code ) {
G
gero3 已提交
195 196 197 198

		var program;

		// Check if code has been already compiled
G
gero3 已提交
199 200 201 202 203 204 205
		for ( var p = 0, pl = programs.length; p < pl; p ++ ) {

			var programInfo = programs[ p ];

			if ( programInfo.code === code ) {

				program = programInfo;
206
				++ program.usedTimes;
G
gero3 已提交
207 208 209 210 211 212 213 214

				break;

			}

		}

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

M
Mr.doob 已提交
216
			program = new THREE.WebGLProgram( renderer, code, material, parameters );
G
gero3 已提交
217
			programs.push( program );
G
gero3 已提交
218

G
gero3 已提交
219
		}
G
gero3 已提交
220

221
		return program;
G
gero3 已提交
222

223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239
	};

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

241 242 243
	// Exposed for resource monitoring & error feedback via renderer.info:
	this.programs = programs;

G
gero3 已提交
244
};