zoukankan      html  css  js  c++  java
  • Parallax Mapping

    首先,我们要知道视差贴图Parallax Mapping的作用,为什么要引入它。

    对于一张原本2D的图片,我们通过使用法线贴图,使其表面表现出了一定的凹凸感,细节感。但是还是可能会出现一些问题,法线贴图只能通过明暗来表现凹凸,同时它忽视了现实中的一些效果。比如说遮挡的效果,只应用了法线贴图的纹理无法塑造出正确的遮挡效果(这里的遮挡效果要和深度测试区分开,你也可以说这种效果为“更加强烈”的凹凸感,并且这种凹凸感还能调整),顶多明暗变化一下就完了。

    图形学是基于现实的模拟,如此问题当然不能容忍,于是就有了后来的视差贴图。


    我们给出一张图片

     如上所示,在应用了法线贴图之后,我们能看到的平面就是红线,但实际上的平面还是平的,红线所代表的平面实际上是不存在的。

    由于这个特性,当我们的视线看向点a的时候,实际上看到的却是点b的纹理。想要获得更加真实的效果的话我们就需要将b点纠正到a点。当然,这里的纠正到a点并不是指真的纠正到a点,实际上因为红线(即表面的凹凸)是不存在的,所以“纠正”的意思其实是纠正到a点对应的纹理像素(texel),也就是经过a点作一条垂直于平面的直线,交点为纹理像素的位置。然后再通过应用法线贴图,创造出看到红线表面。

    为了方便计算,我们将以下的计算都放到切线空间中。

    那么问题来了,我们如何将b点纠正到a点(所对应的纹理像素)呢?这个时候就引入了高度贴图height Map,它用颜色通道的方式记录了平面上各个点的凹凸程度,黑色(0)不凸起,白色(1)完全凸起。具体怎么应用,请看下图:

     首先我们在高度贴图中获取b点的高度(当然是我们赋予它的高度,而不是这东西就有这么高,请永远记住,实际的平面一直是2D的,没有任何凸起),然后沿着视线作相同长度的向量,再过此向量的终点,作垂直于实际平面的垂线,垂线与平面的交点up就是我们要采样的纹理像素(这个纹理像素会被应用于顶点位置的b点)。

    缺点也是有的,看上图就知道up和ua有距离,并且这个距离还会随着视线的改变而改变,我们基本上不能得到真正的ua纹理像素。当物体的表面高度变化极快的时候,这个距离还会进一步增大。

    于是在这个基础上,提出了改进的方法:陡峭视差映射(Steep Parallax Mapping)。

    我们不再只通过一个值来接近a(ua),毕竟那样误差太大。取而代之,我们使用“逼近”的方式来靠近a(ua),从而减少误差。具体方案如下:

    如上所示,我们将高度分层,然后将视线与高度线的交点标记起来,不断地逼近点a(ua),直到找到第一个高度比a点要低的交点,然后过这点作垂线,得到的坐标up既是我们要采样的纹理像素坐标。我们可以通过增加高度线的数量来达到更加精确的效果,虽然通过不断的增加高度线的数量,可以使得结果越来越精确,但是这无疑需要消耗更多的性能。

    于是我们考虑改进陡峭视差贴图:不是找到第一个高度比a点要低的点,而是在两个接近的深度层之间进行插值。这种方法就好比数学中的零点,从高度比a点要高的点,到高度比a点低的点,我们必然能取到最接近a点的点(当然也有可能直接找到a点,只要精确度够)。

    以上。

    参考资料:

    [1]视差贴图(Parallax Mapping)

    P.S. viewDir.xy是将视线投影到xy(uv)平面;而除以viewDir.z是考虑到当视线角度改变的行为,(viewDir进行过标准化)viewDir.z的值在[0.0, 1.0]之间,当视线无限接近水平的时候,P的长度应该更大(假设同一高度的话,当然,高度不统一(更低)的话就更需要)。因此我们用viewDir.xy / viewDir.z,当然这是非必须的。

    最后ParallaxMapping函数的返回值用 TexCoords - P,是因为我们需要将新的纹理坐标往左挪,让它去对应更左边的顶点坐标。

    原来人类的悲欢并不相通, 我只觉得他们吵闹。
  • 相关阅读:
    Set存储元素为啥是唯一的(以HashSet为例源码分析)
    HashTable原理与源码分析
    手写spring(简易版)
    java--String equals方法
    [java]创建一个默认TreeMap() key为什么不能为null
    [java]类初始化挺有意思的题目
    [java] 为什么重写equals()必须要重写hashCode()
    java --Integer 学习
    减少重复代码的书写--Lombok
    JavaScript随笔
  • 原文地址:https://www.cnblogs.com/zhlabcd/p/11908547.html
Copyright © 2011-2022 走看看