zoukankan      html  css  js  c++  java
  • [图形学]视差映射(Parallax Mapping)

    这是个最近几年才开始出现在实时游戏中的技术,其实概念早在2001年的时候就由一个日本人在论文中提出了,而后又有很多人在实时贴图方面上发表过各式各样的论文,到2006年的时候由另一个日本人(看来日本人在视频游戏中做出的努力和贡献确实不小)在论文中较好的实时呈现了这个算法,这些人为了区分自己的算法,不停地添加了各种各样的副名称”with offset limited”、“Occlusion”、”with Approximate Soft”等等,不过宗旨都是一样的~
        我在网上大概搜了搜,找到几篇也都是把它讲的很玄的,真正清楚阐述的,不多,呵呵,在这里把我的理解记下来,权作笔记。
    aotu    视差映射的宗旨和各种贴图技术都一样,为的是能够以很小的代价实现模型表面上一些比较细致的细节上的出色描绘。目前法线贴图技术可以说是已经真正的成熟了,我们在虚幻三引擎开发的游戏中(代表作《战争机器》)能看到的各种物体上的表面细节,而这些细节正是全拜法线贴图技术所赐,视差映射与凹凸法线贴图一样,都是利用一张额外的贴图计算来实现在一个平整的多边形面上产生出凹凸错落的起伏感,只是视差映射能实现的起伏感更加强烈罢了。在下一代的视频游戏中,相信视差映射将会成为非常普及的应用的。 
        后面这个链接里是我以前写的凹凸贴图的算法详解,虽然写的囫囵吞枣,但总算大概写明白了,呵呵,有了这个基础之后再来看视差映射会容易很多。 
         凹凸贴图成功的实现了利用额外的法线干扰平面法线最终影响光影反射颜色的计算,已经可以做到在一定范围内使得平面看上去是凹凸起伏的,但是因为平面本身这个特点并没有改变,所以当视角与平面的角度越接近平行的时候,看上去就越像个光板,所以此后的贴图技术几乎都在努力克服这个缺点。 
        上图和下图都是视差映射的原理图,不过下面这张更明白一些:
    pm01    我们可以看到Viewer,这是我们的观察点,Polygonal surface是多边形的平面,我们需要的是一张材质贴图和一张四通道的辅助贴图,其中辅助贴图的三个通道负责保存该点实际的法线空间(非平面),另一个通道负责保存该点从平面到实际的高度值(0-1区间)
        原理是这样的,我们的视线和平面的交点是to,也就是说用最传统的贴图技术我们看到的是to点的颜色,即使我们使用了凹凸贴图的技术,我们看到也是经过法线干扰的该点的颜色,而我们实际看到的点应该是我们的视线和物体实际的表面(图中Extruded surface profile)上的交点,也就是toff的颜色,我们要做的,就是正确的计算出这个点。
        好,下面我们要开始整个的计算步骤,可能过程会比较乱,我的表达能力很有限,时间长了自己回头看都会经常看不懂的,呵呵-。-
        首先我们需要计算出来的是切线空间内的最大偏移向量,就是说转到切线空间内后的观察视角向量的X、Y坐标平面上的偏移的最大值,在下图中就是to到toff方向上的蓝色向量P(每一个点所对应的P都是不相同的),我们假设在这个点上应该看到的点的高度是最大的,也就是1.0,我们能已知观察向量的xy平面投影向量的长度,和z的高度,这样同P向量和该点的高度值正好组成相似的直角三角形,根据勾股定律和相似三角形比例相同我们可以求出P的长度等于|VIEW.xy|/|VIEW.z|*1.0,而方向很简单就是视角向量在平面投影VIEW.xy的方向。
    PM02    得到最大偏移向量P之后,就要来寻找在P向量的长度内究竟那个点是toff,目前现有的比较好的方法是采用步进搜索的方式进行计算,这也就是为什么要计算P向量的原因了,我们将P向量分成若干段,从to开始每次累加一个步长,也就是如上图所示,当这一点的实际高度值小于这一点的视角直线同平面形成的三角形的高度时,继续累加一个步长,直到大于,说明正确的点应当位于前后的两个步长之内。
        插一句,如何确定步长应该是多少呢,呵呵,当然是步长比例(占整个P的比例)越小,采样次数越多,结果自然越精确了,在视差映射中存在这样一种情况,当视线与平面几乎垂直时,也就是说偏移量会很小,所以采样不必那么精确,步长比例可以比较大;而当视角同平面之间的角度越小的时候,视差位移也就越大,这个时候如果采样率过小会出现失真的情况,所以目前的做法是根据视角同平面的角度进行一个线性插值计算,角度很大的时候,使用较小的采样率,加快计算速度,角度很大的时候,采用较大的采样率,保证图像不是真。
    xijie     图是拿手画的比较简陋,见谅,呵呵,好的,我们已经计算到两个步长之间了,在这里我们做一个二次计算来获取一个相对来说比较近似的坐标位置,我们可以知道两个步长所在的高度以及两点的实际高度,四个点和两条垂直线,正好组成一对相似三角形,我们可以看到,相交的这一点距离实际视线应该看到的点是非常相近的,除非表面会在一个步长内出现较大的抖动,这种情况Errrr….目前是忽略掉的,根据相似三角形底和高成比例,我们知道两个三角形的高的和以及他们的底,而且所有数值都是在假定的0-1区间内,所以不难求出相交点的相对坐标。
        可能这一块看的很让人模糊,我们代数进去算一下,可能会有助于理解,我们假设上图中两个三角形从左到右,从下到上四个底点的坐标分别是A(0.25,0.25),B(0.25,0.55),C(0.5,0.3),D(0.5,0.5)(横坐标从左至右,纵坐标从下到上均为0-1),和图中所示比例也差不多,另外我们知道两个三角形的高的和h1+h2就是一个步长,在本例中即为0.25,根据相似三角形,我们可以知道AB/(AB+CD)=h1/(h1+h2),代入数值计算,我们很容易能得出h1等于0.15,我们便可得出该点的横坐标应为最大偏移向量的(0.25+0.15)=0.4处。
        好了,到此为止,我们就正确的求出了
  • 相关阅读:
    mac下免费的动态截屏制图工具:kap
    ssh端口转发实现socket5代理上网
    Linux上查看node和node_modules所在位置
    elasticsearch索引和快照清理:es curator
    npm运行报错:Error: ENOSPC: System limit for number of file watchers reached
    第二章 : 微服务环境搭建
    第一章 :微服务的架构介绍发展
    超简单的 Docker部署 SpringBoot项目 步骤
    maven继承父工程统一版本号
    Maven史上最全的pom.xml详解
  • 原文地址:https://www.cnblogs.com/lancidie/p/2325225.html
Copyright © 2011-2022 走看看