参考:Threejs 光照和阴影 - 知乎 (zhihu.com)
在ThreeJs中,物体的颜色也是通过光照叠加得到的,bling-Phong等模型在这里同样适用,ThreeJs将光照也封装成了一个对象。
目录
6种光照
1 环境光 AmbientLight
//环境光-常数项
//无需设置位置,也不用设置光强
AmbientLight(color);
//代码定义
var light = new THREE.AmbientLight(0xffffff);
scene.add(light);
2 点光源 PointLight
//代码定义
//()内四个参数分别表示:
//1 颜色
//2 光强(范围[0,1])
//3 光照距离(默认为0,无限远)
//4 光强随着光照方向逐渐衰减,默认为1
var light = new THREE.PointLight(0xffffff, 1, 0, 1);
light.position.set(1,1,1);
scene.add(light);
3 聚光灯 SpotLight
聚光灯是最常用的光源之一,它是一种具有锥形效果的光源,比如手电筒。
//聚光灯
//参数分别表示:
//1 color-光源颜色,默认白
//2 intensity-光强,默认为1,范围[0,1]
//3 distance-光照距离,默认为光源距离
//4 angle-角度,单位弧度,默认 Math.PI/3
//5 penumbra-照射面光影衰减百分比 默认为0 取值[0,1]
//6 decay-光照衰减指数 当=2时摔跤效果与现实世界光雷同,默认为1
SpotLight(color, intensity, distance, angle, penumbra, decay);
//代码实现
var spotlight = new THREE.SpotLight(0xffffff);//创建
scene.add(light);//添加到场景中
//单独设置属性
spotlight.angle = Math.PI/2;
//or
this.spotlight.angle = Math.PI/2;
//其他属性
//位置-position
//直接定义xyz or 用.position.set(...)定义坐标 or 用 new.THREE.Vector3(...)定义
spotlight.position.x = 1;
spotlight.position.y = 2;
spotlight.position.z = 3;
spotlight.position.set(1, 2, 3);
spotlight.position = new THREE.Vector3(1, 2, 3);
//是否可见-visible
spotlight.visible = true
this.spotlight.visible = this.lightProperties.visible//动态修改聚光灯是否可见
//目标-target
//与camera类似,决定光照方向,一般会指向场景中的一个对象
var geom = new THREE.BoxGeometry(4, 4, 4); //创建一个对象
var material = new THREE.MeshLamberMaterial({color: 0xff0000}) //创建一个材质
var cube = new THREE.Mesh(geom, material); //创建网格对象
spotlight.target = cube; //聚光灯对象为cube
其实还有很多其他的属性,比如设置阴影,这里就不赘述,关于其他属性可以参考以下文章:
three.js聚光灯SpotLight使用,调整聚光灯颜色、位置、角度、强度、距离、衰减指数、方向、可见性、是否产生阴影属性(vue中使用three.js09)_点燃火柴的博客
4 方向光 DirectionalLight
方向光是平行光,从位置position开始,向目标方向照射,不会随着距离衰减;这里的目标方向与聚光灯方向类似,目标方向可以是:1-场景中的一个物体对象(需要有位置信息),也可以指向一个点。
//方向光
DirectionalLight(color, intnesity);
//代码定义
var light = new THREE.DirectionalLight(0xffffff, 0.8);
light.position.set(0,0,0);
scene.add(light);
//目标方向-target
//target默认为原点,对于自定义的目标方向,需要加在场景中才能生效
scene.add(light.target);
5 半球光 HemisphereLight
半球光位于场景上方,可以很好的模拟真实环境室外光照效果;可以半球光(基础光照)+方向光(太阳光照)来模拟室外光照。
//半球光
//参数分别表示:
//1 skyColor天空颜色,默认为白
//2 groundColor 地面颜色,默认为黑
//3 光强 默认1
.HemisphereLight(skyColor, groundColor, intensity)
6 平面光 RectAreaLight
平面光光源从一个矩形平面上均匀发射光线,模拟明亮的窗户或者条形透明物体。平面光最大的特点是不支持阴影,其支持的材质也很有限,只支持MeshStandardMaterial和MeshPhysicalMeterial两种材质。
此外,Three.js目前还不支持平面光,需要添加lib库——RectAreaLightUniformsLib(也有说不添加lib库也能运行)
RectAreaLight(color, intensity, width, height)
//代码实例
//创建参数,不传值则为默认值
var width = 10;// 光照宽度,默认10
var height = 10; // 光照高度,默认10
var intensity = 1;
// 创建平面光
var rectlight = new THREE.RectAreaLight(0xffffff, intensity, width, height);
//位置
rectlight.position.set(5, 5, 0);
//聚焦中心
rectlight.lookAt(0, 0, 0);
scene.add(rectlight);
//有人实测发现少了这个说明也是可以执行的,这里不深究
rectLightHelper = new THREE.RectAreaLightHelper(rectlight);
scene.add(rectLightHelper);
更多关于平面光的内容可参考:深入理解three.js中平面光光源RectAreaLight_雁来过的博客
阴影
上述6种光源中,支持阴影的光照有:点光源、聚光灯和方向光。
ThreeJs中由于渲染阴影消耗较大,因此默认不显示阴影,为了实现阴影效果渲染,需要完成以下部分设置:
1 渲染器Renderer开启阴影计算
renderer.shadowMap.enabled = true;
2 光源Light支持阴影并开启光照阴影
//只有点光源、聚光灯、方向光(平行光)支持阴影
light.castShadow = true;
3 指定物体投射阴影
//指定开启
.castShadow = true;
//代码举例
//沿用聚光灯的例子:
const geom = new THREE.BoxGeometry(4, 4, 4); //创建一个对象
const material = new THREE.MeshLamberMaterial({color: 0xff0000}); //创建一个材质
const cube = new THREE.Mesh(geom, material); //创建网格对象
cube.castShadow = true; //开启渲染阴影,默认值为false
4 指定物体接受阴影
有了投射阴影的物体还没结束,还需要接受阴影的物体,例如添加一个平面用以绘制阴影。
.receiveShadow = true;
//代码实例
//创建平面接受阴影
const plane = new THREE.PlaneGeometry(300, 300); // 生成平面几何
const planeMaterial = new THREE.MeshLambertMaterial({ color: 0xcccccc });
const planeMesh = new THREE.Mesh(plane, planeMaterial); // 生成平面网格
planeMesh.receiveShadow = true; // 设置平面网格为接受阴影的投影面
阴影就介绍到这里,后续会再补充光源、阴影相关的内容。