Three.js开发指南-光源

6970次阅读
没有评论

共计 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组件可以模拟眩光效果。

正文完
 0
Chou Neil
版权声明:本站原创文章,由 Chou Neil 于2017-07-24发表,共计7776字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。