Mir*_*pas 1 opengl graphics rasterizing
通常在计算机科学的时候我已经从一些a到b的间隔[a, b).在栅格化几何图元时这是真的吗?
例如,当我有开始于位置的线(0, 0)和结束于位置(0, 10)将所述线包含点(0, 10)使用平行投影时与1个GPU单元映射到屏幕上的1个像素?
编辑:相同条件下的相同问题,但纹理:
如果我有一个纹理2x2映射四从(0, 0)到(2, 2)使用(0, 0)到(1, 1)映射会是"像素完美",一个从纹理象素上的一个像素在屏幕上或将纹理缩放?如果间隔是[0, 2]四边形将是3x3并且纹理必须缩放...
LATER EDIT:这可能会有所帮助:http://msdn.microsoft.com/en-us/library/windows/desktop/bb219690%28v=vs.85%29.aspx
首先,这完全取决于所使用的特定光栅化框架(例如OpenGL,Direct3D,GDI,......),因此我将这个答案基于被标记的问题opengl.
这不是一个简单的问题,因为通常绘制的图元(或更确切地说是其片段)的实际窗口坐标不是整数而是浮点或固定点坐标,这是在一堆(可能是不精确的)变换之后产生的(并非所有可以使用着色器自定义标识,尤其是从标准化设备坐标到窗口坐标的固定功能视口转换.因此,即使您将转换管道配置为直接在窗口空间中指定顶点坐标,也不要指望在所有情况下,生成的片段的窗口坐标都是完美的整数.如果需要,请查看此问题及其答案,以获得有关OpenGL转换管道的更多见解.
然后它取决于原始类型.对于多边形(三角形/四边形),如果片段的中心位于由多边形顶点的窗口坐标定义的多边形边界内,则光栅化器会检查每个片段.因此,如果我们有一个矩形(当然,两个三角形,但我们只是把它作为矩形)跨越了从窗口坐标(0,0)到(2,2),它会覆盖一个2x2的区域,因为只有片段(0,0)(与中心坐标(0.5,0.5))和(1,1)(与中心坐标(1.5,1.5)),和它们的组合与矩形有关.
对于线条来说,使用所谓的"钻石退出规则"会有点复杂.我不会在这里详细讨论,但对于水平或垂直线,这实质上意味着最后一个像素也是独占的.但实际上这也意味着整数窗口坐标是最难用于线的,因为由于转换管道中的舍入问题,很难确定这样的片段属于哪个像素,因为线的"判定阈值"是整数片段边界,而不是多边形的中心.
但是在考虑纹理时,会出现另一个问题,即插值.虽然来自(0,0)to 的四边形(2,2)将覆盖2x2像素区域,但是变化的值(在基元上插入的顶点属性,如颜色或纹理坐标)是从实际窗口坐标内插的.因此,像素(0,0)(与具有中心坐标的片段相对应(0.5,0.5))将不具有左下四极顶点的精确值,而是内部插入片段大小的一半(并且同样针对其他角落)的值.
那么重要的是OpenGL如何过滤纹理.当使用线性滤波时,纹素中心(即(i+0.5)/size)的纹理坐标返回精确的纹理颜色,纹理大小(即i/size)的整数除数将导致相邻纹素颜色之间的中间混合.并且当使用最近邻点采样时(建议在尝试像素或纹素精确度时),浮点纹理坐标向下舍入(落地操作),因此决定颜色是否为"判定阈值"来自一个纹素或其邻居的纹素边界(因此纹理大小的整数除数作为纹理坐标).因此,在纹素中心进行采样既可以使用线性滤波(在使用像素精确时也是不可取的),也可以使用最近的滤波,因为这样可以减少由于不精确和舍入误差而从一个纹素"翻转"到另一个纹素的可能性.纹理坐标插值.
那么让我们来看看你的具体例子吧.我们有一个带坐标的四边形
(0,2) - (2,2)
| |
(0,0) - (2,0)
Run Code Online (Sandbox Code Playgroud)
和纹理坐标
(0,1) - (1,1)
| |
(0,0) - (1,0)
Run Code Online (Sandbox Code Playgroud)
因此,如果已经在窗口/视口空间中给出了这些位置,则会产生具有中心的片段
(0.5,1.5) (1.5,1.5)
(0.5,0.5) (1.5,0.5)
Run Code Online (Sandbox Code Playgroud)
覆盖,代表2x2- [0,1]像素的正方形.插值后这些片段的纹理坐标将是
(0.25,0.75) (0.75,0.75)
(0.25,0.25) (0.75,0.25)
Run Code Online (Sandbox Code Playgroud)
对于2x2纹理,那些确实位于纹素中心.所以一切都很顺利.可能存在舍入和精度误差导致例如坐标1.999或texCoords 0.255,但这仍然不是问题,因为我们远离我们将"捕捉"到相邻像素或纹素的点(假设我们使用最近的过滤,但即使使用线性过滤,您通常也不会注意到与确切纹理颜色的差异).
虽然对于行例如,它是很难说的,因为精度,舍入和实施问题,这是否是从任一(0,0)对(0,9)或(-1,0)至(-1,9)(因此剪裁掉),甚至扭曲,你应该宁愿使用(0.5,0.5)和(0.5,10.5),这肯定会导致在从线(0,0)到(0,9).
总而言之,OpenGL并不是真正用于完全像素精确的操作,但可以通过一些小心实现.但要获得最佳效果,首先应配置转换以直接在窗口坐标中指定顶点位置,例如
glViewport(0, 0, width, height);
glOrtho(0, width, 0, height, -1, 1); //or something similar when using shaders
Run Code Online (Sandbox Code Playgroud)
然后对于多边形,使用整数位置和纹理大小的整数除数作为纹理坐标(并使用GL_NEAREST过滤).但对于线条使用半像素位置(即i+0.5)和纹素中心作为纹理坐标(即(i+0.5)/size).这应该为您提供基元的像素和纹素精确光栅化以及问题中描述的半开区间.但请记住,在这种情况下,栅格化多边形的锥形像素与其顶点角不匹配(向内移动半个像素).对于这种纹理很好地发挥出来与过滤规则,但对于其他属性,如颜色,这意味着一个矩形的左下像素不会有完全相同(是什么"恰好"在这有限的精度方面呢?)颜色左下顶点 但是对于线条,它们确实会匹配(尽可能).
| 归档时间: |
|
| 查看次数: |
772 次 |
| 最近记录: |