深入理解three.js中平面光光源RectAreaLight

前言

之前有深入讲解过Three.js中光源,在那篇文章的最后也说了由于平面光光源的特殊性,所以会单独拿出来讲解,这篇文章会详细的讲解平面光光源的特性和实际应用该如何使用。

首先,平面光光源从一个矩形平面上均匀地发射光线,这种光源的主要应用场景是模拟明亮的窗户或者条状灯光光源,实际在开发家具建模项目中会有广泛应用。平面光光源的最大特点事不支持阴影,我们无法通过设置RectAreaLight.castShadow = true来映射让物体显示阴影,而且,平面光光源支持的材质也很有限,只有MeshStandardMaterialMeshPhysicalMaterial两种材质。有一点需要特别说明下,查看官方文档中有 你必须在你的场景中加入 RectAreaLightUniformsLib ,并调用init() 注意事项,但是我在项目中使用发现,我不添加RectAreaLightUniformsLib也是能够正常运行的

原理说明

创建一个平面光光源很简单,官网实例如下:

 1 var width = 10;
 2 var height = 10;
 3 var intensity = 1;
 4 var rectLight = new THREE.RectAreaLight( 0xffffff, intensity,  width, height );
 5 rectLight.position.set( 5, 5, 0 );
 6 rectLight.lookAt( 0, 0, 0 );
 7 scene.add( rectLight )
 8 rectLightHelper = new THREE.RectAreaLightHelper( rectLight );
 9 scene.add( rectLightHelper );

new THREE.RectAreaLight用于创建平面光光源构造器函数,该函数有四个变量,分别是colorintensitywidthheight,以上四个参数都是可选参数,如果不传都会按照默认的值来创建平面光光源。

color:(可选参数) 十六进制数字表示的光照颜色,缺省值为 0xffffff (白色),实测中发现使用HEX格式和RGB格式都是可以的,但是RGBA格式不支持。

intensity:(可选参数) 光源强度/亮度 ,缺省值为 1,实测最小值为0,最大值不限,2为自然光亮度。

width:(可选参数) 光源宽度,缺省值为 10,只要不小于0都可以。

height:(可选参数) 光源高度,缺省值为 10,只要不小于0都可以。

rectLight.position.set( 5, 5, 0 ) 这行代码用来指示平面光光源位置,这个位置可以随意设定,只要在camera设定的范围内都可以,如果超出了我们将什么都看不到,当然这个位置最好离映射物体不能太远,因为本身平面光光源模拟的是窗口光,所有它的辐射距离很有限,位置设定离物体太远将无法映射物体。

rectLight.lookAt( 0, 0, 0 )这行代码用来指代平行光光源指向的中心位置,一般情况下会指向需要映射物体的中心位置。

rectLightHelper = new THREE.RectAreaLightHelper( rectLight )这行代码再次说明下,实测中删掉也是可以正常执行的。

应用场景说明

首先,需要说明,Three.js中的所有光源在场景中是没有任何显示的,我们是感知不到光源的,所以为了模拟现实中的光源点,比如太阳、灯泡等,我们一般会通过创建一个材质为MeshBasicMaterial的物体来替代现实中的光源。至于为什么会选择MeshBasicMaterial的材质来替代光源,后续我会专门写一篇博文来详细讲解MeshBasicMaterial这种材质。回到平面光光源,项目中模拟平面光光源通常会通过面板来指代光源,一般使用的比较多的是平面缓冲几何体PlaneBufferGeometry。

平面缓冲几何体替代平面光光源位置的时候,我们需要创建两个平面缓冲几何体,这样做是为了保证我们看到平面光光源指向的是同一个方向。

平面光光源正面平面缓冲几何体代码如下:

1 var rectLightMesh = new THREE.Mesh( new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial( {color:'#ffffff' side: THREE.BackSide } ) );
2 rectLightMesh.scale.x = rectLight.width;
3 rectLightMesh.scale.y = rectLight.height;
4 rectLight.add( rectLightMesh );

上述代码中,rectLight表示已经创建好的平面光光源,rectLightMesh 表示平面光光源正面的平面缓冲几何体,正面的平面缓冲几何体我们一定要设置智能单面查看,必须设置side = THREE.BackSide,这样做是为了保证方面的平面缓冲几何体能够上色。

平面光光源反面平面缓冲几何体代码如下:

1 var rectLightMeshBack = new THREE.Mesh( new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial( { color: 0x080808 } ) );
2 rectLightMesh.add( rectLightMeshBack );

上述代码中,rectLightMesh表示的是我们上一步创建的平面光光源正面缓冲几何体,rectLightMeshBack 表示是的我们创建的平面光光源反面平面缓冲几何体,这一步中我们只需要将创建的反面平面缓冲几何体添加到上一步创建的正面缓冲几何体中即可。

平面光光源实例

实例效果图如下:

实例介绍:

实例中,创建了一个平面,这个平面用来限定平面光光源的光照范围,平面上创建了三个物体,分别是一个球体,一个正方体,一个管状体。场景中添加了亮度为0.1的自然光,防止场景太黑影响视觉,也可衬托平面光光源。创建了亮度为1的平面光光源,在平面光光源位置添加了正反两面平面缓冲几何体。为了能够更好地感受到平面光光源在应用中亮度与距离的关系,因此在实例中添加了动画,用于随机移动平面光光源。

实例预览地址:深入理解three.js中平面光光源RectAreaLight

后话

希望上述讲解能够帮助到您,上述见解纯属个人理解,如果有理解不到位的或者表述有误的还请留言说明,共同学习,共同进步。

原文地址:https://www.cnblogs.com/gaozhiqiang/p/11543199.html