todaylg

EnvTools

2020-3-03 todaylg大结

我们知道实时PBR渲染中的IBL部分是可以预计算的,主要包括:

  • Diffuse部分:辐照度图(irradiance map)或SH(Spherical Harmonics)

  • Specular部分:不同粗糙度级别对应的环境贴图、BRDF积分(LUT)

一些部分也可通过近似来达到实时计算:

比如LUT可以通过数学曲线来近似:

// https://www.unrealengine.com/blog/physically-based-shading-on-mobile
vec3 integrateBRDF(const in vec3 specular, const in float roughness, const in float NoV, const in float f90) {
    const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022);
    const vec4 c1 = vec4(1.0, 0.0425, 1.04, -0.04);
    vec4 r = roughness * c0 + c1;
    float a004 = min(r.x * r.x, exp2(-9.28 * NoV)) * r.x + r.y;
    vec2 AB = vec2(-1.04, 1.04) * a004 + r.zw;
    return specular * AB.x + AB.y * f90;
}

以及Three R112以后直接纳入核心API的PMREM(Prefiltered Mipmapped Radiance Environment Map)

这里又歪出来跪一会,R112之前的PMREM是由Prashant Sharma老哥实现的,和这位印度老哥有过一些交流,其已是自由职业,不仅Shader写得惊为天人,甚至还保持着晨练的健康习惯,代码好又身体壮,xmsl。。。

近似和简化毕竟还是会造成一定的效果损失,所以一个好的离线预计算Envtools其实很关键。

现有的一些处理工具包括:

但要数其中功能最多最强大的,那还得看envtools。

毕竟宇宙最强Web渲染SketchFab便是基于osg.js的。

Envtools

在简单的学习一些涉及的知识后(Docker、Cmake、C++、Python)后,便可以一窥强大的envtools到底都干了啥啦。。

envTools

核心指令:

envremap

提供任意两种格式之间的转换,包括:

rect

极坐标映射,入射方向r(x,y,z)对应的纹理坐标为:

image

image

投影计算包含反三角函数,计算效率不高,且在两极附近会有较大拉伸。

ball

球面映射,缺点是采样分布非常不均匀,球面边缘附近大量方向会被映射到边缘较窄的面积。

cube

立方体映射,目前使用最多的映射方式。

关于seamless CubeMap的问题,CubeMap在边缘的顶点采样需要考虑其他面,即需额外采样相邻面进行插值才能得到正确的结果。

WebGL已经提供了API支持,但一些老的浏览器并不支持seamless CubeMap,envtools的解决方法:Nvidia的texture-tools的修复方法

剩下的domehemi介绍可见Readme,不赘述

在格式转换过程中还可以控制不同的超采样方法(cent/rgss/box2/box3/box4)

Three中也提供了实时的直方图转CubeMap方法,即WebGLRenderTargetCube.fromEquirectangularTexture(R110之前为EquirectangularToCubeGenerator)

envIrradiance

生成irradiance map并输出SH,计算全局光照中的间接光照

SH可以用作近似irradiance map,通过SH coefficients可重建低频的环境光

相关文章:

Three目前对IBL的间接光照部分计算用的是环境贴图的最低一级的mipmap(见函数getLightProbeIndirectIrradiance)

对SH的相关的讨论:

envPrefilter

不同粗糙度对应预计算得到的CubeMap,相关文章:

Three PMREM(^R112)的实现,直接上的高斯模糊(应用在球面极坐标系),也没有见到相关的Refer,算是个Hack吗?。。

envBRDF

单独计算并输出BRDF的LUT, 相关文章:

envBackground

耗时最长的一步,相关文章:

filament是直接延用按粗糙度模糊的方法,速度相对较快。

extractLights

分析环境贴图中的明亮区域,从而提取出方向光的方向及亮度等信息

一般用于提取环境贴图中的太阳信息,Viewer中可以在相应位置通过添加一盏方向光来模拟太阳。

相关文章:

process_environment

串联起所有模块的控制入口,除了上面的模块外还添加了:

  • 压缩打包

  • 缩略图生成

  • GPU计算加速

其基本流程为:

initBaseTexture

通过oiiotool(OpenImageIO)将输入文件转化为tiff格式的panorama_highres,调用envremap_cmd生成cubemap_highres

thumbnail_create

通过oiiotool将cubemap_highres缩放到所需缩小的尺寸即可

cubemap_specular_create_mipmap

调用envremap_cmd将cubemap_highres按mipmap级数进行resize,加速后面的预处理

specular_create_prefilter

调用envPrefilter_cmd进行预处理(panorama、cubeMap),有mipmap的话则直接加载mipmap

extract_lights

通过oiiotool将panorama_highres缩放1024x512,再调用extractLights_cmd输出灯光信息

background_create

按传入的background_size复用对应尺寸的mipmap(没有则取第一层),再调用envBackground_cmd进行背景模糊处理

compute_irradiance

调用envIrradiance_cmd对cubemap_highres分析输出irradiance Map及输出shCoef

compute_brdf_lut_ue4

调用envIntegrateBRDF_cmd输出lut

cubemap_packer

调用cubemap_packer_cmd将mipmap数据打包为二进制,在viewer中再进行解包

compress

调用compress_7Zip_cmd对图片资源进行压缩

writeConfig

将所有相关信息输出到config.json

zip

最后调用compress_zip_cmd将整个文件进行zip打包

整个envTools应用的效果可见:https://github.com/todaylg/three-viewer

Todo

  • 升级Unbutu及相关依赖包,删除冗余依赖

  • 仅打包Viewer所需资源,直接输出为单个zip包

  • 直接输出多级背景模糊

  • 学习如何应用OpenCL/Cuda计算加速