python 深度 视差 计算_1,Learn about Parallax(视差贴图)

本文详细介绍了如何利用GLSL和Python进行视差计算,探讨了视差贴图的基本原理和不同技术,包括基础视差、偏移限制视差、陡峭视差贴图等。通过比较法线贴图,阐述了视差贴图如何在2D表面上创造出3D细节的错觉。同时,文章提供了基础视差贴图和陡峭视差贴图的GLSL shader实现,帮助理解其工作原理。
摘要由CSDN通过智能技术生成

纯手码字翻译大佬教程. 因为parallax算法和RayMarching算法相似(都为步进采样),就放在一个专栏里了,自己理解的地方有注明.

原文链接 :https://github.com/UPBGE/upbge/issues/1009

这个教程介绍了怎么用GLSL使用不同的视差贴图技术(也可以在DX中运用)。下面要介绍的技术有:视差贴图,偏移限制视差贴图,陡峭视差贴图,浮雕视差贴图以及视差映射贴图(POM),同样这篇文章介绍了怎么在视差中加自投影。下面的图片描绘了在简单灯光下视差贴图和法线贴图的差别:

c691a77836ae5252de37433fa0cb8d61.png

基础视差贴图

在计算机图形学中视差贴图是法线贴图的进阶版,也就是不仅仅改变光的行为还在平面中制造了3D细节的假象.并没有额外生成模型.在之前展示的视差和法线的对比图中.您可能会认为视差移动了原来的模型,实际上是移动了UV后采样了diffuse贴图和normal贴图.

使用视差贴图需要一张高度图,高度图储存了每个像素表面的高度信息。可以描述成距离表面的深度,在这种情况里必须反转高度图. 这个教程里把高度图的信息视作深度信息.黑色(0)代表了没有孔,白色(1)代表了孔的最大深度.

在下面的视差贴图范例中我们使用三张贴图:heightMap,diffuseMap还有normalMap,通常normalMap是由heightMap生成的.在我们的范例中高度图作为深度图使用.所以在生成normalMap之前.您必须反转高度图.您可以把normalMap和heightMap合并成一张图(heightMap作为Alpha通道),但是本教程为了方便一点使用了三张不同的贴图.下面是视差的贴图范例:

657f9f6cc42a71e7758902a1b7eab1d4.png

视差贴图技术的主要任务是通过移动UV修改贴图来让平面看着像3D. 这个效果会在片段着色器中显示的所有像素进行计算. 如下图.Level0代表没有坑洞.Level1代表最深的孔. 模型实际上没有变而且一直在Level0处.曲线代表的是储存在高度图中的值.当下的像素坐落在黄色方形处.这个像素对应的UV(TextureCoordinates)是T0.V是从摄像机到该像素的向量.如果按照T0采样高度图的话能得到值H(T0) = 0.55.值不等于0。所以该像素并不在表面. 在像素之下有坑. 所以你必须延申V到由高度图定义曲面的交点.这个交点正在深度为H,UV位T1的位置,然后用T1去采样diffuseMap和normalMap.

因此所有视差算法的目标都是去计算摄像机向量V和高度图所定义表面的交点。

2d8007990652f60f6cca91beea58f405.png

视差贴图基础shader

视差贴图的计算必须在切线空间里(和法线一样).所以灯光(L)和摄像机(V)的向量必须转换到切线空间.然后用视差技术计算新的UV坐标,然后您可以用这个新的UV坐标计算子投影以及采样这个像素的diffuseMap和normalMap.在这个例子中执行视差算法的函数是parallaxMapping() ,计算自投影的函数是parallaxSoftShadowMultiplier().光照模型用的是Blinn_Phong光照模型.法线方程是normalMappingLighting().下面的顶点和片段着色器可以当作是视差贴图算法的基本架构.顶点着色器变换了L,V到切线空间.片段着色器调用了视差算法函数,然后计算自投影最后计算光照&

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
视差是指相机左右两个摄像头拍摄同一场景时,由于视角不同而导致的像素位移差异。NCC(Normalized Cross Correlation)视差匹配是一种常用的计算视差的方法之一。下面是在Python中实现NCC视差匹配计算视差图的步骤: 1. 读取左右两个摄像头拍摄的图像。 2. 对图像进行预处理,包括去噪、灰度化、归一化等。 3. 定义一个窗口大小,遍历左图像的每个像素点,在右图像中搜索与该像素点最相似的像素点。相似度可以通过计算两个窗口的NCC系数来得到。 4. 根据计算出的相似度,确定该像素点的视差值。 5. 对所有像素点都进行相似度计算视差值确定,得到最终的视差图。 下面是一段Python代码示例,实现了NCC视差匹配计算视差图的功能: ```python import cv2 import numpy as np # 读取左右两张图像 imgL = cv2.imread('left.png', 0) imgR = cv2.imread('right.png', 0) # 图像预处理 imgL = cv2.GaussianBlur(imgL, (5, 5), 0) imgR = cv2.GaussianBlur(imgR, (5, 5), 0) imgL = cv2.normalize(imgL, None, 0, 255, cv2.NORM_MINMAX) imgR = cv2.normalize(imgR, None, 0, 255, cv2.NORM_MINMAX) # 定义窗口大小和搜索范围 winSize = 5 searchRange = 50 # 初始化视差图 disparity = np.zeros_like(imgL) # 遍历左图像的每个像素点 for i in range(winSize, imgL.shape[0] - winSize): for j in range(winSize, imgL.shape[1] - winSize): # 定义左图像窗口 leftWin = imgL[i - winSize:i + winSize + 1, j - winSize:j + winSize + 1] # 初始化最大相似度和视差值 maxCorr = -1 disp = 0 # 在右图像中搜索与左图像窗口最相似的窗口 for k in range(j - searchRange, j + searchRange): if k < winSize or k >= imgR.shape[1] - winSize: continue rightWin = imgR[i - winSize:i + winSize + 1, k - winSize:k + winSize + 1] corr = np.sum(leftWin * rightWin) / np.sqrt(np.sum(leftWin ** 2) * np.sum(rightWin ** 2)) if corr > maxCorr: maxCorr = corr disp = j - k # 将视差值保存到视差图中 disparity[i, j] = disp # 显示视差图 cv2.imshow('disparity', disparity) cv2.waitKey(0) cv2.destroyAllWindows() ``` 注意,此代码示例仅作为参考,实际应用中还需要根据具体情况进行调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值