透视校正插值

在投影变换视口变换后,需要对投影到屏幕上的平面三角形顶点属性进行线性插值,例如颜色,纹理,深度等。但对于投影前在3D空间的三角形来说,这个插值并不是线性的。下面来推导一下这个插值。

假设屏幕空间的三角形的三个顶点分别为\(v_0,v_1,v_2\),\(v_p\)是位于三角形一边上的点\(v_0 + t(v_1 - v_0)\)。

那么有:
\[
x_p = x_0 + t(x_1 - x_0)
\]
其中,$ 0 \leq t \leq 1$。对于投影前的三角形,根据投影变换则有:
\[
\dfrac{x'}{x} = \dfrac{z'}{d}
\]
其中,\(x',z'\)为投影前三角形的坐标,\(d\)为到投影平面的距离。代入可得:
\[
\dfrac{x'_p}{z'_p} = \dfrac{x'_0}{z'_0} + t(\dfrac{x'_1}{z'_1} - \dfrac{x'_0}{z'_0})
\]
另外,我们已知\(v'_0,v'_1,v'_p\)三点共线,假设直线方程为\(ax'+bz'=c\),代入化简可得到:
\[
\dfrac{1}{z'_p} = \dfrac{1}{z'_0} + t(\dfrac{1}{z'_1} - \dfrac{1}{z'_0})
\]
可见,对于投影前在3D空间的三角形来说,\(z\)的倒数成线性插值。这样,我们就可以根据屏幕空间三角形的顶点深度,插值计算出三角形内任意点的深度值。

同样地,对于其他属性\(m'\)例如颜色纹理等,它们都关于深度\(z'\)成线性关系,即都有\(am'+bz'=c\)。等式两边都除以\(cz'\)得到:
\[
\dfrac{am'}{cz'} + \dfrac{b}{c} = \dfrac{1}{z'}
\]
根据之前求得的结果,有:
\[
\dfrac{am'_p}{cz'_p} + \dfrac{b}{c} = \dfrac{am'_0}{cz'_0} + \dfrac{b}{c} + t(\dfrac{am'_1}{cz'_1} - \dfrac{am'_0}{cz'_0})
\]
化简得到:
\[
\dfrac{m'_p}{z'_p} = \dfrac{m'_0}{z'_0} + t(\dfrac{m'_1}{z'_1} - \dfrac{m'_0}{z'_0})
\]
可见,对于投影前在3D空间的三角形来说,其他属性乘以\(z\)的倒数成线性插值。这样,我们就可以根据屏幕空间三角形的顶点属性,插值计算出三角形内任意点的属性值。

原文地址:https://www.cnblogs.com/back-to-the-past/p/12274314.html

时间: 2024-10-21 11:41:21

透视校正插值的相关文章

透视校正插值(Perspective-Correct Interpolation)

在渲染器光栅化每个三角形的过程中,需要对根据顶点属性对三角形进行扫描线插值.此时由于投影面上顶点的2D坐标与顶点属性不成线性关系,因此是不能简单地使用线性插值来计算顶点属性的. 此时应当利用透视校正插值(Perspective-Correct Interpolation)来计算. 设3D空间中存在一条线段,它的两个端点为A和B,3D坐标分别为(x1,y1,z1)和(x2,y2,z2).这两点投影到camera坐标系投影面的两点为a(p1,q1).b(p2,q2).那么: 设该线段之间存在一个三维

Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础

摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐标系下进行的. 一个二维的笛卡尔坐标系包含了两个部分的信息: 一个特殊的位置,即原点,它是整个坐标系的中心. 两条过原点的互相垂直的矢量,即X轴和Y轴.这些坐标轴也被称为是该坐标的矢量. OpenGL 和 DirectX 使用了不同的二维笛卡尔坐标系.如下图所示: 2)三维笛卡尔坐标系 在三维笛卡尔坐标系中,

图形渲染管线简介

The Graphics Rendering Pipeline 渲染管线,这章主要讲光栅化渲染管线. 毕业前实习时,也实现过一个简单的软光栅化渲染管线,再复习一下. 在计算机图形学领域,shading指基于表面相对灯光的角度.距灯光的距离.相对于相机的角度和材质的属性等来修改物体/表面/多边形的颜色,进而创造一个具有真实感效果的过程. In computer graphics, shading refers to the process of altering the color of an o

透视纹理引发的对于插值的思考

插值还没有系统的学过,最近在实现BlackWalnut3D的纹理映射时,才慢慢发现3D中的插值和我们数学上的插值还是有点不同的. 个人认为,插值可以和向量,矩阵一起称为计算机图形学中最最基本的数学基础. 在构造物体时,可以只设置几个参考点,使用插值完成贝塞尔曲线的逼近.在进行裁剪时,为了获得规范的,可以方便进行裁剪的裁剪立方体CVV,将透视和插值融合实现了透视矩阵,同时,在具体的裁剪过程中,使用插值获得各种裁剪后的坐标.在光栅化的阶段,使用插值完成将一个平面离散到屏幕像素上,并且利用插值完成正确

测试不同格式下depth buffer的精度

这篇文章主要是参考MJP的"Attack of The Depth Buffer",测试不同格式下depth buffer的精度. 测试的depth buffer包含两类: 一是非线性的depth buffer,存储着perspective z(也就是最常用的,透视投影后归一化的z/w的buffer),二是线性的depth buffer,存储着view space z(这里的线性指的是在view space 中是否线性).测试的格式包括16位浮点数,32位浮点数,16位定点数,还有最常

OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)和varying,uniform,attribute修饰范围

OpenGL ES着色器语言之变量和数据类型(一)(官方文档第四章)   所有变量和函数在使用前必须声明.变量和函数名是标识符. 没有默认类型,所有变量和函数声明必须包含一个声明类型以及可选的修饰符.变量在声明的时候首先要标明类型,后边可以跟多个变量,之间用逗号隔开.很多情况下,变量在声明的时候可以使用等号“=”进行初始化. 用户定义类型可以使用struct,在结构体中所有变量类型都必须是OpenGL ES着色器语言定义的关键字.OpenGL ES着色语言是类型安全的,因此不支持隐式类型转换.

视频滤镜参数

在配置编译FFmpeg时可以通过--disable-filters来禁止所有滤镜的编译.也可以配置编译脚本来输出所有包含进编译的滤镜信息.下面是当前可用的视频滤镜介绍. alphaextract 把输入视频作为灰度视频来提取透明通道,它通常和alphamerge滤镜联用. alphamerge 通过添加或者替换透明通道,让主要视频与另外一路视频混合.这里主要是使用alphaextract来让不支持透明通道的视频成为允许传输或存储帧透明的帧序列 例如:为了重建完整的帧,让一个普通的YUV编码视频和

关于GLSL中的限定符的一些记录

glsl是什么就不多说了.这里只介绍一下glsl中一些限定符. glsl中包含两类具有定义性质的符号,一类是和c++中定义变量的一样的符号,用来说明存放数据的类型,如float,int,bool.还有一类是的功能类似于c++中的private,protect,public,是用来说明变量被访问的方式,glsl中常用的限定符包含三个,uniform,attribute 以及 varying,称为限定符(还有一个const,就不多说了). uniform限定了该变量是随着图元变化而变化的,也就是说在

GLSL部分小汇总

一.类型限定符: const, in, out, uniform 1.in: 指定变量为着色器阶段的一个输入,输入可能是顶点属性(用于顶点着色器)或插值变量(用于片段着色器). 片段着色器可进一步限制其输入值,但要和in组合使用才有效: centroid: 在打开多点采样时,强迫一个片段输入变量的采样位于图元像素的覆盖区域内. smooth: 以透视校正的方式插值片段输入变量. flat: 不对片段输入插值. noperspective: 线性插值片段变量. 2.out: 指定变量为着色器阶段的