dist/claygl.es.js
function (light) {
        var volumeMesh;
        if (light.volumeMesh) {
            volumeMesh = light.volumeMesh;
        }
        else {
            switch (light.type) {
                // Only local light (point and spot) needs volume mesh.
                // Directional and ambient light renders in full quad
                case 'POINT_LIGHT':
                case 'SPHERE_LIGHT':
                    var shader = light.type === 'SPHERE_LIGHT'
                        ? this._sphereLightShader : this._pointLightShader;
                    // Volume mesh created automatically
                    if (!light.__volumeMesh) {
                        light.__volumeMesh = new Mesh({
                            material: this._createLightPassMat(shader),
                            geometry: this._lightSphereGeo,
                            // Disable culling
                            // if light volume mesh intersect camera near plane
                            // We need mesh inside can still be rendered
                            culling: false
                        });
                    }
                    volumeMesh = light.__volumeMesh;
                    var r = light.range + (light.radius || 0);
                    volumeMesh.scale.set(r, r, r);
                    break;
                case 'SPOT_LIGHT':
                    light.__volumeMesh = light.__volumeMesh || new Mesh({
                        material: this._createLightPassMat(this._spotLightShader),
                        geometry: this._lightConeGeo,
                        culling: false
                    });
                    volumeMesh = light.__volumeMesh;
                    var aspect = Math.tan(light.penumbraAngle * Math.PI / 180);
                    var range = light.range;
                    volumeMesh.scale.set(aspect * range, aspect * range, range / 2);
                    break;
                case 'TUBE_LIGHT':
                    light.__volumeMesh = light.__volumeMesh || new Mesh({
                        material: this._createLightPassMat(this._tubeLightShader),
                        geometry: this._lightCylinderGeo,
                        culling: false
                    });
                    volumeMesh = light.__volumeMesh;
                    var range = light.range;
                    volumeMesh.scale.set(light.length / 2 + range, range, range);
                    break;
            }
        }
        if (volumeMesh) {
            volumeMesh.update();
            // Apply light transform
            Matrix4.multiply(volumeMesh.worldTransform, light.worldTransform, volumeMesh.worldTransform);
            var hasShadow = this.shadowMapPass && light.castShadow;
            volumeMesh.material[hasShadow ? 'define' : 'undefine']('fragment', 'SHADOWMAP_ENABLED');
        }
    }
function (light) {
        var volumeMesh;
        if (light.volumeMesh) {
            volumeMesh = light.volumeMesh;
        }
        else {
            switch (light.type) {
                // Only local light (point and spot) needs volume mesh.
                // Directional and ambient light renders in full quad
                case 'POINT_LIGHT':
                case 'SPHERE_LIGHT':
                    var shader = light.type === 'SPHERE_LIGHT'
                        ? this._sphereLightShader : this._pointLightShader;
                    // Volume mesh created automatically
                    if (!light.__volumeMesh) {
                        light.__volumeMesh = new Mesh({
                            material: this._createLightPassMat(shader),
                            geometry: this._lightSphereGeo,
                            // Disable culling
                            // if light volume mesh intersect camera near plane
                            // We need mesh inside can still be rendered
                            culling: false
                        });
                    }
                    volumeMesh = light.__volumeMesh;
                    var r = light.range + (light.radius || 0);
                    volumeMesh.scale.set(r, r, r);
                    break;
                case 'SPOT_LIGHT':
                    light.__volumeMesh = light.__volumeMesh || new Mesh({
                        material: this._createLightPassMat(this._spotLightShader),
                        geometry: this._lightConeGeo,
                        culling: false
                    });
                    volumeMesh = light.__volumeMesh;
                    var aspect = Math.tan(light.penumbraAngle * Math.PI / 180);
                    var range = light.range;
                    volumeMesh.scale.set(aspect * range, aspect * range, range / 2);
                    break;
                case 'TUBE_LIGHT':
                    light.__volumeMesh = light.__volumeMesh || new Mesh({
                        material: this._createLightPassMat(this._tubeLightShader),
                        geometry: this._lightCylinderGeo,
                        culling: false
                    });
                    volumeMesh = light.__volumeMesh;
                    var range = light.range;
                    volumeMesh.scale.set(light.length / 2 + range, range, range);
                    break;
            }
        }
        if (volumeMesh) {
            volumeMesh.update();
            // Apply light transform
            Matrix4.multiply(volumeMesh.worldTransform, light.worldTransform, volumeMesh.worldTransform);
            var hasShadow = this.shadowMapPass && light.castShadow;
            volumeMesh.material[hasShadow ? 'define' : 'undefine']('fragment', 'SHADOWMAP_ENABLED');
        }
    }
function ( light ) { var volumeMesh ; if ( light . volumeMesh ) { volumeMesh = light . volumeMesh ; } else { switch ( light . type ) { // Only local light (point and spot) needs volume mesh. // Directional and ambient light renders in full quad case 'POINT_LIGHT' : case 'SPHERE_LIGHT' : var shader = light . type === 'SPHERE_LIGHT' ? this . _sphereLightShader : this . _pointLightShader ; // Volume mesh created automatically if ( ! light . __volumeMesh ) { light . __volumeMesh = new Mesh ( { material : this . _createLightPassMat ( shader ) , geometry : this . _lightSphereGeo , // Disable culling // if light volume mesh intersect camera near plane // We need mesh inside can still be rendered culling : false } ) ; } volumeMesh = light . __volumeMesh ; var r = light . range + ( light . radius || 0 ) ; volumeMesh . scale . set ( r , r , r ) ; break ; case 'SPOT_LIGHT' : light . __volumeMesh = light . __volumeMesh || new Mesh ( { material : this . _createLightPassMat ( this . _spotLightShader ) , geometry : this . _lightConeGeo , culling : false } ) ; volumeMesh = light . __volumeMesh ; var aspect = Math . tan ( light . penumbraAngle * Math . PI / 180 ) ; var range = light . range ; volumeMesh . scale . set ( aspect * range , aspect * range , range / 2 ) ; break ; case 'TUBE_LIGHT' : light . __volumeMesh = light . __volumeMesh || new Mesh ( { material : this . _createLightPassMat ( this . _tubeLightShader ) , geometry : this . _lightCylinderGeo , culling : false } ) ; volumeMesh = light . __volumeMesh ; var range = light . range ; volumeMesh . scale . set ( light . length / 2 + range , range , range ) ; break ; } } if ( volumeMesh ) { volumeMesh . update ( ) ; // Apply light transform Matrix4 . multiply ( volumeMesh . worldTransform , light . worldTransform , volumeMesh . worldTransform ) ; var hasShadow = this . shadowMapPass && light . castShadow ; volumeMesh . material [ hasShadow ? 'define' : 'undefine' ] ( 'fragment' , 'SHADOWMAP_ENABLED' ) ; } }
Update light volume mesh Light volume mesh is rendered in light accumulate pass instead of full quad. It will reduce pixels significantly when local light is relatively small. And we can use custom volume mesh to shape the light.  See "Deferred Shading Optimizations" in GDC2011
Update light volume mesh Light volume mesh is rendered in light accumulate pass instead of full quad . It will reduce pixels significantly when local light is relatively small . And we can use custom volume mesh to shape the light . See Deferred Shading Optimizations in GDC2011