- 主题:外行问一个关于openGL和计算机图形学的一个的问题
看了点openGL的文档,发现这个问题:
似乎四边形和多边形最后都是被GPU拆为三角形处理显示的
那么实际上GPU是无法真正知道三个以上的点是否真正的共面吧?
————————————————————————————————————————————————
GPU不需要知道3个以上的点是否共面。
之所以选三角形的原因是:
(1)三角形是最基本的多边形,并且任何其他的多边形都可以拆分为三角形。
(2)三个点可以保证在一个平面,如果是四边形四个点就不能保证。
(3)它可以很好地用叉积判断一个点是不是在三角形内部(三角形的内外定义特别清晰)-这个在光栅化时特别重要
如下说法是否正确?
比如说有四个点的三维坐标,GPU如果想验证四个点是否共面,就要增加验证步骤消耗细算资源,而且计算机储存的坐标数据类型(比如为float)精度有限,也会很难真正验证成功。所以计算机就舍弃这个验证共面的步骤,一律把这四个点作为两个三角形来显示,不管其是否真的是一个四点共面的四边形
——————————————————————————————————————————————————————————————————————————
同上段,不存在『想验证四个点是否共面』这件事
不管共不共面,渲染任何形状,为获得颜色,需要的是法线方向和深度。
如果显卡显示出来的都是一个个三角形,那么游戏里的视频贴图是怎么实现的呢?视频都是长方形的,是怎么贴合到显存里组成一个长方形的两个三角形上的呢?
——————————————————————————————————————————————————————————————————
这个问题过于业余了,可以了解一下光栅化和基础图形管线。
最终表现的形状和尺寸,和你的视口有关,即这个视口可以是长方形也可以是圆形。
视口就相当于你眼睛前面的罩了一张有洞的纸,这个洞的形状决定你看到的长方形还是圆形。
其他的你问的驴唇不对马嘴,我也不知道怎么回答。
--
修改:sjtuDNA FROM 124.127.210.*
FROM 124.127.210.*
程序的目的如果是渲染,那么就不存在需要判断是否共面的逻辑。
共不共面,2个三角形都需要走图形管线进行渲染。如果共面会造成渲染结果近似,2个三角形分别渲染的结果也是近似的。
换一种说法,在浮点数领域里面,没有等于的说法,判断两个浮点数所谓『相等』需要用:abs(A-B)< Epsilon
换个方法理解,在计算机的眼里,没有绝对相等的2个浮点数,也就没有所谓『共面』的2个三角形。
程序的目的如果是判断2个三角形是否共面,那是另外一种范畴。
想深入了解,建议看完基础的图形渲染管线的原理,再来讨论。
目前问的问题还是过于外行,图形学还是有技术门槛的,不是问几句就可以了解的。
【 在 seeeU 的大作中提到: 】
: 谢谢
: 那程序中该如何判断n个点(n>3)是否是共面的呢?GPU编程实现不了的话,是不是得在CPU程序中判断这n个点的坐标?比如对任意三个向量做混合积,看行列式是否为0?
: 还有如果n个点的“多边形”不共面?送到GPU里,还是会显示出来吧?只不过是被拆成一个个三角形,还是不共面也会按照实际坐标把这个所谓的“多边形”显示出来?
: ...................
--
FROM 124.127.210.*
说了八百遍了,程序不需要判断n点共面,程序不需要判断n点共面,程序不需要判断n点共面。
只是你臆想的程序需要判断n点共面,实际渲染管线不需要判断n点共面。
blender和3dmax可以创造同一个平面上的多边形,他们只是生产模型。
obj的格式也好,任何格式送入渲染管线的都是三角形,如果不是三角形,要做triangulation。
渲染不关心在不在一个平面上,只按照实际的坐标进行绘制。
【 在 seeeU 的大作中提到: 】
: 就是说程序上如果要实际上判断n点共面,最后也是要设定一个近似的阈值吗?
: 在blender和3dmax里是可以创造同一个平面上的多边形的吧?它们是怎么处理的呢?
: 还有obj文件格式里,定义一个面的时候需要包括其顶点,是可以包括n个点(n大于3)的,那如果这n个点如果不在一个平面上,还会被按照实际坐标渲染出来吗?
: ...................
--
FROM 124.127.210.*
4点共面可以考虑:
1. 可以拆成有共同边的2个三角形,2个三角形的法向量的夹角小于epsilon。(一般模型输入的时候都带法向量,所以不用计算)。复杂度O(n)
2. W点到ABC面的距离,小于epsilon
【 在 seeeU 的大作中提到: 】
: 好吧,我明白了,那我不问渲染管线和GPU,我只问在cpu里或者非shader程序里如何判断n点共面呢?
--
修改:sjtuDNA FROM 124.127.210.*
FROM 124.127.210.*
动图的序列帧可以作为N个纹理对象,通过timer来进行触发这个纹理对象id的变换。
【 在 seeeU 的大作中提到: 】
: “纹理中的数据可以是静态图片、动图、视频、cpu生成的、gpu之前渲染得到的等等;其中的数据也可以不是颜色值,而是4维以内的整数、普通浮点数等”
: 动图和视频是怎么作为纹理的呢?我看了一遍一个openGL入门教程,没看到有提过这方面的内容。具体是如何实现的呢?谢谢
:
--
FROM 124.127.210.*
光栅化过程的原理你没有搞清楚。
为什么GPU必须要处理三角形面片,而不是四边形面片。
最重要的原因就是:可以通过叉积判断一个点是不是在三角形内部
在光栅化时,会遍历所有像素,这个像素在哪个三角形内,根据这个三角形的颜色属性等,通过brdf模型或者其他的模型来给这个像素赋值。在fragment shader里面,可以更灵活的编程处理这个赋值过程。
所以你说的什么四边形,什么共面,根本就不可能存在。
【 在 seeeU 的大作中提到: 】
: 谢谢
: 但是存储的位置坐标都是浮点值,实际在程序里算出来两个向量都是float格式,数值是近似出来的,可能在数学上不一定完全平行吧?可能会差一点点。会有这种情况吗?这时候如何处理呢,只要是二者叉积结果小于一定的阈值就判定是平行的?前面 @sjtuDNA 也这样说过。
: 那么问题又来了:如果是要通过一个小的阈值来判断的话,那程序实际是无法区分两个三角形是真正完全共面的,还是说二者间有一个非常非常小的角度,因为两种情况下都会使得两个法向量的叉乘结果小于这个很小的阈值。那么是否能说实际工程角度而言,其实是无法真正判断数学上的共面是否确实为真(除非这n个点的x、y、z三分量中的某一个分量数值完全相等)。
: ...................
--
FROM 124.127.210.*
OpenGL API虽然接受Polygon,但是依然会把他处理成Triangle再继续操作顶点。
【 在 DoorWay 的大作中提到: 】
: 1 是,用阈值。根据模型精度定的阈值,数值精度一般用很多位;模型精度10分之1毫米。
: 2 数学真正的共面就用数学的方法解出来。程序的精度就是小于阈值,就真正的共面。
: 3 程序就把4个点视为共面了,然后给他们组成的“四边形”明明一个名称来标记这个面,那么这个面的法向量怎么取?—— 这里指的是哪个程序?程序没有这么傻,如果有也是程序员傻(笑)。一般图形程序定义一个面,就是选一个点和一个法向就行了。叫它CPlane。内部计算时,就是平面公式,Ax + By +Cz =d。判断多点共面,取三点构造CPlane,判断其他点到平面的距离就可以。
: ...................
--
FROM 124.127.210.*
举个例子:我用4个点组成两个毗邻的三角形,二者共享一条边,两个三角形的法向量有个非常非常小的角度是0.001度,小于程序里的阈值0.01度,程序就把4个点视为共面了,然后给他们组成的“四边形”明明一个名称来标记这个面,那么这个面的法向量怎么取?两个法向量的数学平均?程序对于它所认定的面的操作也只是把它们用同一个名称(这个面的名称)来标记,取消各个点之间连线在这个面内部的显示吧(使其看起来像一个面),然后就是针对这组点(或者这个面)做平移变换缩放组操作吧?对面的本质操作就是对一组毗邻三角形及其点和线的组操作吧,和其是否真的共面没关系(而且本来程序就无法真正的在数学上判断共面)?
————————————————————————————————————————————————————————————
你举的例子,是你独创的渲染管线,不是目前的渲染管线的做法。
渲染管线从来不会,也不需要判断2个三角形是否共面。
2个三角形,有相邻边,法相方向接近,那么在最后渲染的结果上就是『一致』的,不需要判断他是否共面。
我不明白你天天纠结这个共面,干嘛。很难以理解吗?
2包中华,画出来就是2包中华,你管他是不是放在一个桌子上干嘛?
--
FROM 124.127.210.*
你在建模软件的一个平面内,画了个n边形,建模软件会保存相关的坐标。
为什么你还要再判断他的坐标是共面的?
【 在 seeeU 的大作中提到: 】
: 在非GPU非shader程序里呢?
: 建模软件在一个平面里画了个n边形,这不就是多边形吗?这时候就有判断共面的要求了
: 显卡和渲染管线里只有三角形这点我已经了解了,但是在CPU程序里有时候还是要处理n点共面的问题吧?
: ...................
--
FROM 124.127.210.*
视频经过解码之后,也是一个序列帧的纹理啊,一帧一帧的图片。
【 在 seeeU 的大作中提到: 】
: 谢谢,timer触发纹理贴图的变换我也在教程里看到过,没想到真是这样
: 那视频呢?教程里没有这个。我猜是把视频的每一帧都乘以一个变换矩阵,覆盖到目标四边形的前方?
--
FROM 124.127.210.*