Parallax Mapping

本文介绍了视差映射(Parallax Mapping)技术的基本原理及其应用。通过对比普通纹理映射,视差映射能够为平坦表面带来更真实的凹凸视觉效果。文章详细解释了视差映射所需的数据及计算过程,并探讨了该技术在不同角度下的适用性和局限性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

请勿转载.

clayman
Blog:
http://blog.youkuaiyun.com/soilwork
clayman_joe@yahoo.com.cn  

  

   作为实现bump map的技术之一,Parallax Mapping(视差映射)的目的同样也是让平坦表面实现凹凸效果。和Normal Mapping相比,Parallax Mapping能实现更加真实和强烈的凹凸感。

 

Parallax Mapping的思想:

       对真正高度起伏不同的凹凸表面来说,当观察它时会出现视差效果,但用平坦面表来模拟这种凹凸效果时,这种视差效果就消失了。上图中,点A对应的像素元为Ta,点B对应的为Tb。假设我们从上图所示的eye位置观察表明,对普通的纹理映射来说,应为观察矢量穿过了像素元Ta,所以我们应该看到A点。可是,观察矢量同样穿过了真实表面的B点。在实际生活中,我们观察的结果应该是看到点B,也就是看到像素元Tb。因此,对平坦表明来说,为了正确的显示点B,我们必须对Ta处的纹理坐标进行偏移,使它等于Tb。如果我们对多边形中的每个像素都进行这样的计算,视差效果也就出现了。

 

需要的数据:

       除了渲染表面所需的纹理,法线等贴图之外,为了计算像素的纹理坐标偏移值,还需要表面的高度图。当然,还需要从每个象素指向观察点的矢量。由于最终的结果是用来修改纹理坐标,所以所有的计算都在切线空间下计算。这里,需要把世界坐标下的观察矢量变换到切空间下,因此对每个顶点来说都要一个切空间坐标变换矩阵。

 

算法:

       在一般的纹理映射中,每个顶点都包含一对纹理坐标。在parallax mapping中,我们将用纹理坐标对高度图进行查找,根据所得结果对自身进行修改,最后再进行普通的纹理查找。如上图所示,纹理坐标偏移值等于点A到观察矢量的距离offset。由于从点A到观察矢量的射线和观察矢量的交点不一定在真正的几何体凹凸表面,所以parallax mapping上只是一种近似实现视差的方法。当然,可以使用其它方法获得更精确的偏移值,但这通常需要许多额外的计算,实际上在大多数情况下,这种近似已经足够好了。为了计算偏移,先要对切空间下的观察矢量进行标准化(normalized)。在切空间下,xy轴都位于切平面上V{x,y}z轴于切平面正交V{z}。接下来需要对高度图中的值进行缩放和偏移。高度图中的值在[01]之间,一般来说,需要把这个值映射到一个合适的范围内。比如对边长为 2m 的砖墙来说,假设表面水泥的厚度为 0.02m ,那么相应的缩放值应该为 0.02 / 2 = 0.01。此外,偏移值为0,那么水泥看起来是凸起的,如果为-0.01,则看起来是凹陷的。用以下公式来计算高度:

Hsb = h * s+ b

       最终,修改之后的纹理坐标就为:

Tb = Ta + V{x,y} * Hsb/ V{z}

      

    上面的公式虽然看起来是很合理的,但却有一些重要缺陷。当观察矢量和平面间的角度趋近于0时,Vz也趋近于0,结果将导致坐标偏移变的无限大,让parallax mapping方法崩溃。为了避免这种效果,只需要丢弃公式中的Vz项就可以了。当然,这同样会在精度上带来一些损失,不过实际情况下,一般不容易察觉出这些效果。

Tb = Ta + (V{x,y} * Hsb)

 
<think>我们正在讨论的是视差遮蔽映射(ParallaxOcclusionMapping,简称POM)代码及其用途。根据引用资料,POM是一种用于增强表面细节的技术,尤其在实时渲染中。它通过考虑高度图(heightmap)和视线的角度,模拟表面的凹凸效果,并且能够处理自阴影和遮挡问题。下面我们将分步骤解释POM代码的含义和作用。</think> ### POM(视差遮蔽映射)代码的含义与用途解析 #### 📌 **POM代码的含义** POM(Parallax Occlusion Mapping)代码是通过GLSL/HLSL编写的着色器程序,其核心逻辑为: ```glsl // 核心伪代码逻辑 for (int i = 0; i < numLayers; i++) { float currentDepth = layerDepth * i; vec2 offset = viewDir.xy * (currentDepth * heightScale); // 视差偏移计算 vec2 sampleCoord = texCoord - offset; // 采样坐标修正 float sampledHeight = texture(heightMap, sampleCoord).r; if (sampledHeight < currentDepth) { // 深度检测 // 进行光线步进插值计算最终遮挡位置 vec2 prevOffset = ... // 上一层的偏移 float delta = ... // 插值权重 finalCoord = mix(sampleCoord, prevSampleCoord, delta); break; } } ``` **关键元素**: - **高度图**:存储表面凹凸数据的灰度纹理(通常用.r通道读取) - **分层采样**:将视线方向分解为多层进行深度检测 - **光线步进算法**:逐层比较当前深度与采样高度值 - **线性插值**:在检测到遮挡时计算精确的遮挡边界位置 - **法线修正**:根据最终坐标重新计算表面法线(引用自[^4]) #### 🎯 **在图形编程中的作用** 1. **细节增强**: - 用**2D纹理模拟3D几何细节**(如砖墙缝隙、岩石凹凸),避免建模高精度网格(对比效果见引用[^3]图6.41) - 在**低多边形表面**实现接近雕刻模型的视觉效果 2. **动态交互优化**: - 实时计算**视角相关的自阴影和遮蔽**(引用[^1]) - 处理**复杂光线交互**:当视角倾斜时自动增强凹凸感(效果对比见引用[^2]) 3. **性能优势**: - 相比传统浮雕映射(Relief Mapping)**节省90%+的GPU负载**(引用[^3]) - 解决法线贴图(Bump Mapping)的**轮廓失真问题**(引用[^3]) 4. **真实感提升**: - 与**其他光照组件无缝集成**: ```glsl vec3 normal = getPOMAdjustedNormal(); // POM修正法线 float diffuse = dot(normal, lightDir); // 漫反射计算(引用[^4]) vec3 specular = pow(max(0, dot(halfVec, normal)), 128.0); // 高光计算 ``` #### 💻 **典型应用场景** - **游戏地表渲染**:沙砾/草地等高频细节表面(Unity/Unreal引擎集成方案见引用[^4]) - **建筑材质**:砖墙/大理石等需表现深度纹理的物体 - **虚拟现实**:对视角变化敏感的沉浸式场景 - **旧硬件优化**:在移动端实现次表面散射效果 > 示例:在Unity中启用POM只需在Shader中添加: > ```glsl > #pragma shader_feature _PARALLAX_OCCLUSION > sampler2D _HeightMap; > float _HeightScale; // 控制凹凸强度 > ```
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值