在Shader里面,反射和折射的实现其实很简单。关键是使用者要懂得把它们使用在哪里。一起来复习一下啦。——ZwqXin.com [Shader快速复习:Per Pixel Lighting(逐像素光照)] 本文来源于 ZwqXin (http://www./), 转载请注明 首先,反射与折射的物理就不多说了。光线矢量在两种介质之间发生方向的改变,而人眼睛和目标物分别在这两种介质当中,非直线的光线连接两者。然而人总会“自觉”地认为自己的视线总是直线,所以看到目标物在原始位置的上前方,此为折射现象。反射类似。其实这样理解不直观,更“白”点地说,人的视线在图中5线交汇处的点(称O点)停顿了,所看到的只是交界面处的O点的颜色,好比交界面是一块镜子,人所见的只是镜子的像,而这像由两部分组成,一是沿着反射光像来的“投影”,二是镜底沿着折射光线来的“投影”。是的,真真假假在这里已经不重要了,因为这是图形学中反射与折射的“图形学原理”啊。 譬如绘制一个湖面后,我们为了要让湖面真实表现反射与折射,需要真的在湖底把真实世界再绘制一次吗?恩,我在学模板缓冲的时候尝试过(小场景),况且不提效率上的浪费,如果湖面不是场景的“底面”呢?这样就很不好办了吧。折射方面,因为湖底物没有其他参照嘛,肯定要画的。但是有时候你只不过想表达一下湖底的境况——譬如静止的沙床,你其实只需要一张纹理就够了,什么都不用画(如果你觉得可以更随便,干脆忽略折射)…… 要做到这样,就要考虑图形学上的折射和反射了。把湖面作为一块大镜子,在上面帖帖花吧~恩,就是帖纹理,多重纹理的混合。 1.在哪里找这种纹理呢? 答案是立方环境帖图[Shader快速复习:Cube Mapping(立方环境贴图)] 。而且不仅是通常的反射向量,折射向量同样可以用来检索cubemap:
其中,WaterTex是水纹理的纹理句柄号;WaterCube是环境纹理的句柄号(静态场景中最常见的,是直接把天空盒的纹理组成CUBEMAP环境纹理)。 2. 反射向量,折射向量怎么来的啊? 恩,有了上面那张原理图,有了眼睛(相机)坐标,有了湖面中各个顶点的坐标,湖面的法向量,还有两种介质的折射率,当然可以自己动手计算了。但是其实这种小计算,GLSL还是给我们准备好的了:
refract函数和reflect函数,很容易了解。最后是乘以视图转换矩阵的逆矩阵,把向量转回世界空间了。在橙书里提到可利用gl_TextureMatrix纹理矩阵[再弹OpenGL矩阵——到另一个空间去] ,但其实不是说要做什么纹理坐标变换,只是用来保存旋转而已。 最后把它俩作为varying经过插值输出到fragment shader,也不需要重归一化了,因为只用来检索CubeMap(见上篇)。 3.怎样确定反射与折射结果之间的混合因子? 其实就是上面提到的Ratio。有这么一种现象:我们在湖边看湖的时候更多地看到的是反射的结果,在湖的上空望下去则更多看到的是折射的结果——换言之,这个混合因子应该跟我们看湖的角度有关(入射角,上图的Θ)。这叫Fresnel现象,用其发现的关系式表达,则是:......呃,听说挺复杂的,于是Christophe Schlick 为我们计算机图形学编程提供了一条近似的简单式: Ratio = f + (1 - f) (1 - InVec · norm)fresnelPower 式子的几个参数含义就是上面所说的。另外fresnelPower一般取5就可以了。而 f 则明显得与具体的介质有关,即跟折射率有关: n1/n2就是空气与水间的折射率了。 同时对环境帖图拥有反射和折射的模型(renderMonkey内): 本文来源于 ZwqXin (http://www./), 转载请注明 |
|
来自: LVADDIE > 《rendering》