three.js中定义了不同种类的光源,本节主要讲四种基本光源的应用:THREE.AmbientLight、THREE.PointLight、THREE.SpotLight和THREE.DirectionalLight。它们的介绍如下表:
THREE.AmbientLight |
自然光源,该光源的颜色会叠加到场景现有物体的颜色上,不产生阴影 |
THREE.PointLight |
点光源,从空间一点向所有方向射出光线,像太阳。不产生阴影 |
THREE.SpotLight |
聚光灯光源,类似手电筒,台灯。可以产生阴影 |
THREE.DirectionalLight | 平行光源,从这种光源发出的光线可以看作平行的,可创建阴影 |
从上表我们可以知道一些光源可一产生阴影,关于场景中阴影的创建可一参考:点击打开链接。值得注意的是,这几个光源中的THREE.AmbientLight要配合其他的光使用,才能达到弱化阴影或者给场景添加其他颜色的效果,如果单独使用,场景中的物体不管是什么颜色,都会被这个光源给覆盖。在接下来的Demo会做演示。为了展示这几种光源的效果,编写了一个小Demo,其运行效果如下:
自然光源: 点光源:
聚光灯光源: 平行光源:
程序里加了一个交互工具条,用于实现各种光源的切换:
代码如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>threejs - basic - light</title> <style> body{ font-family: Monospace; background: #f0f0f0; margin: 0px; overflow: hidden; } </style> </head> <body> <script type="text/javascript" src="build/three.js"></script> <script type="text/javascript" src="js/Detector.js"></script> <script type="text/javascript" src="js/libs/dat.gui.min.js"></script> <script type="text/javascript"> //检测webgl的支持情况 if(!Detector.webgl) {Detector.addGetWebGLMessage();} var container; var scene, camera, renderer; var mesh; var light; var gui; //添加交互工具栏 var controls = new function() { this.光源 = false; }; window.onload = function main(){ //添加一个div container = document.createElement('div'); document.body.appendChild(container); //创建一个新场景 scene = new THREE.Scene(); initRenderer(container); initCamera(); ambientLight(); planMesh(); sphereMesh(); initGUI(); render(); }; //渲染器 function initRenderer(container){ //渲染 //antialias:true增加抗锯齿效果 renderer = new THREE.WebGLRenderer({antialias:true}); renderer.setClearColor(new THREE.Color(0x3399CC));//设置窗口背景颜色为黑 renderer.setSize(window.innerWidth, window.innerHeight);//设置窗口尺寸 renderer.shadowMapEnabled = true; //将renderer关联到container,这个过程类似于获取canvas元素 container.appendChild(renderer.domElement); } //相机 function initCamera() { camera = new THREE.PerspectiveCamera(25, window.innerWidth/window.innerHeight, 1, 1000); camera.position.set(150, 180, 100);//设置相机位置 camera.lookAt(scene.position);//让相机指向场景中心 } //创建一个平面 function planMesh() { var planeGeo = new THREE.PlaneGeometry(100,100,10,10);//创建平面 var planeMat = new THREE.MeshLambertMaterial({ //创建材料 color:0xFFFFFF, wireframe:false }); mesh = new THREE.Mesh(planeGeo, planeMat); mesh.position.set(0, 0, -20); mesh.rotation.x = -0.5 * Math.PI;//将平面绕X轴逆时针旋转90度 mesh.receiveShadow = true;//允许接收阴影 scene.add(mesh);//将平面添加到场景中 } //创建一个球 function sphereMesh() { var sphereGeo = new THREE.SphereGeometry(16, 40, 60);//创建球体 var sphereMat = new THREE.MeshLambertMaterial({//创建材料 color:0x0000FF, wireframe:false }); mesh = new THREE.Mesh(sphereGeo, sphereMat);//创建球体网格模型 mesh.position.set(25, 16, 0);//设置球的坐标 mesh.castShadow = true;//允许投射阴影 mesh.receiveShadow = true;//允许接收阴影 scene.add(mesh);//将球体添加到场景 } //自然光 function ambientLight() { scene.remove(light); light = new THREE.AmbientLight( 0x606060 ); scene.add(light); } //点光源 function pointLight() { scene.remove(light); light = new THREE.PointLight( 0xffffff ); light.position.set(80, 50, 30); scene.add(light); } //聚光灯光源 function spotLight() { scene.remove(light); light = new THREE.SpotLight( 0xffffff ); light.position.set(100, 40, 30); light.castShadow = true;//允许投射阴影 scene.add(light); } //平行光源 function directionalLight() { scene.remove(light); light = new THREE.DirectionalLight( 0xffffff ); light.position.set(30, 10, 10); light.castShadow = true; light.shadowCameraNear = 2; light.shadowCameraFar = 200; light.shadowCameraLeft = -50; light.shadowCameraRight = 50; light.shadowCameraTop = 50; light.shadowCameraBottom = -50; scene.add(light); } //添加交互工具条
function initGUI() { gui = new dat.GUI(); gui.add(controls, '光源', ["自然光源", "点光源", "聚光灯光源", "平行光源"]).onChange (function (e) { switch (e) { case "自然光源": ambientLight(); render(); break; case "点光源": ambientLight(); pointLight(); render(); break; case "聚光灯光源": ambientLight(); spotLight(); render(); break; case "平行光源": ambientLight(); directionalLight(); render(); break; } }); }
//渲染 function render() { renderer.render(scene, camera); } </script> </body> </html>