共计 7776 个字符,预计需要花费 20 分钟才能阅读完成。
一、光源简介
Three.js库提供了一系列光源,而且光源都有特定的行为和用途,例如下表
光源名称 | 描述 |
---|---|
AmbientLight(环境光) | 这是一种基础光源,它的颜色会添加到整个场景和所有对象的当前颜色上 |
PointLight(点光源) | 空间中的一点,朝所有的方向发射光线 |
SpotLight(聚光灯光源) | 这种光源有聚光的效果,类似台灯,吊灯,手电筒 |
DirectionalLight(方向光) | 也称作无限光,从这种光源发出的光线可以看作是平行的,例如太阳光 |
HemisphereLight(半球光) | 这是一种特殊光源,可以用来创建更加自然的室外光线,模拟反光面和光线微弱的天空 |
AreaLight(面光源) | 使用这种光源可以指定散发光线的平面,而不是空间的一个点 |
LensFlare(镜头炫光) | 这不是一种光源,但是通过LensFlare方法为场景中的光源添加炫光效果 |
前4种是基础光源,后2种是特殊光源。
使用THREE.Color()对象
当构造Three.js库中的对象时,可以用16进制字符串或者16进制的数值指定颜色,然而在对象构造好之后,常常需要修改颜色,这是就需要重新创建一个新的THREE.Color()对象或者直接修改THREE.Color()对象的内部属性。现在来看看THREE.Color()对象通过下面的函数来设置或获取信息。
函数名 | 描述 |
---|---|
set(value) | 将当前颜色改成指定的16进制值。这个值可以是字符串,也可以是数值。 |
setHex(value) | 将当前颜色改成指定的16进制数字值。 |
setRGB(r,g,b) | 根据提供的RGB值设置颜色。参数范围0-1 |
setHSV(h,s,v) | 根据提供的HSV值设置颜色。参数范围0-1 |
setStyle(style) | 根据CSS值设置颜色 |
copy(color) | 从提供的颜色对象复制颜色值到当前对象 |
copyGamaToLinear(color) | 通常在内部使用:根据提供的颜色设置物体的颜色。颜色参数先从伽马色彩空间转换到线性色彩空间。伽马色彩空间用的也是RGB值,但是会带有一个额外的比例系数,而在线性色彩空间中这个系数为1 |
copyLinearToGamman(color) | 主要在内部使用:基于提供的颜色设置物体的颜色。颜色参数先从线性色彩空间转换到伽马色彩空间。 |
convertGamaToLinear() | 将当前颜色先从伽马色彩空间转换到线性色彩空间 |
convertLinearToGamman() | 将当前颜色先从线性色彩空间转换到伽马色彩空间 |
getHex() | 以16进制值形式从颜色对象中获取颜色值 |
getHexString() | 以16进制字符串形式从颜色对象中获取颜色值 |
getStyle() | 以CSS值的形式从颜色对象中获取颜色值 |
getHSV() | 以HSV形式从颜色对象中获取颜色值 |
add(color) | 将提供的颜色添加到当前颜色上 |
addColor(color1,color2) | 通常在内部使用:将提供的各个颜色添加到当前颜色 |
addScalar(s) | 通常在内部使用:在当前颜色的RGB分量上添加值 |
multiply(color) | 通常在内部使用:将当前颜色与提供颜色相乘 |
multiplyScalar(s) | 通常在内部使用:将当前光源与提供的值相乘 |
lerp(color,alpha) | 通常在内部使用:找到当前颜色和指定颜色之间的颜色值,并将该颜色值与提供的alpha值相乘 |
1.AmbientLight-影响整个场景的光源
AmbientLight光源的颜色会影响整个场景,AmbientLight的光线没有特定的来源,而且这个光源也不会影响阴影的生成。不能将AmbientLight光源作为唯一的光源。
创建AmbientLight光源很简单,只需要使用new THREE.AmbientLight()即可。如下:
var ambiColor = "#0c0c0c";
var ambientLight = new THREE.AmbientLight(ambiColor);
scene.add(ambientLight);
在这个例子中将AmbientLight光源的颜色绑定到控制菜单中,用的是下面方法:
var gui = new dat.GUI();
gui.addColor(controls, 'ambientColor').onChange(function (e) {
ambientLight.color = new THREE.Color(e);
});
gui.add(controls, 'disableSpotlight').onChange(function (e) {
spotLight.visible = !e;
});
2.PointLight-照射所有方向的光源
单点发光,照射所有方向。创建点光源的方法:
var PointColor = "#0c0c0c";
var PointLight = new THREE.PointLight(PointColor);
PointLight.distance = 100;
PointLight.intensity = 2.4;
scene.add(PointLight);
点光源的属性有以下几种:
属性 | 描述 |
---|---|
color(颜色) | 光源颜色 |
intensity(强度) | 光照的强度,默认为1 |
distance(距离) | 光源照射的距离 |
position(位置) | 光源所在的位置 |
visible(是否可见) | 如果设为true,该光源就会打开;反之会关闭 |
用dat.CUI监听器:
var controls v= new function(){
this.intensity=1;
};
var gui = new dat.GUI();
gui.add(controls,'intensity',0,3).onChange(function(e){
pointLight.intensity = e;
})
distance属性的默认为0,光线的亮度不会随距离的增加而递减。
3.SpotLight-具有锥型效果的光源
聚光灯光源有以下的属性:
属性 | 描述 |
---|---|
castShadow(投影) | 如果设为(true),这个光源就会生成阴影 |
shadowCameraNear(投影近点) | 从距离光源的哪一点开始可以生成阴影 |
shadowCameraFar(投影远点) | 到距离光源的哪一点为止可以生成阴影 |
shadowCameraFov(投影视场) | 用于生成阴影的视场有多大 |
target目标 | 决定光照的方向 |
shadowBias阴影偏移 | 用来偏置阴影的位置 |
angle角度 | 光源射出的光柱有多宽。单位是弧度,默认值是Math.PI/3 |
exponent光强衰减指数 | 光照指向特定目标,在这个方向上距离光源越远,则光照强度递减的越快。这个值决定光照强度递减的有多快 |
onlyShadow仅阴影 | 如果设为true,那个这个光源只会生成阴影,而不会在场景中添加任何光照 |
shadowCameraVisible投影方式可见 | 如果设为true,你就可以看见光源在哪里以及如何生成阴影 |
shadowDarkness阴影暗度 | 默认值是0.5,定义渲染的阴影有多黑,场景渲染后不能修改 |
shadowMapWidth阴影映射宽度 | 决定由多少像素用来生成阴影。如果阴影的边缘参差不齐或看上去不那么平滑,可以增加这个值,场景渲染后不能修改 |
shadowMapHeight阴影映射高度 | 决定由多少像素用来生成阴影。如果阴影的边缘参差不齐或看上去不那么平滑,可以增加这个值,场景渲染后不能修改 |
创建聚光灯光源,只需要指定颜色,设置需要的属性,添加到场景即可。
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;
spotLight.angle = 0.4;
scene.add(spotLight);
如果有其他物体,比如球体可以把target
设置为该对象。
var target = new THREE.Object3D();
target.position = new THREE.Vector3(5, 0, 0);
spotlight.target = target
angle属性定义光锥的宽度(角度),distance定义光锥的长度。正切函数可以用来计算对边长度(光锥宽度)和邻边长度(光锥长度)之比;
光束的明亮度(intensity)值很高,离中心越远光强衰减得越快(exponent值越高)。如果角度很小,那它很快就会导致光线渲染失真。
注意:
1.启用shadowCameraVisible属性,这样会受光源影响,把生成阴影的区域显示出来。
2.如果阴影看上去有点模糊,可以增加shadowMapWidth,shadowMapHeight属相值,或者保证用于生成阴影的区域紧密包围着对象。可以使用shadowCameraNear,shadowCameraFar,shadowCameraFov,属性来配置这个区域。
3.不仅仅要设置光源是否生成阴影,还要通过castShadow和receviceShadow属性设定几何体是否接收或者投射阴影。
4.DirectinaLight-模拟远处类似太阳的光源
特点所有的光线都是平行的,方向光不像聚焦光那样离目标越远越暗淡,光强在整个区域都是一样的。
属性值同spotLight
一样。
var pointColor = "#ff5808";
var directionalLight = 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;
scene.add(directionalLight);
这个区域的对象都可以投影或者接受阴影,跟聚光灯光源一样,包围对象的空间定义越紧密,投影效果越好。
5.使用特殊光源生成高级光照效果
5.1半球光光源
半球光光源是THREE.HemisphereLight生成的。这个特点可以创造出更加贴近自然光照效果,模拟室外光照,在添加一个方向光光源模拟太阳,或添加一个环境光光源,为场景提供基础色。
var hemiLight = new THREE.HemisphereLight(0x0000ff, 0x00ff00, 0.6);
hemiLight.position.set(0, 500, 0);
scene.add(hemiLight);
半球光光源有以下的属性:
属性 | 描述 |
---|---|
groundColor | 从地面发出的光线的颜色 |
color | 从天空发出的光线的颜色 |
intensity | 光照照射的强度 |
5.2平行光光源
平行光光源是THREE.AreaLight生成的。这个特点可以创造一个发光矩形。如果使用平行光光源为了不影响性能,不能使用THREE.WebGLRenderer,而是使用THREE.WebGLDeferredRenderer,要使用THREE.WebGLDeferredRenderer需要单独添加一个JS;
<script type="text/javascript" src="../libs/WebGLDeferredRenderer.js"></script>
<script type="text/javascript" src="../libs/ShaderDeferred.js"></script>
<script type="text/javascript" src="../libs/RenderPass.js"></script>
<script type="text/javascript" src="../libs/EffectComposer.js"></script>
<script type="text/javascript" src="../libs/CopyShader.js"></script>
<script type="text/javascript" src="../libs/ShaderPass.js"></script>
<script type="text/javascript" src="../libs/FXAAShader.js"></script>
<script type="text/javascript" src="../libs/MaskPass.js"></script>
这样可以使用,而且多了几个参数;
var renderer = new THREE.WebGLDeferredRenderer({
width: window.innerWidth,
height: window.innerHeight,
scale: 1, antialias: true,
tonemapping: THREE.FilmicOperator, brightness: 2.5
});
这样在使用THREE.AreaLight生成平行光源;
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);
5.3镜头眩光
镜头眩光是THREE.LensFlare生成的。这个特点可以创造一个镜头眩光。
镜头眩光有以下的参数:
参数 | 描述 |
---|---|
texture纹理 | 用作眩光的材质,决定眩光的样子 |
size尺寸 | 可以指定眩光应该多大,这个尺寸单位是像素,如果值为-1,则使用本身的尺寸 |
distance距离 | 光源0到相机1的距离 |
blending融合 | 为眩光提供多种材质,融合模式决定他们如何融合在一起。默认是THREE.AdditiveBlending,它提供一种半透明的眩光。 |
color颜色 | 眩光的颜色 |
var textureFlare0 = THREE.ImageUtils.loadTexture("../assets/textures/lensflare/lensflare0.png");
var textureFlare3 = THREE.ImageUtils.loadTexture("../assets/textures/lensflare/lensflare3.png");
var flareColor = new THREE.Color(0xffaacc);
var lensFlare = new THREE.LensFlare(textureFlare0, 350, 0.0, THREE.AdditiveBlending, flareColor);
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(spotLight.position);
scene.add(lensFlare);
6.总结
1.配置光源、颜色和阴影不是严谨的科学。需要把不断尝试
2.环境光光源的颜色可以附加到场景中的每一种颜色上。它没有位置概念。通常用这种光源来柔化那些硬生生的颜色和阴影
3.点光源并不生成阴影,而且可以朝所有方向发射光线。
4.聚光灯光源类似手电筒,发射出的光线是一个锥形。而且可以配置它随着距离的增大而逐渐变弱。聚光灯光源可以设定生成阴影
5.聚光灯光源跟方向光光源一样,都有一个debug开关。可以用来微调阴影相机的配置。
6.方向光光源可以跟很远的地方光源相对比,光线都是平行的,光线里目标越远,光强衰弱的越多。
7.半球光光源,可以模拟自然的室外效果。
8.平面光光源,要用webGL延迟期优化性能。
9.LensFlare组件可以模拟眩光效果。