【Three.js】RGBのSpotLightが作る影
See the Pen RGB SpotLight by aadebdeb (@aadebdeb) on CodePen.
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>[2017/03/26] RGB SpotLight</title> <style> body { margin: 0; overflow: hidden; } </style> <script src="https://cdnjs.cloudflare.com/ajax/libs/stats.js/r16/Stats.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.6.3/dat.gui.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/84/three.min.js"></script> <script> window.onload = function() { init(); render(); } window.onresize = onResize; var camera, scene, renderer; var stats; var controller; var box; var spotLightR, spotLightG, spotLightB; var spotLightRHelper, spotLightGHelper, spotLightBHelper; function init() { rotation = new THREE.Euler(); initGui(); initStats(); initScene(); initCamera(); initRenderer(); } function initStats() { stats = new Stats(); stats.setMode(0); stats.domElement.style.position = 'absolute'; stats.domElement.style.left = '0px'; stats.domElement.style.top = '0px'; document.body.appendChild(stats.domElement); } function initGui() { controller = new function() { this.positionAngleR = 0; this.positionHeightR = 30; this.lightAngleR = Math.PI / 4; this.lightIntensityR = 1; this.positionAngleG = Math.PI * 2 / 3; this.positionHeightG = 30; this.lightAngleG = Math.PI / 4; this.lightIntensityG = 1; this.positionAngleB = Math.PI * 2 / 3 * 2; this.positionHeightB = 30; this.lightAngleB = Math.PI / 4; this.lightIntensityB = 1; }; gui = new dat.GUI(); var folderR = gui.addFolder('Red Light'); folderR.open(); folderR.add(controller, 'positionAngleR', 0, Math.PI * 2).onChange(function(e) { updateSpotLightR(); }); folderR.add(controller, 'positionHeightR', 0, 50).onChange(function(e) { updateSpotLightR(); }); folderR.add(controller, 'lightAngleR', 0, Math.PI / 2).onChange(function(e) { updateSpotLightR(); }); folderR.add(controller, 'lightIntensityR', 0, 10).onChange(function(e) { updateSpotLightR(); }); var folderG = gui.addFolder('Green Light'); folderG.open(); folderG.add(controller, 'positionAngleG', 0, Math.PI * 2).onChange(function(e) { updateSpotLightG(); }); folderG.add(controller, 'positionHeightG', 0, 50).onChange(function(e) { updateSpotLightG(); }); folderG.add(controller, 'lightAngleG', 0, Math.PI / 2).onChange(function(e) { updateSpotLightG(); }); folderG.add(controller, 'lightIntensityG', 0, 10).onChange(function(e) { updateSpotLightG(); }); var folderB = gui.addFolder('Blue Light'); folderB.open(); folderB.add(controller, 'positionAngleB', 0, Math.PI * 2).onChange(function(e) { updateSpotLightB(); }); folderB.add(controller, 'positionHeightB', 0, 50).onChange(function(e) { updateSpotLightB(); }); folderB.add(controller, 'lightAngleB', 0, Math.PI / 2).onChange(function(e) { updateSpotLightB(); }); folderB.add(controller, 'lightIntensityB', 0, 10).onChange(function(e) { updateSpotLightB(); }); } function initRenderer() { renderer = new THREE.WebGLRenderer(); renderer.setClearColor(new THREE.Color(0x333333)); renderer.setSize(window.innerWidth, window.innerHeight); renderer.shadowMap.enabled = true; document.body.appendChild(renderer.domElement); } function initCamera() { camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(50, 50, 50); camera.lookAt(scene.position); } function initScene() { scene = new THREE.Scene(); var ground = new THREE.Mesh( new THREE.PlaneGeometry(100, 100), new THREE.MeshLambertMaterial({ color: 0xffffff }) ); ground.rotation.x = -Math.PI / 2; ground.position.set(0, 0, 0); ground.receiveShadow = true; scene.add(ground); box = new THREE.Mesh( new THREE.BoxGeometry(10, 5, 10), new THREE.MeshLambertMaterial({ color: 0xffffff }) ); box.position.set(0, 15, 0); box.castShadow = true; scene.add(box); var ambientLight = new THREE.AmbientLight(0xffffff); ambientLight.intensity = 0.3; scene.add(ambientLight); spotLightR = new THREE.SpotLight(0xff0000); spotLightR.target = box; spotLightR.castShadow = true; scene.add(spotLightR); spotLightRHelper = new THREE.SpotLightHelper(spotLightR); scene.add(spotLightRHelper); updateSpotLightR(); spotLightG = new THREE.SpotLight(0x00ff00); spotLightG.target = box; spotLightG.castShadow = true; scene.add(spotLightG); spotLightGHelper = new THREE.SpotLightHelper(spotLightG); scene.add(spotLightGHelper); updateSpotLightG(); spotLightB = new THREE.SpotLight(0x0000ff); spotLightB.target = box; spotLightB.castShadow = true; scene.add(spotLightB); spotLightBHelper = new THREE.SpotLightHelper(spotLightB); scene.add(spotLightBHelper); updateSpotLightB(); } function updateSpotLightR() { spotLightR.position.set( 10 * Math.cos(controller.positionAngleR), controller.positionHeightR, 10 * Math.sin(controller.positionAngleR) ); spotLightR.angle = controller.lightAngleR; spotLightR.intensity = controller.lightIntensityR; spotLightRHelper.update(); } function updateSpotLightG() { spotLightG.position.set( 10 * Math.cos(controller.positionAngleG), controller.positionHeightG, 10 * Math.sin(controller.positionAngleG) ); spotLightG.angle = controller.lightAngleG; spotLightG.intensity = controller.lightIntensityG; spotLightGHelper.update(); } function updateSpotLightB() { spotLightB.position.set( 10 * Math.cos(controller.positionAngleB), controller.positionHeightB, 10 * Math.sin(controller.positionAngleB) ); spotLightB.angle = controller.lightAngleB; spotLightB.intensity = controller.lightIntensityB; spotLightBHelper.update(); } function render() { requestAnimationFrame(render); stats.update(); renderer.render(scene, camera); } function onResize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); } </script> </head> <body> </body> </html>