Three.js阴影

目录

Three.js入门

Three.js光源

Three.js阴影

Three.js纹理贴图

使用灯光后,场景中就会产生阴影。物体的背面确实在黑暗中,这称为核心阴影(core shadow )。我们缺少的是落下的阴影(drop shadow ),即对象在其他对象上创建阴影。本文主要探索是落下的阴影(drop shadow)的相关内容。

支持阴影的光源类型

前面的文章我们有介绍过,只有部分光源支持阴影:

  • 平行光(DirectionalLight)
  • 点光源(PointLight)
  • 聚光灯(SpotLight)

它们对应的阴影在three.js中也有对应的实现类:

  • 平行光阴影(DirectionalLightShadow)
  • 点光源阴影(PointLightShadow)
  • 聚光灯阴影(SpotLightShadow)

阴影的代码实现

在入门系列中有介绍阴影的基本代码实现,这里再简单叙述一遍。主要分为四个步骤:

  1. 告诉渲染器显示阴影贴图;

    复制代码
    renderer.shadowMap.enabled = true;
  2. 对需要投影的物体设置castShadowtrue

    复制代码
    sphere.castShadow = true; 
  3. 对需要接收投影的物体设置receiveShadowtrue

    复制代码
    plane.receiveShadow = true; 
  4. 最后,对可以产生阴影的光源设置castShadowtrue

    复制代码
    light.castShadow = true;

至此,我们应该就可以在接收投影的物体上看到阴影了!

阴影的实现原理

每次渲染时,three.js 将为每个支持阴影的光源都会做一次渲染。

  • 光源具有一个相机,以这个相机为视角进行渲染;
  • 光源的渲染结果被作为纹理存储起来,也就是 阴影贴图(shadow map);
  • 阴影贴图将被用于所有需要接受阴影的材质(material ),并投影到几何体(geometry )上。 有些材质不接受光照,所以材质也会影响阴影的显示。

阴影的优化和调整

阴影贴图大小
复制代码
directionalLight.shadow.mapSize.width = 1024;
directionalLight.shadow.mapSize.height = 1024;
  • 阴影贴图越大约清晰,但是越消耗资源;
  • 512和1024大小对比图,就可以看出来对比效果是1024更清晰(运行效果更明显)。
相机设置
幅度

我们先来看一个阴影不完整的现象:

正交相机OrthographicCamera

平行光源用的是正交相机进行渲染:

复制代码
export class DirectionalLight extends Light<DirectionalLightShadow> {
    shadow: DirectionalLightShadow;
}

export class DirectionalLightShadow extends LightShadow<OrthographicCamera> {
    camera: OrthographicCamera;
}
  1. 用相机辅助线看一下光线的阴影的相机视角:

    const cameraHelper = new THREE.CameraHelper(directionalLight.shadow.camera);
    scene.add(cameraHelper);

球体超过了阴影的相机视角的上边缘。

  1. 扩大相机的上边缘

    directionalLight.shadow.camera.top = 8; // 这个值不是固定的,视场景不同

far

和相机的渲染一致,设置相机的far,可以控制是否显示阴影。

复制代码
directionalLight.shadow.camera.far = 100;
Blur 模糊

我们可以使用 radius 属性控制阴影模糊:

复制代码
directionalLight.shadow.radius = 20

阴影的边缘会有模糊的效果。

阴影的类型

Three.js中,ShadowMapType枚举定义了几种阴影映射的类型:

  • BasicShadowMap:基本阴影映射类型,使用简单的阴影投影算法生成阴影。这是默认的阴影映射类型。

性能优秀但是质量不好(默认)

  • PCFShadowMap:使用 Percentage-Closer Filtering (PCF)技术生成阴影,以获得更平滑的阴影边缘效果。

性能稍差但是拥有光滑的边缘

  • PCFSoftShadowMap:使用软阴影技术生成阴影,通过多次采样和模糊处理来产生更柔和的阴影效果。

性能稍差但是拥有更 soft 的边缘

  • VSMShadowMap:使用Variance Shadow Mapping (VSM)技术生成阴影,以获得更高质量的阴影效果和更柔和的阴影边缘。

性能稍差,更多限制,有着意想不到的效果

代码实现:

复制代码
renderer.shadowMap.type = THREE.BasicShadowMap;

我项目中使用,倒是看不出来有啥大的区别。

相关推荐
冴羽14 分钟前
这是一个很酷的金属球,点击它会产生涟漪……
前端·javascript·three.js
胖虎2651 天前
Three.js 工业 3D 可视化:生产线状态监控系统实现方案
three.js
何贤4 天前
🪐 行星科技概念官网!Hero Section 回归!(Three.js ✨)
前端·javascript·three.js
爱看书的小沐4 天前
【小沐杂货铺】基于Three.js绘制三维管道Pipe(WebGL、vue、react)
javascript·vue.js·webgl·three.js·管道·pipe·三维管道
小码编匠6 天前
Three.js 遇上 Vue3 开发现代化 3D 可视化编辑系统
vue.js·typescript·three.js
阿明Drift8 天前
从炫酷粒子星云学 Three.js:深度解析一个 15 万粒子的 GPU 动画系统
前端·three.js
秋田君11 天前
3D热力图封装组件:Vue + Three.js 实现3D图表详解
javascript·vue.js·3d·three.js·热力图
Mintopia14 天前
🌌 Three.js 几何变化动画配合噪声粒子教程:让你的代码也会“呼吸”
前端·javascript·three.js
爱看书的小沐19 天前
【小沐杂货铺】基于Three.js渲染三维风力发电机(WebGL、vue、react、WindTurbine)
javascript·vue.js·webgl·three.js·opengl·风力发电机·windturbine