Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add WebglProgramCache #7072

Merged
merged 6 commits into from
Sep 7, 2015
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 12 additions & 238 deletions src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ THREE.WebGLRenderer = function ( parameters ) {
var state = new THREE.WebGLState( _gl, extensions, paramThreeToGL );
var properties = new THREE.WebGLProperties();
var objects = new THREE.WebGLObjects( _gl, properties, this.info );
var programCache = new THREE.WebGLProgramCache( this, _gl, extensions );

var bufferRenderer = new THREE.WebGLBufferRenderer( _gl, extensions, _infoRender );
var indexedBufferRenderer = new THREE.WebGLIndexedBufferRenderer( _gl, extensions, _infoRender );
Expand Down Expand Up @@ -262,6 +263,7 @@ THREE.WebGLRenderer = function ( parameters ) {
this.context = _gl;
this.extensions = extensions;
this.state = state;
this.logarithmicDepthBuffer = _logarithmicDepthBuffer;
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of adding properties to the renderer I would pass this in the WebGLProgramCache constructor. It's a temporal ugliness, but that way we don't have issues in case users start accessing that property.

I suspect that's what you mean with WebGLCapabilities?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This will be fixed by #7075


// shadow map

Expand Down Expand Up @@ -1291,7 +1293,7 @@ THREE.WebGLRenderer = function ( parameters ) {

pushImmediateRenderItem( object );

} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.PointCloud ){
} else if ( object instanceof THREE.Mesh || object instanceof THREE.Line || object instanceof THREE.PointCloud ) {

if ( object instanceof THREE.SkinnedMesh ) {

Expand Down Expand Up @@ -1403,134 +1405,13 @@ THREE.WebGLRenderer = function ( parameters ) {

}

// Materials

var shaderIDs = {
MeshDepthMaterial: 'depth',
MeshNormalMaterial: 'normal',
MeshBasicMaterial: 'basic',
MeshLambertMaterial: 'lambert',
MeshPhongMaterial: 'phong',
LineBasicMaterial: 'basic',
LineDashedMaterial: 'dashed',
PointCloudMaterial: 'particle_basic'
};

function initMaterial( material, lights, fog, object ) {

var materialProperties = properties.get( material );

var shaderID = shaderIDs[ material.type ];

// heuristics to create shader parameters according to lights in the scene
// (not to blow over maxLights budget)

var maxLightCount = allocateLights( lights );
var maxShadows = allocateShadows( lights );
var maxBones = allocateBones( object );
var precision = _precision;

if ( material.precision !== null ) {

precision = state.getMaxPrecision( material.precision );

if ( precision !== material.precision ) {

console.warn( 'THREE.WebGLRenderer.initMaterial:', material.precision, 'not supported, using', precision, 'instead.' );

}

}

var parameters = {

precision: precision,
supportsVertexTextures: _supportsVertexTextures,

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,
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,
logarithmicDepthBuffer: _logarithmicDepthBuffer,

skinning: material.skinning,
maxBones: maxBones,
useVertexTexture: _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture,

morphTargets: material.morphTargets,
morphNormals: material.morphNormals,
maxMorphTargets: _this.maxMorphTargets,
maxMorphNormals: _this.maxMorphNormals,

maxDirLights: maxLightCount.directional,
maxPointLights: maxLightCount.point,
maxSpotLights: maxLightCount.spot,
maxHemiLights: maxLightCount.hemi,

maxShadows: maxShadows,
shadowMapEnabled: shadowMap.enabled && object.receiveShadow && maxShadows > 0,
shadowMapType: shadowMap.type,
shadowMapDebug: shadowMap.debug,

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

};
var parameters = programCache.getParameters( material, lights, fog, object );
var code = programCache.getProgramCode( material, parameters );

// Generate code

var chunks = [];

if ( shaderID ) {

chunks.push( 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 ] );

}

}

for ( var name in parameters ) {

chunks.push( name );
chunks.push( parameters[ name ] );

}

var code = chunks.join();
var programChange = true;

if ( ! materialProperties.program ) {
Expand All @@ -1543,7 +1424,7 @@ THREE.WebGLRenderer = function ( parameters ) {
// changed glsl or parameters
releaseMaterialProgramReference( material );

} else if ( shaderID !== undefined ) {
} else if ( parameters.shaderID !== undefined ) {

// same glsl and uniform list
return;
Expand All @@ -1555,9 +1436,9 @@ THREE.WebGLRenderer = function ( parameters ) {

}

if ( shaderID ) {
if ( parameters.shaderID ) {

var shader = THREE.ShaderLib[ shaderID ];
var shader = THREE.ShaderLib[ parameters.shaderID ];

materialProperties.__webglShader = {
name: material.type,
Expand All @@ -1577,37 +1458,13 @@ THREE.WebGLRenderer = function ( parameters ) {

}

var program;

// Check if code has been already compiled

for ( var p = 0, pl = _programs.length; p < pl; p ++ ) {

var programInfo = _programs[ p ];

if ( programInfo.code === code ) {

program = programInfo;

if ( programChange ) {
material.__webglShader = materialProperties.__webglShader;

program.usedTimes ++;
var program = programCache.getProgram( material, parameters, code );

}

break;

}

}
if ( programChange ) {

if ( program === undefined ) {

material.__webglShader = materialProperties.__webglShader;
program = new THREE.WebGLProgram( _this, code, material, parameters );
_programs.push( program );

_infoMemory.programs = _programs.length;
program.usedTimes ++;

}

Expand Down Expand Up @@ -3504,89 +3361,6 @@ THREE.WebGLRenderer = function ( parameters ) {

}

// Allocations

function allocateBones ( object ) {

if ( _supportsBoneTextures && object && object.skeleton && object.skeleton.useVertexTexture ) {

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)

var nVertexUniforms = _gl.getParameter( _gl.MAX_VERTEX_UNIFORM_VECTORS );
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;

}

}

function allocateLights( lights ) {

var dirLights = 0;
var pointLights = 0;
var spotLights = 0;
var hemiLights = 0;

for ( var l = 0, ll = lights.length; l < ll; l ++ ) {

var light = lights[ l ];

if ( light.onlyShadow || light.visible === false ) continue;

if ( light instanceof THREE.DirectionalLight ) dirLights ++;
if ( light instanceof THREE.PointLight ) pointLights ++;
if ( light instanceof THREE.SpotLight ) spotLights ++;
if ( light instanceof THREE.HemisphereLight ) hemiLights ++;

}

return { 'directional': dirLights, 'point': pointLights, 'spot': spotLights, 'hemi': hemiLights };

}

function allocateShadows( lights ) {

var maxShadows = 0;

for ( var l = 0, ll = lights.length; l < ll; l ++ ) {

var light = lights[ l ];

if ( ! light.castShadow ) continue;

if ( light instanceof THREE.SpotLight ) maxShadows ++;
if ( light instanceof THREE.DirectionalLight ) maxShadows ++;

}

return maxShadows;

}

// DEPRECATED

this.supportsFloatTextures = function () {
Expand Down
Loading