透视矫正插值 Perspective-Correct Interpolation

> Perspective-Correct Interpolation 翻译仅供学习

(PDF) Perspective-Correct Interpolation (researchgate.net)

透视矫正插值 Perspective-Correct Interpolation#

3D渲染中,输入数据是一些primitive信息,包括顶点位置、颜色、纹理坐标等等。在光栅化阶段,primitive(一般为三角形)被转化成一系列的fragment(或者称为像素),这些fragment接下来要做ps操作,此时每个fragment都有位置、颜色、纹理坐标这些属性信息,这些属性信息通过顶点属性用插值方法得到的。

就是说在3D图形处理器绘制三角形时,每个像素处的属性信息(包括颜色、纹理坐标等)是对扫描线左右端点对应的顶点属性信息进行插值运算得到的。

1 介绍 INTRODUCTION

我们将推导出(并证明)一种在屏幕空间中通过线性插值实现透视校正插值的方法。在线性图形基元(例如线和多边形)的光栅化过程中,顶点属性的直接屏幕空间线性插值通常不会产生透视正确的结果。

在传统的光栅图形中,颜色、纹理坐标和法向量等属性通常与图形基元的顶点相关联[1,2]。在3D空间中,每个属性的值在每个图形基元之间线性变化。然而,在3D顶点通过透视投影投影到2D图像平面(或屏幕)之后,3D空间中属性值的这种线性变化不会转化为屏幕空间中类似的线性变化。因此,如果我们对屏幕空间中的这些属性值应用直接的线性插值,通常我们会在图像中得到错误的结果。

图1:屏幕空间(或图像平面)中属性值的直接线性插值并不总是产生透视正确的结果。

为便于说明,图1仅显示了投影到1D图像平面上的2D空间中的一条线,但可以将相同的参数应用于投影到2D图像平面上的3D线性几何基元。在图中,二维空间中线AB的顶点A和B分别投影到一维图像平面中的点a和b上。顶点处的属性值是强度值(intensity)。在A处,强度值为0.0,在B处,强度值为1.0。因此a和b处的强度值分别为0.0和1.0。假设c是a和b之间的图像平面中点。如果我们在图像平面(或屏幕空间)中对a和b处的强度值进行线性插值,则c处的强度值为0.5。然而,如果我们将点c“反投影”到直线AB上的点C上,我们可以看到C不一定是A和B之间的中点。由于强度值从A到B线性变化(在3D空间中),如果C不是A和B之间的中点,则C处的强度值不应为0.5。

尽管如此,仍然可以通过在屏幕空间中进行线性插值来获得透视正确的结果。这可以通过对属性的某些函数的值进行插值来完成,而不是直接对属性进行插值。然后每个插值结果由另一个函数(反函数)转换,以获得屏幕空间中所需点的最终属性值。您将看到这些函数使用了顶点的z值。

2 插值z INTERPOLATING z-VALUES

在进行透视投影以将图元的3D顶点投影到2D图像平面之前,许多图形渲染系统假设虚拟相机已经位于3D空间的原点,从-z或+z方向看。这定义了一个称为相机坐标系的坐标系。相机的固定观察方向也允许我们始终拥有垂直于z轴的图像平面,这显着简化了透视投影计算。不失一般性,我们将假设相机在+z方向上看,并且图像平面在相机前面的距离为d(见图2)。

许多光栅图形渲染系统使用z-buffer[1,2]来执行隐藏表面去除。这要求在将图元投影到屏幕上的每个像素上,必须知道图元上相应3D点的z坐标(z值)。然而,因为只有图元的顶点被实际投影,它们在屏幕空间中对应的2D图像点是屏幕空间中唯一知道z值的地方。为了更快地光栅化,我们希望使用顶点图像点的已知z值导出其他像素的z值。

z值可以被视为一个属性,其值在3D线性基元中呈线性变化。与我们在图1中看到的示例一样,屏幕空间中z值的直接线性插值并不总是产生透视正确的结果。但是,我们将在下文中看到,我们实际上可以对z值的倒数进行线性插值以获得正确的结果。

