ThreeJs学习笔记【day15】阴影 【3】

243 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第15天,点击查看活动详情 >>

方向光阴影相机是正交相机

正交相机在width和height为100的时候,阴影出现了马赛克纹理,这是因为,被投射产生的阴影也是有纹理的,这些阴影的纹理也是有单位大小的。如果阴影相机的属性设置的越大,就意味着它能投射的区域也变得很大,就意味着投射的阴影会越来越块状。

你可以设置light.shadow.mapSize.width和 light.shadow.mapSize.height来设置阴影的纹理分辨率。他们默认为 512X512。如果设置的很大,他们在计算时将占用更多的内存,并且变得很慢。为了获得更真实的阴影,应该尽量将值设置的最小。请注意在渲染器中该属性renderer.capabilities.maxTextureSize对于每个用户都有最大纹理的上限值。

这里还记得正交相机的属性是吧,top,left,right,bottom,near,far,width是由left->right决定的height由top,bottom决定的,正交相机的视野是一个长方体,投射的阴影会越来越块状:因为相机渲染区域的扩大,在细节上会有意识的去弱化,这个是优化决定的,就像在相机篇的文章讲的一样,我们必须选择适合的远近大小来渲染我们的元素,灯光上阴影的mapSize和纹理里讲到的mips是类似的原理,都是为了提高渲染性能,提升渲染速度。

聚光灯是透视相机

当我们切换到 SpotLight 聚光灯时,光源的阴影相机就变成了PerspectiveCamera透视相机 ,与DirectionalLight 定向光的阴影相机不同,SpotLight 聚光灯的阴影相机有其本身所控制,我们也可以手动设置大部分设置。SpotLight聚光灯阴影相机的的fovSpotLight聚光灯angle 关联。aspect属性是根据阴影映射自动设置大小的。

PointLight 聚光灯是向四面八方发散的,所以唯一的设置只有near 和 far。实际上PointLight 聚光灯 相当于 6 个面的SpotLight 点光源组合而成。这意味着它的渲染速度要慢得多,相当于整个场景的阴影和渲染 6 次,每个方向(面)都需要渲染一次。

为了方便观察,这里我们创建一个正方立方体盒子,模拟墙壁和天花板的阴影效果。我们设置材质的属性,只让它在盒子的内部渲染,就像地板一样。我们还设置它可以被投射阴影,并且将它的高度设置的比地板稍微低一点,防止 Z 轴渲染重合,这样,来看一下聚光灯的效果

const cubeSize = 30;
const cubeGeo = new THREE.BoxGeometry(cubeSize, cubeSize, cubeSize);
const cubeMat = new THREE.MeshPhongMaterial({
  color: '#CCC',
  side: THREE.BackSide,
});
const mesh = new THREE.Mesh(cubeGeo, cubeMat);
mesh.receiveShadow = true;
mesh.position.set(0, cubeSize / 2 - 0.1, 0);
scene.add(mesh);

image.png

使用 GUI 的position来移动光源的位置,你就可以看到墙上阴影强度的改变。你还可以调整其他的设置,比如near 和 far ,near代表最小的渲染阴影的距离,这只会渲染物体的距离大于其值的物体的阴影。 far 这代表渲染比其值距离小的物体的阴影