更新于 

Realistic Scenes 真实场景

HDR/Tone Mapping/Gamma Correction/sRGB Color Space

HDR

什么是DR?

DR全称Dynamic Range
表示传感器或显示屏能够捕捉图片中最亮和最暗点之间的差异,
设备能能够捕捉的DR值越高,
图片显示的细节程度就越高。

HDR全称High Dynamic Range
要制作一张HDR图片(即光影分辨率较高的图片),
摄影师需要先拍一张中间调的图片,
然后拍几张亮度不同的图片,
通过像Adobe Lightroom这样的软件合成在一起。

Tone Mapping

HDR和EXR格式的图片文件包含的数据量更大,
因此选用16/32bit编码,
但是大多数显示屏都是8bit/10bit的,因此在显示这些图片时会丢失很多细节。

想要解决这个问题:

  • 可以用Photoshop等专业图像处理软件
  • 也可以使用Tone Map映射算法

Tone Map映射方法能够解决这个问题,
它可以使用算法映射的方式,
使8bit编码中能够蕴含16/32bit编码的信息

Gamma Correction

随着实际亮度的增高,人眼对亮度的感受往往更弱,
这是因为人眼对黑暗的反应比对光的反应更加敏感。

与人眼相反,显示屏显示出的亮度往往要高于实际亮度

Gamma Correction就是对这种差异进行校正的方法:
在要显示的图片亮度上使用人眼反曲线调整,这样最终显示出来的亮度会被校正到线性关系上

Gamma Correction的方法在jpeg/png等格式的图片内部完成,
因此这些格式的图片数据使用反曲线格式保存,要更亮一些。

而HDR、EXR类型的文件使用的仍然是线性格式保存,
因为大部分CGI、游戏渲染器都需要线性工作流程,
因此使用线性格式图片进行开发。

sRGB Color Space

ThreeJs中渲染HDR图像,
需要通过图像的原始颜色(sRGB)计算出像素颜色,
再根据编码算法进行Gamma Correction

sRGB指的是最纯正的RGB颜色

场景渲染

环境加载

为scene添加360°HDR背景图,需要注意以下操作:

  • 使用 RGBELoader 加载图片
  • 材质的映射方式应为 EquirectangularReflectionMapping
  • 需要将渲染器加载图片的编码格式配置成 sRGBEncoding
    • 0.152.0版本的threejs默认是sRGBEncoding格式的
    • 在这之前的版本中默认值都是LinearEncoding编码格式
  • 将ToneMapping算法配置成ACESFilmicToneMapping
  • 适当调整ToneMapping曝光率属性
1
2
3
4
5
6
7
8
9
10
11
12
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader'

renderer.outputEncoding = THREE.sRGBEncoding
renderer.toneMapping = THREE.ACESFilmicToneMapping
renderer.toneMappingExposure = 1.8

const backgroundUrl = new URL('../asserts/kitchen.hdr',import.meta.url)
const rgbeLoader = new RGBELoader()
rgbeLoader.load(backgroundUrl.href, texture => {
texture.mapping = THREE.EquirectangularReflectionMapping
scene.background = texture
})
环境加载

环境贴图可以将物体放置在指定的环境光下渲染,
无需外加光源,
可以使用全局环境配置的方式:

1
scene.environment = texture

也可以单独对物体进行环境光贴图:

1
2
3
4
5
6
7
8
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(3,50,50),
new THREE.MeshStandardMaterial({
roughness: 0,
metalness: 1,
envMap:texture // 贴图属性
})
)