与图1类似,图2显示了2D相机坐标系中的一条线被投影到1D图像平面上。标题解释了我们将在公式推导中使用的符号。图中,s为图像平面内的插值参数,t为图元上的插值参数。

图2:虚拟相机在相机坐标系中的+z方向看。图像平面位于相机前方距离d处。A、B和C分别是属性值I1,I2It的图元上的点,它们在图像平面上的图像分别为a、b和c。s和t是用于线性插值的参数。

我们的目标是推导出公式以在屏幕空间中正确插入z值。相同的推导可以直接应用于投影到2D图像平面上的3D线性图元(primitive)的情况。

参考图2,由相似三角形,我们有

(1)X1Z1=u1dX1=u1Z1d

(2)X2Z2=u2dX2=u2Z2d

(3)XtZt=usdZt=dXtus

通过在图像平面(或屏幕空间)中进行线性插值,我们有

(4)us=u1+s(u2u1)

通过在相机坐标系中对图元进行线性插值,我们有

(5)Xt=X1+t(X2X1)

(6)Zt=Z1+t(Z2Z1)

将(4)和(5)代入(3),

(7)Zt=d(X1+t(X2X1))u1+s(u2u1)

将(1)和(2)代入(7),

(8)Zt=d(u1Z1d+t(u2Z2du1Z1d))u1+s(u2u1)=u1Z1+t(u2Z2u1Z1)u1+s(u2u1)

将(6)代入(8),

(9)Z1+t(Z2Z1)=u1Z1+t(u2Z2u1Z1)u1+s(u2u1)

可以简化为

(10)t=sZ1sZ1+(1s)Z2

将(10)代入(6),我们有

(11)Zt=Z1+sZ1sZ1+(1s)Z2(Z2Z1)

可以简化为

(12)Zt=11Z1+s(1Z21Z1)

等式(12)告诉我们,只需在1/Z11/Z2,之间进行线性插值,然后计算插值结果的倒数,就可以正确导出图像平面中点c处的z值。对于z缓冲区的,甚至不需要计算最终倒数,因为我们只需要在z值比较期间反转比较操作。

3 插值属性 INTERPOLATING ATTRIBUTE VALUES

在这里,我们要推导出公式以在屏幕空间中正确插入其他属性值。再次参考图2。通过在相机坐标系中跨图元线性插值属性值,我们得到

(13)It=I1+t(I2I1)

将(10)代入(13),我们有

(14)It=I1+sZ1sZ1+(1s)Z2(I2I1)

可以重新排列成

(15)It=(I1Z1+s(I2Z2I1Z1))/(1Z1+s(1Z21Z1))

从(12),我们可以看到(15)中的分母只是 1/Zi

所以,

(16)It=(I1Z1+s(I2Z2I1Z1))/1Zt

式(16)的意思是只要在I1/Z1I2/Z2之间进行线性插值,然后将插值结果除以1/Zt,就可以正确导出图像平面c点的属性值,它本身可以通过屏幕空间中的线性插值导出,如(12)所示。

参考文献 REFERENCES#

[1] James D. Foley, Andries van Dam, Steven K. Feiner and John F. Hughes. Computer Graphics: Principles and Practice, Second Edition. Addison-Wesley, 1990.

[2] Mason Woo, Jackie Neider, Tom Davis, Dave Shreiner (OpenGL Architecture Review Board). OpenGL Programming Guide, Third Edition: The Official Guide to Learning OpenGL, Version 1.2. Addison-Wesley, 1999.

相关参考#

透视校正插值 - 知乎 (zhihu.com)

3D数学-透视校正插值 - 简书 (jianshu.com)

透视校正插值(Perspective-Correct Interpolation) - 任程 - 博客园 (cnblogs.com)

计算机图形学六:正确使用重心坐标插值(透视矫正插值(Perspective-Correct Interpolation))和图形渲染管线总结_吃人的博客-CSDN博客_重心坐标插值

Microsoft Word - lowk_persp_interp_06.doc (nus.edu.sg)

【基础】透视校正插值(Perspective-Correct Interpolation)_MiaoMiaoM-的博客-CSDN博客

透视校正插值 | おたくのスタジオ (eclipseflower.github.io)

posted @   straywriter  阅读(1322)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