|
@@ -2015,27 +2015,10 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
function refreshUniformsLights ( uniforms, lights ) {
|
|
|
|
|
|
uniforms.ambientLightColor.value = lights.ambient;
|
|
|
-
|
|
|
- uniforms.directionalLightColor.value = lights.directional.colors;
|
|
|
- uniforms.directionalLightDirection.value = lights.directional.positions;
|
|
|
-
|
|
|
- uniforms.pointLightColor.value = lights.point.colors;
|
|
|
- uniforms.pointLightPosition.value = lights.point.positions;
|
|
|
- uniforms.pointLightDistance.value = lights.point.distances;
|
|
|
- uniforms.pointLightDecay.value = lights.point.decays;
|
|
|
-
|
|
|
- uniforms.spotLightColor.value = lights.spot.colors;
|
|
|
- uniforms.spotLightPosition.value = lights.spot.positions;
|
|
|
- uniforms.spotLightDistance.value = lights.spot.distances;
|
|
|
- uniforms.spotLightDirection.value = lights.spot.directions;
|
|
|
- uniforms.spotLightAngleCos.value = lights.spot.anglesCos;
|
|
|
- uniforms.spotLightExponent.value = lights.spot.exponents;
|
|
|
- uniforms.spotLightDecay.value = lights.spot.decays;
|
|
|
-
|
|
|
- uniforms.hemisphereLightSkyColor.value = lights.hemi.skyColors;
|
|
|
- uniforms.hemisphereLightGroundColor.value = lights.hemi.groundColors;
|
|
|
- uniforms.hemisphereLightDirection.value = lights.hemi.positions;
|
|
|
-
|
|
|
+ uniforms.directionalLights.value = lights.directional;
|
|
|
+ uniforms.pointLights.value = lights.point;
|
|
|
+ uniforms.spotLights.value = lights.spot;
|
|
|
+ uniforms.hemisphereLights.value = lights.hemi;
|
|
|
}
|
|
|
|
|
|
// If uniforms are marked as clean, they don't need to be loaded to the GPU.
|
|
@@ -2044,25 +2027,10 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
uniforms.ambientLightColor.needsUpdate = value;
|
|
|
|
|
|
- uniforms.directionalLightColor.needsUpdate = value;
|
|
|
- uniforms.directionalLightDirection.needsUpdate = value;
|
|
|
-
|
|
|
- uniforms.pointLightColor.needsUpdate = value;
|
|
|
- uniforms.pointLightPosition.needsUpdate = value;
|
|
|
- uniforms.pointLightDistance.needsUpdate = value;
|
|
|
- uniforms.pointLightDecay.needsUpdate = value;
|
|
|
-
|
|
|
- uniforms.spotLightColor.needsUpdate = value;
|
|
|
- uniforms.spotLightPosition.needsUpdate = value;
|
|
|
- uniforms.spotLightDistance.needsUpdate = value;
|
|
|
- uniforms.spotLightDirection.needsUpdate = value;
|
|
|
- uniforms.spotLightAngleCos.needsUpdate = value;
|
|
|
- uniforms.spotLightExponent.needsUpdate = value;
|
|
|
- uniforms.spotLightDecay.needsUpdate = value;
|
|
|
-
|
|
|
- uniforms.hemisphereLightSkyColor.needsUpdate = value;
|
|
|
- uniforms.hemisphereLightGroundColor.needsUpdate = value;
|
|
|
- uniforms.hemisphereLightDirection.needsUpdate = value;
|
|
|
+ uniforms.directionalLights.needsUpdate = value;
|
|
|
+ uniforms.pointLights.needsUpdate = value;
|
|
|
+ uniforms.spotLights.needsUpdate = value;
|
|
|
+ uniforms.hemisphereLights.needsUpdate = value;
|
|
|
|
|
|
}
|
|
|
|
|
@@ -2258,6 +2226,72 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
break;
|
|
|
|
|
|
+ case 's':
|
|
|
+
|
|
|
+ // TODO: Optimize this.
|
|
|
+ for( var propertyName in uniform.properties ) {
|
|
|
+
|
|
|
+ var property = uniform.properties[ propertyName ];
|
|
|
+ var locationProperty = location[ propertyName ];
|
|
|
+ var valueProperty = value[ propertyName ];
|
|
|
+
|
|
|
+ switch( property.type ) {
|
|
|
+ case 'f':
|
|
|
+ _gl.uniform1f( locationProperty, valueProperty );
|
|
|
+ break;
|
|
|
+ case 'v2':
|
|
|
+ _gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
|
|
|
+ break;
|
|
|
+ case 'v3':
|
|
|
+ _gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
|
|
|
+ break;
|
|
|
+ case 'v4':
|
|
|
+ _gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
|
|
|
+ break;
|
|
|
+ case 'c':
|
|
|
+ _gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
|
|
|
+ break;
|
|
|
+ };
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 'sa':
|
|
|
+
|
|
|
+ // TODO: Optimize this.
|
|
|
+ for( var i = 0; i < value.length; i ++ ) {
|
|
|
+
|
|
|
+ for( var propertyName in uniform.properties ) {
|
|
|
+
|
|
|
+ var property = uniform.properties[ propertyName ];
|
|
|
+ var locationProperty = location[ i ][ propertyName ];
|
|
|
+ var valueProperty = value[i][ propertyName ];
|
|
|
+
|
|
|
+ switch( property.type ) {
|
|
|
+ case 'f':
|
|
|
+ _gl.uniform1f( locationProperty, valueProperty );
|
|
|
+ break;
|
|
|
+ case 'v2':
|
|
|
+ _gl.uniform2f( locationProperty, valueProperty.x, valueProperty.y );
|
|
|
+ break;
|
|
|
+ case 'v3':
|
|
|
+ _gl.uniform3f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z );
|
|
|
+ break;
|
|
|
+ case 'v4':
|
|
|
+ _gl.uniform4f( locationProperty, valueProperty.x, valueProperty.y, valueProperty.z, valueProperty.w );
|
|
|
+ break;
|
|
|
+ case 'c':
|
|
|
+ _gl.uniform3f( locationProperty, valueProperty.r, valueProperty.g, valueProperty.b );
|
|
|
+ break;
|
|
|
+ };
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ break;
|
|
|
+
|
|
|
case 'iv1':
|
|
|
|
|
|
// flat array of integers (JS or typed array)
|
|
@@ -2500,60 +2534,22 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
}
|
|
|
|
|
|
- function setColorLinear( array, offset, color, intensity ) {
|
|
|
-
|
|
|
- array[ offset + 0 ] = color.r * intensity;
|
|
|
- array[ offset + 1 ] = color.g * intensity;
|
|
|
- array[ offset + 2 ] = color.b * intensity;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
function setupLights ( lights, camera ) {
|
|
|
|
|
|
var l, ll, light,
|
|
|
r = 0, g = 0, b = 0,
|
|
|
- color, skyColor, groundColor,
|
|
|
+ color,
|
|
|
intensity,
|
|
|
distance,
|
|
|
|
|
|
zlights = _lights,
|
|
|
|
|
|
- viewMatrix = camera.matrixWorldInverse,
|
|
|
-
|
|
|
- dirColors = zlights.directional.colors,
|
|
|
- dirPositions = zlights.directional.positions,
|
|
|
-
|
|
|
- pointColors = zlights.point.colors,
|
|
|
- pointPositions = zlights.point.positions,
|
|
|
- pointDistances = zlights.point.distances,
|
|
|
- pointDecays = zlights.point.decays,
|
|
|
-
|
|
|
- spotColors = zlights.spot.colors,
|
|
|
- spotPositions = zlights.spot.positions,
|
|
|
- spotDistances = zlights.spot.distances,
|
|
|
- spotDirections = zlights.spot.directions,
|
|
|
- spotAnglesCos = zlights.spot.anglesCos,
|
|
|
- spotExponents = zlights.spot.exponents,
|
|
|
- spotDecays = zlights.spot.decays,
|
|
|
-
|
|
|
- hemiSkyColors = zlights.hemi.skyColors,
|
|
|
- hemiGroundColors = zlights.hemi.groundColors,
|
|
|
- hemiPositions = zlights.hemi.positions,
|
|
|
-
|
|
|
- dirLength = 0,
|
|
|
- pointLength = 0,
|
|
|
- spotLength = 0,
|
|
|
- hemiLength = 0,
|
|
|
-
|
|
|
- dirCount = 0,
|
|
|
- pointCount = 0,
|
|
|
- spotCount = 0,
|
|
|
- hemiCount = 0,
|
|
|
+ viewMatrix = camera.matrixWorldInverse;
|
|
|
|
|
|
- dirOffset = 0,
|
|
|
- pointOffset = 0,
|
|
|
- spotOffset = 0,
|
|
|
- hemiOffset = 0;
|
|
|
+ zlights.directional = [];
|
|
|
+ zlights.point = [];
|
|
|
+ zlights.spot = [];
|
|
|
+ zlights.hemi = [];
|
|
|
|
|
|
for ( l = 0, ll = lights.length; l < ll; l ++ ) {
|
|
|
|
|
@@ -2573,122 +2569,119 @@ THREE.WebGLRenderer = function ( parameters ) {
|
|
|
|
|
|
} else if ( light instanceof THREE.DirectionalLight ) {
|
|
|
|
|
|
- dirCount += 1;
|
|
|
-
|
|
|
- if ( ! light.visible ) continue;
|
|
|
-
|
|
|
- _direction.setFromMatrixPosition( light.matrixWorld );
|
|
|
- _vector3.setFromMatrixPosition( light.target.matrixWorld );
|
|
|
- _direction.sub( _vector3 );
|
|
|
- _direction.transformDirection( viewMatrix );
|
|
|
+ if( ! light.__webglUniforms ) {
|
|
|
+ light.__webglUniforms = {
|
|
|
+ direction: new THREE.Vector3(),
|
|
|
+ color: new THREE.Color()
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- dirOffset = dirLength * 3;
|
|
|
+ var lightUniforms = light.__webglUniforms;
|
|
|
+ zlights.directional.push( lightUniforms );
|
|
|
|
|
|
- dirPositions[ dirOffset + 0 ] = _direction.x;
|
|
|
- dirPositions[ dirOffset + 1 ] = _direction.y;
|
|
|
- dirPositions[ dirOffset + 2 ] = _direction.z;
|
|
|
+ if ( ! light.visible ) {
|
|
|
+ lightUniforms.color.setRGB( 0, 0, 0 );
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- setColorLinear( dirColors, dirOffset, color, intensity );
|
|
|
+ lightUniforms.direction.setFromMatrixPosition( light.matrixWorld );
|
|
|
+ _vector3.setFromMatrixPosition( light.target.matrixWorld );
|
|
|
+ lightUniforms.direction.sub( _vector3 );
|
|
|
+ lightUniforms.direction.transformDirection( viewMatrix );
|
|
|
|
|
|
- dirLength += 1;
|
|
|
+ lightUniforms.color.copy( light.color ).multiplyScalar( light.intensity );
|
|
|
|
|
|
} else if ( light instanceof THREE.PointLight ) {
|
|
|
|
|
|
- pointCount += 1;
|
|
|
-
|
|
|
- if ( ! light.visible ) continue;
|
|
|
-
|
|
|
- pointOffset = pointLength * 3;
|
|
|
-
|
|
|
- setColorLinear( pointColors, pointOffset, color, intensity );
|
|
|
+ if( ! light.__webglUniforms ) {
|
|
|
+ light.__webglUniforms = {
|
|
|
+ position: new THREE.Vector3(),
|
|
|
+ color: new THREE.Color(),
|
|
|
+ distance: 0,
|
|
|
+ decay: 0
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- _vector3.setFromMatrixPosition( light.matrixWorld );
|
|
|
- _vector3.applyMatrix4( viewMatrix );
|
|
|
+ var lightUniforms = light.__webglUniforms;
|
|
|
+ zlights.point.push( lightUniforms );
|
|
|
|
|
|
- pointPositions[ pointOffset + 0 ] = _vector3.x;
|
|
|
- pointPositions[ pointOffset + 1 ] = _vector3.y;
|
|
|
- pointPositions[ pointOffset + 2 ] = _vector3.z;
|
|
|
+ if ( ! light.visible ) {
|
|
|
+ lightUniforms.color.setRGB( 0, 0, 0 );
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- // distance is 0 if decay is 0, because there is no attenuation at all.
|
|
|
- pointDistances[ pointLength ] = distance;
|
|
|
- pointDecays[ pointLength ] = ( light.distance === 0 ) ? 0.0 : light.decay;
|
|
|
+ lightUniforms.position.setFromMatrixPosition( light.matrixWorld );
|
|
|
+ lightUniforms.position.applyMatrix4( viewMatrix );
|
|
|
|
|
|
- pointLength += 1;
|
|
|
+ lightUniforms.color.copy( light.color ).multiplyScalar( light.intensity );
|
|
|
+ lightUniforms.distance = light.distance;
|
|
|
+ lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
|
|
|
|
|
|
} else if ( light instanceof THREE.SpotLight ) {
|
|
|
|
|
|
- spotCount += 1;
|
|
|
-
|
|
|
- if ( ! light.visible ) continue;
|
|
|
-
|
|
|
- spotOffset = spotLength * 3;
|
|
|
+ if( ! light.__webglUniforms ) {
|
|
|
+ light.__webglUniforms = {
|
|
|
+ position: new THREE.Vector3(),
|
|
|
+ direction: new THREE.Vector3(),
|
|
|
+ color: new THREE.Color(),
|
|
|
+ distance: 0,
|
|
|
+ decay: 0,
|
|
|
+ angleCos: 0
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- setColorLinear( spotColors, spotOffset, color, intensity );
|
|
|
+ var lightUniforms = light.__webglUniforms;
|
|
|
+ zlights.spot.push( lightUniforms );
|
|
|
|
|
|
- _direction.setFromMatrixPosition( light.matrixWorld );
|
|
|
- _vector3.copy( _direction ).applyMatrix4( viewMatrix );
|
|
|
+ if ( ! light.visible ) {
|
|
|
+ lightUniforms.color.setRGB( 0, 0, 0 );
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- spotPositions[ spotOffset + 0 ] = _vector3.x;
|
|
|
- spotPositions[ spotOffset + 1 ] = _vector3.y;
|
|
|
- spotPositions[ spotOffset + 2 ] = _vector3.z;
|
|
|
+ lightUniforms.position.setFromMatrixPosition( light.matrixWorld );
|
|
|
+ lightUniforms.position.applyMatrix4( viewMatrix );
|
|
|
|
|
|
- spotDistances[ spotLength ] = distance;
|
|
|
+ lightUniforms.color.copy( color ).multiplyScalar( intensity );
|
|
|
+ lightUniforms.distance = distance;
|
|
|
|
|
|
+ lightUniforms.direction.setFromMatrixPosition( light.matrixWorld );
|
|
|
_vector3.setFromMatrixPosition( light.target.matrixWorld );
|
|
|
- _direction.sub( _vector3 );
|
|
|
- _direction.transformDirection( viewMatrix );
|
|
|
+ lightUniforms.direction.sub( _vector3 );
|
|
|
+ lightUniforms.direction.transformDirection( viewMatrix );
|
|
|
|
|
|
- spotDirections[ spotOffset + 0 ] = _direction.x;
|
|
|
- spotDirections[ spotOffset + 1 ] = _direction.y;
|
|
|
- spotDirections[ spotOffset + 2 ] = _direction.z;
|
|
|
-
|
|
|
- spotAnglesCos[ spotLength ] = Math.cos( light.angle );
|
|
|
- spotExponents[ spotLength ] = light.exponent;
|
|
|
- spotDecays[ spotLength ] = ( light.distance === 0 ) ? 0.0 : light.decay;
|
|
|
-
|
|
|
- spotLength += 1;
|
|
|
+ lightUniforms.angleCos = Math.cos( light.angle );
|
|
|
+ lightUniforms.exponent = light.exponent;
|
|
|
+ lightUniforms.decay = ( light.distance === 0 ) ? 0.0 : light.decay;
|
|
|
|
|
|
} else if ( light instanceof THREE.HemisphereLight ) {
|
|
|
|
|
|
- hemiCount += 1;
|
|
|
-
|
|
|
- if ( ! light.visible ) continue;
|
|
|
-
|
|
|
- _direction.setFromMatrixPosition( light.matrixWorld );
|
|
|
- _direction.transformDirection( viewMatrix );
|
|
|
-
|
|
|
- hemiOffset = hemiLength * 3;
|
|
|
+ if( ! light.__webglUniforms ) {
|
|
|
+ light.__webglUniforms = {
|
|
|
+ direction: new THREE.Vector3(),
|
|
|
+ skyColor: new THREE.Color(),
|
|
|
+ groundColor: new THREE.Color()
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
- hemiPositions[ hemiOffset + 0 ] = _direction.x;
|
|
|
- hemiPositions[ hemiOffset + 1 ] = _direction.y;
|
|
|
- hemiPositions[ hemiOffset + 2 ] = _direction.z;
|
|
|
+ var lightUniforms = light.__webglUniforms;
|
|
|
+ zlights.hemi.push( lightUniforms );
|
|
|
|
|
|
- skyColor = light.color;
|
|
|
- groundColor = light.groundColor;
|
|
|
+ if ( ! light.visible ) {
|
|
|
+ lightUniforms.skyColor.setRGB( 0, 0, 0 );
|
|
|
+ continue;
|
|
|
+ }
|
|
|
|
|
|
- setColorLinear( hemiSkyColors, hemiOffset, skyColor, intensity );
|
|
|
- setColorLinear( hemiGroundColors, hemiOffset, groundColor, intensity );
|
|
|
+ lightUniforms.direction.setFromMatrixPosition( light.matrixWorld );
|
|
|
+ lightUniforms.direction.transformDirection( viewMatrix );
|
|
|
+ lightUniforms.direction.normalize();
|
|
|
|
|
|
- hemiLength += 1;
|
|
|
+ lightUniforms.skyColor.copy( light.color ).multiplyScalar( intensity );
|
|
|
+ lightUniforms.groundColor.copy( light.groundColor ).multiplyScalar( intensity );
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
- // null eventual remains from removed lights
|
|
|
- // (this is to avoid if in shader)
|
|
|
-
|
|
|
- for ( l = dirLength * 3, ll = Math.max( dirColors.length, dirCount * 3 ); l < ll; l ++ ) dirColors[ l ] = 0.0;
|
|
|
- for ( l = pointLength * 3, ll = Math.max( pointColors.length, pointCount * 3 ); l < ll; l ++ ) pointColors[ l ] = 0.0;
|
|
|
- for ( l = spotLength * 3, ll = Math.max( spotColors.length, spotCount * 3 ); l < ll; l ++ ) spotColors[ l ] = 0.0;
|
|
|
- for ( l = hemiLength * 3, ll = Math.max( hemiSkyColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiSkyColors[ l ] = 0.0;
|
|
|
- for ( l = hemiLength * 3, ll = Math.max( hemiGroundColors.length, hemiCount * 3 ); l < ll; l ++ ) hemiGroundColors[ l ] = 0.0;
|
|
|
-
|
|
|
- zlights.directional.length = dirLength;
|
|
|
- zlights.point.length = pointLength;
|
|
|
- zlights.spot.length = spotLength;
|
|
|
- zlights.hemi.length = hemiLength;
|
|
|
-
|
|
|
zlights.ambient[ 0 ] = r;
|
|
|
zlights.ambient[ 1 ] = g;
|
|
|
zlights.ambient[ 2 ] = b;
|