ThreeJs学习笔记【day14】阴影 【1】

252 阅读2分钟

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

阴影

Three.js 默认使用shadow maps(阴影贴图) ,阴影贴图的工作方式就是具有投射阴影的光能对所有能被投射阴影的物体从光源渲染阴影。

这句怎么理解? 首先需要拆分几个关键字,具有投射阴影的光所有能被投射阴影的物体从光源渲染

  • 具有投射阴影的光: 哪些光源有投影?之前的文章中探讨过,环境光,半球光没有投影,方向光,点状光,聚光灯,矩形区域光均有投射阴影
  • 所有
  • 能被投射阴影的物体: 取决于材质,基础网格材质不受光照影响,Lambert网格材质只在顶点响应光照,Phong网格材质则是每个像素都响应光照,标准网格和物理网格均可投射阴影,深度材质,法线材质,阴影材质,着色器和自定义着色器材质均支持阴影投射
  • 从光源处渲染 指定了阴影的方向性

举个栗子,假设有20个物体,5个光源,物体与光源均可投射阴影与被投射阴影,那么,将会渲染6次,为什么是6次,5个光源会渲染5次,第六次则是基于前五次的绘制结果进行叠加,特别的,假如你有一个可以投射阴影的点光源,那么基于这个点光源和其他光源的交互,他还会渲染6次来进行修正。所以,除了寻找其他根本上的解决方案去解决一堆光源都能投射阴影的性能问题。一般还有常见的解决方案,就是允许多个光源,但只让一个光源能投射阴影,另一个解决方案就是使用光照贴图或者环境光贴图,预先计算离线照明的效果。这将导致静态光照,但是至少该方案渲染的非常快。再另一篇文章中将涵盖这两个解决方案。 其他的解决方案是使用假的阴影。举个例子,做一个飞机模型,将它的平面纹理做灰值处理,将其绘制再模型的下面的地面上

演示材料准备-地面+阴影贴图

还是利用地面, 小球,和立方体,我们通过修改材质,修改光源的方式来探索阴影

  • 将背景设置为白色
scene.background = new THREE.Color("white");
  • 将地面设置为基础网格材质,然后设置颜色为浅灰色浅白色
const planeMat = new THREE.MeshBasicMaterial({
  map: texture,
  side: THREE.DoubleSide,
});
planeMat.color.setRGB(1.5, 1.5, 1.5);
  • 加载阴影贴图
const shadowTexture = loader.load("https://threejs.org/manual/examples/resources/images/roundshadow.png");

下一章,我们将会创建一个球,通过循环的方式假如3D对象,然后处理阴影和球体,观察阴影渲染状态