灯光是场景中非常重要的一部份,没有光源线框材质都不可见(除非使用基础材质),threejs包含大量的光源,每个光源都有特别的行为和用法,本次我们来探讨不同光源的用法。
光源名称 | 描述 |
---|---|
AmbientLight(环境光源) | 颜色会叠加在场景中所有物体的颜色上 |
PointLight(点光源) | 空间中一点向所有方向发射光源(不能创建阴影) |
SpotLight(聚光灯) | 有聚光效果,类似台灯,手电筒。可以投射阴影 |
DirectionalLight(方向光源) | 也成无限光,光源发出的光线是平行的,类似太阳光 |
HemisphereLight(半球光) | 创造自然室外光线,模拟反光和光线微弱的天空,模拟室外光线。(不提供与阴影相关的功能) |
AreaLight(面光源) | 可指定散发光线的平面,不是一个点。(不投射任何阴影) |
LensFlare(镜头光晕) | 这不是一种光源,给场景添加镜头光晕的效果 |
1 THREE.AmbientLight (环境光)
var ambiColor = "#0c0c0c";
var ambientLight = new THREE.AmbientLight(ambiColor); //环境光
//ambientLight.intensity = 1; //唯一属性,调光照强度
scene.add(ambientLight);
THREE.AmbientLight光源不需要指定位置并且会应用到全局。在项目中不能作为唯一光源使用,因为它会将场景中所有物体渲染成统一颜色(图1.1,1.2所示)。通常搭配聚光灯或者平行光使用。
作用:一般用在弱化阴影或给场景添加一点额外颜色。
图 1.1 环境光作为独立光源使用
图 1.2 搭配聚光灯效果
使用THREE.AmbientLight光源时注意:用色尽量保守,如果指定的颜色过于明亮,那么画面颜色过于饱和,光源强度默认即可。
2 THREE.SpotLight (聚光灯)
THREE.SpotLight是一种具有锥形效果的光源,该光源产生的光具有方向与角度。
var pointColor = "#ffffff";
var spotLight = new THREE.SpotLight(pointColor);
spotLight.position.set(-40, 60, -10); //设置光源的位置
spotLight.castShadow = true; //开启阴影效果
spotLight.shadowCameraNear = 2; // 投影近点,距离光源多近能产生阴影
spotLight.shadowCameraFar = 200; //投影远点,到哪一点为止不再产生阴影
spotLight.shadowCameraFov = 30; //投影视场,聚光的角度大小
spotLight.target = plane; //光照的方向。 plane: 地面
spotLight.distance = 0; //光照距离,默认为0.
spotLight.angle = 0.4; //光源发射的宽度(弧度)
scene.add(spotLight);
SpotLight有个很好用的属性shadowCameraVisible=true,如果设置了那么效果将是这样的如图1.3。能显示光源,光的角度大小,光源的distance等信息,这个对于调试设置等有很好的效果。
图 1.3 shadowCameraVisible=true时光源效果
光源的target属性只照射其中一个,如图1.4
图 1.4 光源target属性为圆球
使用SpotLight光源时注意:有一个非常光亮的光束,离中心越远衰减地越快。可以使用小的exponent衰减值和小的angle值来创建同样的聚光效果。不过如果角度很小,可能会产生光线渲染失真。
另一个值得注意的是:如果看起来阴影有点模糊,可以增加shadowMapWidth和shadowMapHeight来配置。
3 THREE.PointLight(点光源)
THREE.PointLight是一种单点发光,照亮所有方向的光源,夜空中的照明弹就是一个很好的点光源的例子。
var pointColor = "#3bd93b";
var pointLight = new THREE.PointLight(pointColor);
pointLight.position.set(-0,5,0);
pointLight.intensity = 20;
pointLight.distance = 10;
scene.add(pointLight);
PointLight光源会朝着所有的方向发射光线,在这种情况下计算阴影对GPU来讲是一个非常沉重的负担,渲染非常慢。所以不能产生阴影。
在场景中添加点光源辅助线,方便调试点光源的位置。通过调试光源的位置,可以看到完整的光源范围。如图1.5.场景中通过光源intensity属性强化了光照强度。
var pointLightHelper = new THREE.PointLightHelper(pointLight,10);
scene.add(pointLightHelper);
图 1.5 点光源效果图
4 THREE.DirectionalLight(平行光)
THREE.DirectionalLight光源发出的光线相互平行。所有对象接收的光强都是一样的会产生阴影与聚点光源的主要差别是:聚点光源光距离目标越远光越暗淡,而平行光光强都是一样的。一般模拟太阳光使用如图1.6。
var pointColor = "#ffffff";
var dirLight = new THREE.DirectionalLight(pointColor);
directionalLight.position.set(-40, 60, -10);
directionalLight.castShadow = true;
//定义光照空间范围
directionalLight.shadowCameraNear = 2;
directionalLight.shadowCameraFar = 200;
directionalLight.shadowCameraLeft = -50;
directionalLight.shadowCameraRight = 50;
directionalLight.shadowCameraTop = 50;
directionalLight.shadowCameraBottom = -50;
//其他属性与点光源相同
directionalLight.distance = 0;
directionalLight.intensity = 0.5;
directionalLight.shadowMapHeight = 1024;
directionalLight.shadowMapWidth = 1024;
//debug调试光照
// dirLight.shadowCameraVisible =true;
scene.add(dirLight);
图 1.6 平行光 效果图
4.1 THREE.HemisphereLight(半球光源)
THREE.HemisphereLight光源的创立是为了创建出更加贴切自然的户外光照效果。那么要怎么样模拟户外灯光呢。由于在户外很多光照并非来自上方:很多来自大气的散射和地面以及其他物体的反射。THREE.HemisphereLight就是为这种情形创建的。你只需要指定接受天空的颜色,地面的颜色,以及这些光线的强度。
var hemiLight = new THREE.HemisphereLight(0x0000ff, 0x00ff00, 0.6);
hemiLight.position.set(0, 500, 0);
// hemiLight.groundColor=0x000000; 地面反射颜色
// hemiLight.color = new THREE.Color(0x8cccccc); 天空照射颜色
//hemiLight.intensity = 1;
scene.add(hemiLight);
搭载THREE.DirectionalLight来模拟太阳光,同时添加THREE.AmbientLight来为场景提供基础色。可以渲染出自然的户外场景图。如图1.7。
图 1.7 HemisphereLight光源效果图
4.2 THREE.LensFlare(镜头光晕)
当用手机向太阳或者非常明亮的光源拍照时,镜头会出现光晕效果。大多数情况下我们需要避开这种效果。但在游戏和三维图像中,它提供了一种非常好的效果,让场景看上去更加真实。
如何创建这一对象:
var lensFlare = new THREE.LensFlare(texture,size,distence,Blending,color.opacity);
scene.add(lensFlare) ;
参数 | 描述 |
---|---|
texture(纹理) | 纹理是一张图片,用来决定光晕的形状 |
size(尺寸) | 指定光晕的大小(像素) |
distence(距离) | 光源(0)到摄像机(1)的距离 |
blending(混合) | 为光晕提供多种材质,默认混合方式THREE.AdditiveBlending |
color (颜色) | 光晕的颜色 |
opacity(不透明度) | 范围 0 - 1 |
在平行光实例场景中添加如下代码:如图1.8
var textureFlare0 =THREE.ImageUtils.loadTexture("../lensflare0.png");
var textureFlare3 = THREE.ImageUtils.loadTexture("../lensflare3.png");
//颜色
var color = new THREE.Color(0xffaacc);
var lensFlare = new THREE.LensFlare(textureFlare0,350,0.0,THREE.AdditiveBlending,color);
lensFlare.add(textureFlare3,60,0.6,THREE.AdditiveBlending);
lensFlare.add(textureFlare3,70,0.7,THREE.AdditiveBlending);
lensFlare.add(textureFlare3,120,0.9,THREE.AdditiveBlending);
lensFlare.add(textureFlare3,70,1.0,THREE.AdditiveBlending);
lensFlare.position.copy(dirLight.position);
scene.add(lensFlare);
图 1.8 光晕效果图
lensflare3.png
lensflare0.png
5 THREE.AreaLight(平面光)
THREE.AreaLight是一个发光区域,单纯场景中添加光源,在放置光源位置看不出任何效果。需要光照射物体上才能看到。可以调节颜色,光源强度观察效果。如图1.9.
var areaLight1 = new THREE.AreaLight(0xff0000, 3);
areaLight1.position.set(-10, 10, -35);
//设置光源垂直平面
areaLight1.rotation.set(-Math.PI / 2, 0, 0);
//设置光源的宽
areaLight1.width = 4;
//设置光源的高
areaLight1.height = 9.9;
scene.add(areaLight1);
var areaLight2 = new THREE.AreaLight(0x00ff00, 3);
areaLight2.position.set(0, 10, -35);
areaLight2.rotation.set(-Math.PI / 2, 0, 0);
areaLight2.width = 4;
areaLight2.height = 9.9;
scene.add(areaLight2);
var areaLight3 = new THREE.AreaLight(0x0000ff, 3);
areaLight3.position.set(10, 10, -35);
areaLight3.rotation.set(-Math.PI / 2, 0, 0);
areaLight3.width = 4;
areaLight3.height = 9.9;
scene.add(areaLight3);
var planeGeometry1 = new THREE.BoxGeometry(4, 10, 0);
var planeGeometry1Mat = new THREE.MeshBasicMaterial({color: 0xff0000});
var plane1 = new THREE.Mesh(planeGeometry1, planeGeometry1Mat);
plane1.position.copy(areaLight1.position);
scene.add(plane1);
var planeGeometry2 = new THREE.BoxGeometry(4, 10, 0);
var planeGeometry2Mat = new THREE.MeshBasicMaterial({color: 0x00ff00});
var plane2 = new THREE.Mesh(planeGeometry2, planeGeometry2Mat);
plane2.position.copy(areaLight2.position);
scene.add(plane2);
var planeGeometry3 = new THREE.BoxGeometry(4, 10, 0);
var planeGeometry3Mat = new THREE.MeshBasicMaterial({color: 0x0000ff});
var plane3 = new THREE.Mesh(planeGeometry3, planeGeometry3Mat);
plane3.position.copy(areaLight3.position);
scene.add(plane3);
图 1.9 AreaLight光源效果图
6 总结
Threejs库中提供的各种不同灯源,信息量非常大。在本文中,我们学习了搭配光源、颜色和阴影,并且知道了它们不是严谨的科学。要获得正确的结果,需要不新试验,可以使用dat.GUI控件可以微调配置。不同的光源以不同的方式表现,
THREE.AmbientLight光源的颜色可以附加到场景中的每一种颜色上,通常用来柔化生硬的颜色和阴影。THREEPointLight光源会朝所有方向发射光线,不能被用来创建阴影。THREE.SpotLight光源类似于手电。它有一个维形的光束,可以配置它随着距离的增大而逐渐弱,并且可以生成阴影。同时还学习了THREE.DirectionalLight光源。这个光源相当于远光的效果,比如太阳光。它的光线彼此平行,其光强并不会随着与目标对象距离的增大而减弱。除了这些标准光源之外,同时还学习了几个更加特殊的光源。如果想要一个更加自然的户外效果,可以使用THREE HemisphereLight 光源,它考虑了天空和地面的反射。THREE.AreaLight 不从单个点发射光线,面是从一个很大的区域发射光线。本文还展示了如何通过THREE.LensFlare对象添加图像化的镜头光晕。