From 7065b8632a6c4c910bfec45cacb68a1154cdd3c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mathieu=20Br=C3=A9dif?= Date: Tue, 7 Aug 2018 18:20:06 +0200 Subject: [PATCH] light.target optional + optional camera construction param --- examples/js/loaders/GLTFLoader.js | 2 ++ .../js/renderers/WebGLDeferredRenderer.js | 19 ++++------- examples/webgl_lights_spotlight.html | 1 + examples/webgl_lights_spotlights.html | 2 ++ examples/webgl_loader_md2_control.html | 1 + examples/webgl_loader_nrrd.html | 1 + examples/webgl_loader_vrml.html | 1 + examples/webgl_loader_vtk.html | 1 + examples/webgl_materials_cubemap_dynamic.html | 5 ++- examples/webgl_shadowmap.html | 2 +- examples/webgl_shadowmap_pcss.html | 1 + examples/webgl_shadowmap_performance.html | 2 +- examples/webgl_shadowmap_viewer.html | 2 ++ examples/webvr_sandbox.html | 6 ++-- src/helpers/DirectionalLightHelper.js | 34 +++++-------------- src/helpers/SpotLightHelper.js | 33 ++++++------------ src/lights/DirectionalLight.js | 9 +++-- src/lights/DirectionalLightShadow.js | 5 +-- src/lights/SpotLight.js | 9 +++-- src/lights/SpotLightShadow.js | 5 +-- src/renderers/webgl/WebGLLights.js | 9 ++--- src/renderers/webgl/WebGLShadowMap.js | 15 ++++---- 22 files changed, 71 insertions(+), 94 deletions(-) diff --git a/examples/js/loaders/GLTFLoader.js b/examples/js/loaders/GLTFLoader.js index af2aca0c4505f1..0bc955ce047c50 100644 --- a/examples/js/loaders/GLTFLoader.js +++ b/examples/js/loaders/GLTFLoader.js @@ -291,6 +291,7 @@ THREE.GLTFLoader = ( function () { case 'directional': lightNode = new THREE.DirectionalLight( color ); + lightNode.target = new THREE.Object3D(); lightNode.target.position.set( 0, 0, 1 ); lightNode.add( lightNode.target ); break; @@ -309,6 +310,7 @@ THREE.GLTFLoader = ( function () { lightDef.spot.outerConeAngle = lightDef.spot.outerConeAngle !== undefined ? lightDef.spot.outerConeAngle : Math.PI / 4.0; lightNode.angle = lightDef.spot.outerConeAngle; lightNode.penumbra = 1.0 - lightDef.spot.innerConeAngle / lightDef.spot.outerConeAngle; + lightNode.target = new THREE.Object3D(); lightNode.target.position.set( 0, 0, 1 ); lightNode.add( lightNode.target ); break; diff --git a/examples/js/renderers/WebGLDeferredRenderer.js b/examples/js/renderers/WebGLDeferredRenderer.js index 057ed2d1dd8690..8802c64f262a85 100644 --- a/examples/js/renderers/WebGLDeferredRenderer.js +++ b/examples/js/renderers/WebGLDeferredRenderer.js @@ -890,14 +890,11 @@ THREE.WebGLDeferredRenderer = function ( parameters ) { uniforms.lightAngle.value = originalLight.angle; uniforms.lightColor.value.copy( originalLight.color ); uniforms.lightIntensity.value = originalLight.intensity; - uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ).applyMatrix4( _currentCamera.matrixWorldInverse ); + uniforms.lightPositionVS.value.setFromMatrixPosition( originalLight.matrixWorld ) + uniforms.lightPositionVS.value.applyMatrix4( _currentCamera.matrixWorldInverse ); - var vec = uniforms.lightDirectionVS.value; - var vec2 = _tmpVector3; - - vec.setFromMatrixPosition( originalLight.matrixWorld ); - vec2.setFromMatrixPosition( originalLight.target.matrixWorld ); - vec.sub( vec2 ).normalize().transformDirection( _currentCamera.matrixWorldInverse ); + originalLight.getWorldDirection( uniforms.lightDirectionVS.value ).negate(); + uniforms.lightDirectionVS.value.transformDirection( _currentCamera.matrixWorldInverse ); updateDeferredLightCommonUniforms( uniforms ); @@ -933,12 +930,8 @@ THREE.WebGLDeferredRenderer = function ( parameters ) { uniforms.lightColor.value.copy( originalLight.color ); uniforms.lightIntensity.value = originalLight.intensity; - var vec = uniforms.lightDirectionVS.value; - var vec2 = _tmpVector3; - - vec.setFromMatrixPosition( originalLight.matrixWorld ); - vec2.setFromMatrixPosition( originalLight.target.matrixWorld ); - vec.sub( vec2 ).normalize().transformDirection( _currentCamera.matrixWorldInverse ); + originalLight.getWorldDirection( uniforms.lightDirectionVS.value ).negate(); + uniforms.lightDirectionVS.value.transformDirection( _currentCamera.matrixWorldInverse ); updateDeferredLightCommonUniforms( uniforms ); diff --git a/examples/webgl_lights_spotlight.html b/examples/webgl_lights_spotlight.html index 6c973a7e69abff..5243ccb3f9bde2 100644 --- a/examples/webgl_lights_spotlight.html +++ b/examples/webgl_lights_spotlight.html @@ -82,6 +82,7 @@ spotLight = new THREE.SpotLight( 0xffffff, 1 ); spotLight.position.set( 15, 40, 35 ); + spotLight.lookAt( 0, 0, 0 ); spotLight.angle = Math.PI / 4; spotLight.penumbra = 0.05; spotLight.decay = 2; diff --git a/examples/webgl_lights_spotlights.html b/examples/webgl_lights_spotlights.html index cb011f3ded9f27..5d514d775c82b9 100644 --- a/examples/webgl_lights_spotlights.html +++ b/examples/webgl_lights_spotlights.html @@ -132,6 +132,8 @@ newObj.shadow.mapSize.width = 1024; newObj.shadow.mapSize.height = 1024; + newObj.target = scene; + return newObj; } diff --git a/examples/webgl_loader_md2_control.html b/examples/webgl_loader_md2_control.html index ffa31f11c88818..2809c108b63275 100644 --- a/examples/webgl_loader_md2_control.html +++ b/examples/webgl_loader_md2_control.html @@ -241,6 +241,7 @@ var gyro = new THREE.Gyroscope(); gyro.add( camera ); + light.target = new THREE.Object3D(); gyro.add( light, light.target ); characters[ Math.floor( nSkins / 2 ) ].root.add( gyro ); diff --git a/examples/webgl_loader_nrrd.html b/examples/webgl_loader_nrrd.html index e2d4932f839ef0..719619a1bea9df 100644 --- a/examples/webgl_loader_nrrd.html +++ b/examples/webgl_loader_nrrd.html @@ -98,6 +98,7 @@ dirLight.position.set( 200, 200, 1000 ).normalize(); camera.add( dirLight ); + dirLight.target = new THREE.Object3D(); camera.add( dirLight.target ); var loader = new THREE.NRRDLoader(); diff --git a/examples/webgl_loader_vrml.html b/examples/webgl_loader_vrml.html index 97da9834a20730..9b3ca82593a910 100644 --- a/examples/webgl_loader_vrml.html +++ b/examples/webgl_loader_vrml.html @@ -73,6 +73,7 @@ dirLight.position.set( 200, 200, 1000 ).normalize(); camera.add( dirLight ); + dirLight.target = new THREE.Object3D(); camera.add( dirLight.target ); var loader = new THREE.VRMLLoader(); diff --git a/examples/webgl_loader_vtk.html b/examples/webgl_loader_vtk.html index bdcbfa3e582e98..550eaaf1df9ab3 100644 --- a/examples/webgl_loader_vtk.html +++ b/examples/webgl_loader_vtk.html @@ -82,6 +82,7 @@ dirLight.position.set( 200, 200, 1000 ).normalize(); camera.add( dirLight ); + dirLight.target = new THREE.Object3D(); camera.add( dirLight.target ); var material = new THREE.MeshLambertMaterial( { color: 0xffffff, side: THREE.DoubleSide } ); diff --git a/examples/webgl_materials_cubemap_dynamic.html b/examples/webgl_materials_cubemap_dynamic.html index 714511750b206f..286ac2e1504d70 100644 --- a/examples/webgl_materials_cubemap_dynamic.html +++ b/examples/webgl_materials_cubemap_dynamic.html @@ -162,7 +162,7 @@ spotLight = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI/2 ); spotLight.position.set( 0, 1800, 1500 ); - spotLight.target.position.set( 0, 0, 0 ); + spotLight.lookAt( 0, 0, 0 ); spotLight.castShadow = true; spotLight.shadow.camera.near = 100; @@ -947,8 +947,7 @@ // update shadows - spotLight.target.position.x = currentCar.root.position.x; - spotLight.target.position.z = currentCar.root.position.z; + spotLight.lookAt( currentCar.root.position.x, 0, currentCar.root.position.z ); // render cube map diff --git a/examples/webgl_shadowmap.html b/examples/webgl_shadowmap.html index b44db405cfb89b..c15cb6c223770b 100644 --- a/examples/webgl_shadowmap.html +++ b/examples/webgl_shadowmap.html @@ -108,7 +108,7 @@ light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI / 2 ); light.position.set( 0, 1500, 1000 ); - light.target.position.set( 0, 0, 0 ); + light.lookAt( 0, 0, 0 ); light.castShadow = true; diff --git a/examples/webgl_shadowmap_pcss.html b/examples/webgl_shadowmap_pcss.html index df110cb41deb0b..64d711ce37ec5c 100644 --- a/examples/webgl_shadowmap_pcss.html +++ b/examples/webgl_shadowmap_pcss.html @@ -167,6 +167,7 @@ var light = new THREE.DirectionalLight( 0xdfebff, 1.75 ); light.position.set( 2, 8, 4 ); + light.lookAt( 0, 0, 0 ); light.castShadow = true; light.shadow.mapSize.width = 1024; diff --git a/examples/webgl_shadowmap_performance.html b/examples/webgl_shadowmap_performance.html index 1531ef44c6982a..9fcfc0f429822a 100644 --- a/examples/webgl_shadowmap_performance.html +++ b/examples/webgl_shadowmap_performance.html @@ -103,7 +103,7 @@ light = new THREE.SpotLight( 0xffffff, 1, 0, Math.PI/2 ); light.position.set( 0, 1500, 1000 ); - light.target.position.set( 0, 0, 0 ); + light.lookAt( 0, 0, 0 ); light.castShadow = true; diff --git a/examples/webgl_shadowmap_viewer.html b/examples/webgl_shadowmap_viewer.html index 9fdad005223477..2e40b18ed41ad1 100644 --- a/examples/webgl_shadowmap_viewer.html +++ b/examples/webgl_shadowmap_viewer.html @@ -75,6 +75,7 @@ spotLight.angle = Math.PI / 5; spotLight.penumbra = 0.3; spotLight.position.set( 10, 10, 5 ); + spotLight.lookAt( 0, 0, 0 ); spotLight.castShadow = true; spotLight.shadow.camera.near = 8; spotLight.shadow.camera.far = 30; @@ -87,6 +88,7 @@ dirLight = new THREE.DirectionalLight( 0xffffff, 1 ); dirLight.name = 'Dir. Light'; dirLight.position.set( 0, 10, 0 ); + dirLight.lookAt( 0, 0, 0 ); dirLight.castShadow = true; dirLight.shadow.camera.near = 1; dirLight.shadow.camera.far = 10; diff --git a/examples/webvr_sandbox.html b/examples/webvr_sandbox.html index f3414586d0f8df..e53267fb77961e 100644 --- a/examples/webvr_sandbox.html +++ b/examples/webvr_sandbox.html @@ -67,22 +67,20 @@ var light = new THREE.DirectionalLight( 0x8800ff ); light.position.set( - 1, 1.5, - 1.5 ); + light.lookAt( 0, 0, - 2 ); light.castShadow = true; light.shadow.camera.zoom = 4; scene.add( light ); - light.target.position.set( 0, 0, - 2 ); - scene.add( light.target ); var helper = new THREE.CameraHelper( light.shadow.camera ); // scene.add( helper ); var light = new THREE.DirectionalLight( 0xff0000 ); light.position.set( 1, 1.5, - 2.5 ); + light.lookAt( 0, 0, - 2 ); light.castShadow = true; light.shadow.camera.zoom = 4; scene.add( light ); - light.target.position.set( 0, 0, - 2 ); - scene.add( light.target ); var helper = new THREE.CameraHelper( light.shadow.camera ); // scene.add( helper ); diff --git a/src/helpers/DirectionalLightHelper.js b/src/helpers/DirectionalLightHelper.js index e920d5378e0f48..7e1c2e13d00828 100644 --- a/src/helpers/DirectionalLightHelper.js +++ b/src/helpers/DirectionalLightHelper.js @@ -4,7 +4,6 @@ * @author WestLangley / http://github.com/WestLangley */ -import { Vector3 } from '../math/Vector3.js'; import { Object3D } from '../core/Object3D.js'; import { Line } from '../objects/Line.js'; import { Float32BufferAttribute } from '../core/BufferAttribute.js'; @@ -63,36 +62,19 @@ DirectionalLightHelper.prototype.dispose = function () { DirectionalLightHelper.prototype.update = function () { - var v1 = new Vector3(); - var v2 = new Vector3(); - var v3 = new Vector3(); + if ( this.color !== undefined ) { - return function update() { + this.lightPlane.material.color.set( this.color ); + this.targetLine.material.color.set( this.color ); - v1.setFromMatrixPosition( this.light.matrixWorld ); - v2.setFromMatrixPosition( this.light.target.matrixWorld ); - v3.subVectors( v2, v1 ); + } else { - this.lightPlane.lookAt( v3 ); + this.lightPlane.material.color.copy( this.light.color ); + this.targetLine.material.color.copy( this.light.color ); - if ( this.color !== undefined ) { + } - this.lightPlane.material.color.set( this.color ); - this.targetLine.material.color.set( this.color ); - - } else { - - this.lightPlane.material.color.copy( this.light.color ); - this.targetLine.material.color.copy( this.light.color ); - - } - - this.targetLine.lookAt( v3 ); - this.targetLine.scale.z = v3.length(); - - }; - -}(); +}; export { DirectionalLightHelper }; diff --git a/src/helpers/SpotLightHelper.js b/src/helpers/SpotLightHelper.js index 4d006d88b769d4..bb71ae1e1c0248 100644 --- a/src/helpers/SpotLightHelper.js +++ b/src/helpers/SpotLightHelper.js @@ -4,7 +4,6 @@ * @author WestLangley / http://github.com/WestLangley */ -import { Vector3 } from '../math/Vector3.js'; import { Object3D } from '../core/Object3D.js'; import { LineSegments } from '../objects/LineSegments.js'; import { LineBasicMaterial } from '../materials/LineBasicMaterial.js'; @@ -68,36 +67,24 @@ SpotLightHelper.prototype.dispose = function () { SpotLightHelper.prototype.update = function () { - var vector = new Vector3(); - var vector2 = new Vector3(); - - return function update() { - - this.light.updateMatrixWorld(); - - var coneLength = this.light.distance ? this.light.distance : 1000; - var coneWidth = coneLength * Math.tan( this.light.angle ); - - this.cone.scale.set( coneWidth, coneWidth, coneLength ); - - vector.setFromMatrixPosition( this.light.matrixWorld ); - vector2.setFromMatrixPosition( this.light.target.matrixWorld ); + this.light.updateMatrixWorld(); - this.cone.lookAt( vector2.sub( vector ) ); + var coneLength = this.light.distance ? this.light.distance : 1000; + var coneWidth = coneLength * Math.tan( this.light.angle ); - if ( this.color !== undefined ) { + this.cone.scale.set( coneWidth, coneWidth, coneLength ); - this.cone.material.color.set( this.color ); + if ( this.color !== undefined ) { - } else { + this.cone.material.color.set( this.color ); - this.cone.material.color.copy( this.light.color ); + } else { - } + this.cone.material.color.copy( this.light.color ); - }; + } -}(); +}; export { SpotLightHelper }; diff --git a/src/lights/DirectionalLight.js b/src/lights/DirectionalLight.js index 396a2a2282cb14..5bc7a2db3328bb 100644 --- a/src/lights/DirectionalLight.js +++ b/src/lights/DirectionalLight.js @@ -14,12 +14,15 @@ function DirectionalLight( color, intensity ) { this.type = 'DirectionalLight'; this.position.copy( Object3D.DefaultUp ); - this.updateMatrix(); + this.lookAt( 0, 0, 0 ); - this.target = new Object3D(); + this.target = undefined; this.shadow = new DirectionalLightShadow(); + this.add( this.shadow.camera ); + this.shadow.camera.scale.set( - 1, 1, - 1 ); + } DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), { @@ -32,7 +35,7 @@ DirectionalLight.prototype = Object.assign( Object.create( Light.prototype ), { Light.prototype.copy.call( this, source ); - this.target = source.target.clone(); + this.target = source.target ? source.target.clone() : undefined; this.shadow = source.shadow.clone(); diff --git a/src/lights/DirectionalLightShadow.js b/src/lights/DirectionalLightShadow.js index 7c2a5fc8e6eca4..5f204d479f4d4f 100644 --- a/src/lights/DirectionalLightShadow.js +++ b/src/lights/DirectionalLightShadow.js @@ -5,9 +5,10 @@ import { OrthographicCamera } from '../cameras/OrthographicCamera.js'; * @author mrdoob / http://mrdoob.com/ */ -function DirectionalLightShadow( ) { +function DirectionalLightShadow( camera ) { - LightShadow.call( this, new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ) ); + camera = camera || new OrthographicCamera( - 5, 5, 5, - 5, 0.5, 500 ); + LightShadow.call( this, camera ); } diff --git a/src/lights/SpotLight.js b/src/lights/SpotLight.js index 90d891af10d6aa..7ba134fb35867c 100644 --- a/src/lights/SpotLight.js +++ b/src/lights/SpotLight.js @@ -13,9 +13,9 @@ function SpotLight( color, intensity, distance, angle, penumbra, decay ) { this.type = 'SpotLight'; this.position.copy( Object3D.DefaultUp ); - this.updateMatrix(); + this.lookAt( 0, 0, 0 ); - this.target = new Object3D(); + this.target = undefined; Object.defineProperty( this, 'power', { get: function () { @@ -41,6 +41,9 @@ function SpotLight( color, intensity, distance, angle, penumbra, decay ) { this.shadow = new SpotLightShadow(); + this.add( this.shadow.camera ); + this.shadow.camera.scale.set( - 1, 1, - 1 ); + } SpotLight.prototype = Object.assign( Object.create( Light.prototype ), { @@ -58,7 +61,7 @@ SpotLight.prototype = Object.assign( Object.create( Light.prototype ), { this.penumbra = source.penumbra; this.decay = source.decay; - this.target = source.target.clone(); + this.target = source.target ? source.target.clone() : undefined; this.shadow = source.shadow.clone(); diff --git a/src/lights/SpotLightShadow.js b/src/lights/SpotLightShadow.js index 0a80e7b0bc14ad..e3244f15b3254a 100644 --- a/src/lights/SpotLightShadow.js +++ b/src/lights/SpotLightShadow.js @@ -6,9 +6,10 @@ import { PerspectiveCamera } from '../cameras/PerspectiveCamera.js'; * @author mrdoob / http://mrdoob.com/ */ -function SpotLightShadow() { +function SpotLightShadow( camera ) { - LightShadow.call( this, new PerspectiveCamera( 50, 1, 0.5, 500 ) ); + camera = camera || new PerspectiveCamera( 50, 1, 0.5, 500 ); + LightShadow.call( this, camera ); } diff --git a/src/renderers/webgl/WebGLLights.js b/src/renderers/webgl/WebGLLights.js index 217611d753f6aa..c9c19863a6235a 100644 --- a/src/renderers/webgl/WebGLLights.js +++ b/src/renderers/webgl/WebGLLights.js @@ -135,7 +135,6 @@ function WebGLLights() { }; - var vector3 = new Vector3(); var matrix4 = new Matrix4(); var matrix42 = new Matrix4(); @@ -172,9 +171,7 @@ function WebGLLights() { var uniforms = cache.get( light ); uniforms.color.copy( light.color ).multiplyScalar( light.intensity ); - uniforms.direction.setFromMatrixPosition( light.matrixWorld ); - vector3.setFromMatrixPosition( light.target.matrixWorld ); - uniforms.direction.sub( vector3 ); + light.getWorldDirection( uniforms.direction ).negate(); uniforms.direction.transformDirection( viewMatrix ); uniforms.shadow = light.castShadow; @@ -205,9 +202,7 @@ function WebGLLights() { uniforms.color.copy( color ).multiplyScalar( intensity ); uniforms.distance = distance; - uniforms.direction.setFromMatrixPosition( light.matrixWorld ); - vector3.setFromMatrixPosition( light.target.matrixWorld ); - uniforms.direction.sub( vector3 ); + light.getWorldDirection( uniforms.direction ).negate(); uniforms.direction.transformDirection( viewMatrix ); uniforms.coneCos = Math.cos( light.angle ); diff --git a/src/renderers/webgl/WebGLShadowMap.js b/src/renderers/webgl/WebGLShadowMap.js index 6c144640d854e5..2f1c497d9da2e8 100644 --- a/src/renderers/webgl/WebGLShadowMap.js +++ b/src/renderers/webgl/WebGLShadowMap.js @@ -188,9 +188,6 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { var shadowMap = shadow.map; var shadowMatrix = shadow.matrix; - _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); - shadowCamera.position.copy( _lightPositionWorld ); - if ( isPointLight ) { faceCount = 6; @@ -198,14 +195,20 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { // for point lights we set the shadow matrix to be a translation-only matrix // equal to inverse of the light's position + _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); + shadowCamera.position.copy( _lightPositionWorld ); shadowMatrix.makeTranslation( - _lightPositionWorld.x, - _lightPositionWorld.y, - _lightPositionWorld.z ); } else { faceCount = 1; - _lookTarget.setFromMatrixPosition( light.target.matrixWorld ); - shadowCamera.lookAt( _lookTarget ); + if ( light.target ) { + + _lookTarget.setFromMatrixPosition( light.target.matrixWorld ); + light.lookAt( _lookTarget ); + + } shadowCamera.updateMatrixWorld(); // compute shadow matrix @@ -232,7 +235,7 @@ function WebGLShadowMap( _renderer, _objects, maxTextureSize ) { if ( isPointLight ) { - _lookTarget.copy( shadowCamera.position ); + _lookTarget.copy( _lightPositionWorld ); _lookTarget.add( cubeDirections[ face ] ); shadowCamera.up.copy( cubeUps[ face ] ); shadowCamera.lookAt( _lookTarget );