呀哈喽!这里是 alphardex。
在使用 three.js 开发时,有时会感觉场景的渲染不是非常美观,本文就来一步一步地将一个不是很美观的场景重新焕发它的生机。
场景美化前:
场景美化后:
准备工作
首先在码上掘金上打开并 fork 这个初始场景
https://code.juejin.cn/pen/7209892060004876344
环境贴图
尽管已经有了 2 个光照,但模型还是显得非常暗,第一个任务就是要增加模型的亮度
该模型的主要材质是MeshStandardMaterial
,它是一种基于PBR的材质,PBR 材质比较容易受光照的影响,但效果最显著的还是要靠环境贴图
环境贴图往往就是 360° 的全景照片,通常可以在polyhaven网站上找到,这里选用了最常见的potsdamer_platz来模拟城市的环境光
在kokomi.AssetManager中加载 HDR 素材(加载的背后用到了RGBELoader)
1 | const am = new kokomi.AssetManager( |
用THREE.PMREMGenerator提取出 envmap,应用到scene.environment
即可
1 | const getEnvmapFromHDRTexture = (renderer, texture) => { |
1 | const envMap = getEnvmapFromHDRTexture(this.renderer, am.items["hdr"]); |
输出编码
three.js 默认的输出编码是线性编码(THREE.LinearEncoding
),这种编码会使场景看上去偏暗淡一点
为了获得一个色彩更加明艳的场景,我们需要将编码改为THREE.sRGBEncoding
1 | this.renderer.outputEncoding = THREE.sRGBEncoding; |
后期处理
如果说以上的两步是必经之路的话,那这一步可以算是画龙点睛了
Bloom
滤镜是最常用的滤镜之一,它可以照亮整个场景
SMAA
滤镜也是很常用的滤镜,它能消除场景中的锯齿,尤其是对这种顶点很多的模型颇为有效
1 | this.scene.background = this.scene.background.convertSRGBToLinear(); |
使用了它们后,会发现场景除了无锯齿外并没有什么明显的变化,别急,好戏还在后头~
在这个场景中,车灯、轮胎灯、尾灯都用到了自发光贴图emissive map
,而这个贴图的显示效果跟材质的某个参数息息相关,这个参数是emissiveIntensity,将它调高就会使自发光的效果更加显著
此外,我们也要将材质的tonemapping给关闭,因为 tonemapping 会自动把颜色的 RGB 值限制在 0-1 内,达不到自发光的要求,解除了这个限制后,我们就会发现那些地方亮起来了
还有一个注意点:在Bloom
滤镜中,我们把luminanceThreshold
设为了 1,这是为了防止场景的其他部分发亮,仅仅让那些有emissive map
的材质发亮