three.js 03-01 之 AmbientLight 光源

来源:互联网 发布:lol封3年淘宝解封方法 编辑:程序博客网 时间:2024/06/05 20:22

    在前面的一些文章里我们深入地学习了场景中最重要的部分:几何体、网格和相机。尽管其中有的示例可能用到了光源,但是没有过多解释。接下来的一些文章里,我们将会重点讲解一些在 three.js 中常用的几种光源。

    在 three.js 中,如果没有光源,我们就看不到任何渲染结果。为此,three.js 为我们准备了多种不同用途的光源,如下表所示:

光源名称描述AmbientLight (环境光)这是一种基础光源,它的颜色会添加到整个场景和所有对象的当前颜色上PointLight (点光源)空间中的一个发光点,朝所有的方向发射光线SpotLight (聚光灯光源)这种光源有聚光的效果,类似台灯、天花板吊灯,或者手电筒DirectionalLight (方向光)也称作无限光。从这种光源发出的光线可以看做是平行的,例如太阳光HemisphereLight (半球光)这是一种特殊光源。可以用来创建更加自然的室外光线,模拟反光面和光线微弱的天空RectAreaLight (面光源)使用这种光源可以指定散发光线的平面,而不是空间中的一个点LensFlare (镜头眩光)这不是一种光源,但是通过它可以为场景中的光源添加眩光效果    我们先从最基础的光源 AmbientLight 环境光开始介绍。按照惯例,我们先来一个完整的示例,如下所示:

<!DOCTYPE html><html><head>    <title>示例 03.01 - 环境光</title><script src="../build/three.js"></script><script src="../build/js/controls/OrbitControls.js"></script><script src="../build/js/libs/stats.min.js"></script><script src="../build/js/libs/dat.gui.min.js"></script><script src="../jquery/jquery-3.2.1.min.js"></script>    <style>        body {            /* 设置 margin 为 0,并且 overflow 为 hidden,来完成页面样式 */            margin: 0;            overflow: hidden;        }/* 统计对象样式 */#Stats-output {position: absolute;left: 0px;top: 0px;}    </style></head><body><!-- 用于 WebGL 输出的 Div --><div id="WebGL-output"></div><!-- 用于统计 FPS 输出的 Div --><div id="Stats-output"></div><!-- 运行 Three.js 示例的 Javascript 代码 --><script type="text/javascript">var scene;var camera;var render;var controls;var stats;var guiControls;var cube;var sphere;    // 当所有元素加载完毕后,就执行我们 Three.js 相关的东西    $(function() {stats = initStats();scene = new THREE.Scene();camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000); // 2147483647camera.position.set(-30, 40, 30);render = new THREE.WebGLRenderer( {antialias: true} ); // antialias 抗锯齿render.setSize(window.innerWidth, window.innerHeight);render.setClearColor(0xEEEEEE);render.shadowMap.enabled = true; // 允许阴影投射$('#WebGL-output')[0].appendChild(render.domElement);window.addEventListener('resize', onWindowResize, false);var target = new THREE.Vector3(scene.position.x, scene.position.y ,scene.position.z);controls = new THREE.OrbitControls(camera, render.domElement);controls.target = target;camera.lookAt(target);scene.add(new THREE.AxisHelper(20));// 加入坐标轴// 加入一个平面(带线框效果)var planeGeometry = new THREE.PlaneGeometry(60, 20, 1, 1);var planeMaterials = [new THREE.MeshLambertMaterial( {color: 0xFFFFFF} ),new THREE.MeshBasicMaterial( {color: 0xFFFFFF, wireframe: true, transparent: true, opacity: 0.5} )];var plane = THREE.SceneUtils.createMultiMaterialObject(planeGeometry, planeMaterials);plane.rotation.x = -0.5 * Math.PI; // 沿着 X轴旋转-90°plane.position.x = 15; // 沿着 x轴右移 15个单位plane.position.y = 0; // y轴为 0plane.position.z = 0; // z轴为 0plane.children[0].receiveShadow = true; // 非线框几何平面接收阴影scene.add(plane);// 加入一个立方体var cubeGeometry = new THREE.BoxGeometry(4, 4, 4);var cubeMaterial = new THREE.MeshLambertMaterial( {color: 0xFF0000} );cube = new THREE.Mesh(cubeGeometry, cubeMaterial);cube.position.x = -4;cube.position.y = 3;cube.position.z = 0;cube.castShadow = true; // 立方体投射阴影scene.add(cube);// 加入一个球体var sphereGeometry = new THREE.SphereGeometry(4, 20, 20);var sphereMaterial = new THREE.MeshLambertMaterial( {color: 0x7777FF} );sphere = new THREE.Mesh(sphereGeometry, sphereMaterial);sphere.position.x = 20;sphere.position.y = 4;sphere.position.z = 2;sphere.castShadow = true; // 球体投射阴影scene.add(sphere);// 加入一个环境光源var ambientLight = new THREE.AmbientLight(0x0c0c0c);scene.add(ambientLight);// 加入一个聚光灯光源// 注:基础材质 MeshBasicMaterial 不会对光源产生反应,因此要改用 MeshLambertMaterial 或 MeshPhongMaterial 材质才有效果var spotLight = new THREE.SpotLight( 0xFFFFFF);spotLight.position.set(-60, 60, -10);spotLight.castShadow = true; // 光源产生阴影spotLight.shadow.mapSize.width = 2048; // 必须是 2的幂,默认值为 512spotLight.shadow.mapSize.height = 2048; // 必须是 2的幂,默认值为 512scene.add(spotLight);/** 用来保存那些需要修改的变量 */guiControls = new function() {this.rotationSpeed = 0.02;this.bouncingSpeed = 0.04;this.ambientColor = '#0c0c0c';this.disableSpotLight = false;}/** 定义 dat.GUI 对象,并绑定 guiControls 的有关属性 */var gui = new dat.GUI();gui.addColor(guiControls, 'ambientColor').onChange( function(e) {ambientLight.color = new THREE.Color(e);});gui.add(guiControls, 'disableSpotLight').onChange(function(e){spotLight.visible = !e;});renderScene();    });/** 渲染场景 */function renderScene() {stats.update();rotateCube(); // 旋转立方体bounceSphere() // 弹跳球体requestAnimationFrame(renderScene);render.render(scene, camera);}/** 初始化 stats 统计对象 */function initStats() {stats = new Stats();stats.setMode(0); // 0 为监测 FPS;1 为监测渲染时间$('#Stats-output').append(stats.domElement);return stats;}/** 当浏览器窗口大小变化时触发 */function onWindowResize() {camera.aspect = window.innerWidth / window.innerHeight;camera.updateProjectionMatrix();render.setSize(window.innerWidth, window.innerHeight);}/** 转动立方体 */function rotateCube() {cube.rotation.x += guiControls.rotationSpeed;cube.rotation.y += guiControls.rotationSpeed;cube.rotation.z += guiControls.rotationSpeed;}/** 弹跳球体 */var step = 0;function bounceSphere() {step += guiControls.bouncingSpeed;sphere.position.x = 20 + (10 * Math.cos(step));sphere.position.y = 2 + (10 * Math.abs(Math.sin(step)));}</script></body></html>

