之前说过立方体贴图,它是环境贴图技术的一种实现方式,能够模拟物体周围环境,使用了环境反射的物体可以看起来像表面镀了一层金属一样反射处周围环境。反射探针就是基于立方体贴图实现的一种unity组件。
但是立方体贴图没有什么可调整性,它产生的反射性很强烈,一般只适用于金属、镜子等具有强反射特性的材质,并且开发者并不能灵活控制它。那么有没有一种技术,可以灵活控制立方体贴图技术的反射性,让它是适用于任何材质的物体呢?
这种技术就是基于图像的照明技术(简称IBL)!
IBL的设置
IBL是基于立方体贴图技术改进的一种环境反射技术,它最大的特点是可以灵活控制反射属性,轻松模拟出物体材质光滑、粗糙等特性。这时普通的立方体贴图技术难以做到的。
要使用IBL,只需要将cubeMap的Convolution Type属性 设置为Specular(Glossy Reflection)。
另外,还需要将过贴图的过滤模式filter mode设置为Trilinear(默认为Bilinear),Trilinear能够在不同的mip map层级中进行插值计算,这样保证了每个层级的贴图过渡效果都很顺滑,这是Bilinear无法做到的。
环境反射模拟的是间接光照,将IBL设置为Specular,模拟的是间接光照的镜面反射(高光),如果设置为Diffuse,IBL将模拟间接光照的漫反射效果。
除了直接设置立方体贴图的Convolution Type属性可以用IBL外,还可以通过添加反射探针烘焙贴图的方式动态生成IBL技术的立方体贴图。通过烘焙方式生成的IBL贴图不需要进行任何设置,在烘焙的过程中unity已经帮助我们设置好了
基本原理
IBL并不像cubeMap那样直接存储纹理信息,通过将cubeMap的Convolution Type属性 设置为Specular(Glossy Reflection),unity为帮助我们做了一个IBL最重要的操作:获取到环境贴图后对它进行了一系列离线的光照计算,然后生成了新的光照结果,并把它存储在mip map层级中。
也就是说IBL还有一个重新计算光照的过程,也正是因为如此,我们才能对重新计算的光照进行调整,从而模拟出更多的材质效果。
IBL 光照计算后的cubeMap,会比计算之前更粗糙一些,这些粗糙度信息分布在每个mip map层级中,通过调整层级我们可以看到cubeMap的过渡会比计算之前更流畅。
调整mipMap层级有什么作用呢?
我们知道,区分材质与材质的不同,其中一个非常重要的属性就是粗糙度,通过调整粗糙度,就能模拟出不同的材质效果,而这个mipMap层级的调整,就能达到异曲同工的效果。
手动采样
接下来,我们在shader 中配置一个粗糙度的参数,通过设置粗糙度来采样不同层级的mip map,这里使用texCUBElod()方法,对cubeMap进行采样。
_Roughness("Roughness",Range(0,1))= 0.5
float _Roughness;
float mip_Level = _Roughness * 9.0; // mipmap 9个层级
half4 colorCubeMap = texCUBElod(_CubeMap,float4(reflect_dir,mip_Level));
half3 env_hdr_color = DecodeHDR(env_color,unity_SpecCube0_HDR);
cubeMap通常有9个层级,因此在代码中_Roughness参数 乘以了一个9.0,这样就能灵活切换贴图各个层级的mipMap。
代码中的unity_SpecCube0_HDR,是unity内置的一个专门用于获取cubeMap贴图的变量。
通过设置Roughness参数,就可以调节cubeMap的粗糙度,这样能轻松模拟出金属、非金属的材料质感
这种方式,适用于自定义IBL贴图的场景,如果是由反射探针烘焙生成的IBL贴图,要采用什么方式呢?
自动采样
要对反射探针自动生成的贴图采样,需要使用的unity配置的一个方法UNITY_SAMPLE_TEXCUBE_LOD(),分别传入unity_SpecCube0(内置变量)、反射方向、mipMap层级,这样就能获取到基本的颜色贴图。
之后再对它进行解码操作即可,其他代码和手动采样基本一致。
half4 colorCubeMap = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0,reflect_dir,mip_Level);
half3 env_color = DecodeHDR(colorCubeMap,unity_SpecCube0_HDR);
以上就是IBL技术的最简单展示,我们重点要掌握IBL的基本技术原理,它在Unity中该如何设置,使用shader如何采样IBL贴图。
在实际项目过程中,IBL并不是单独存在的,它通常还会与光照模型、后期处理技术结合一起使用,代码复杂度也会加大。