先来看一下 AmbientLight 环境光的构造方法:

AmbientLight( color, intensity )

color - 表示构成 RGB 颜色组件的数值;

intensity - 可选。表示光强弱的数值;

    由上例可见,AmbientLight 的光线没有特定的来源,而且这个光源也不会影响阴影的生成。我们不应该将 AmbientLight 作为场景中的唯一光源(可以试着在本示例中点击右上角的 disableSpotLight 复选框,关掉聚光灯后只剩环境光的效果)。而应该结合其他光源(如 SpotLight、DirectionalLight 等)同时使用 AmbientLight,目的是弱化阴影或添加一些颜色。作为试验,可以在本示例右上角菜单中调整 AmbientLight 的颜色,如手动输入 #007700 明亮的绿色,那么场景中的各个对象就会笼罩在一片明亮的绿光下。

    在这个示例中,我们改变环境光的颜色时用到了一个 THREE.Color() 对象,构造这个对象时,通常情况下可以通过用十六进制字符串如"#0c0c0c"或者十六进制值如 0x0c0c0c 来指定颜色。下面我们来看看这个对象常用的一些函数和属性:

set(value) - 把当前颜色设置成指定的十六进制值;

setHex(value) - 把当前颜色设置成指定的十六进制数字值;

setRGB(r, g, b) - 根据提供的 RGB 值设置颜色,参数值得范围从 0 到 1;

getHex() - 以十六进制值形式从颜色对象获取颜色值,如 26852316;

getHexString() - 以十六进制字符串形式从颜色对象获取颜色值,如"99bbdc";

getStyle() - 以 CSS 值得形式从颜色对象获取颜色值,如"rgb(408,442,476)";

add(color) - 把提供的颜色加到当前颜色上;

clone() - 复制当前颜色对象;


未完待续···

原创粉丝点击