How to rasterize OpenGL triangle on half-integer pixels centers

拜拜、爱过 提交于 2020-04-10 09:08:51

问题


OpenGL pixels/fragments are conceptually 1x1 squares centered on half-integer pixels. The OpenGL 4.5 specification states:

A fragment is located by its lower left corner, which lies on integer grid coordinates. Rasterization operations also refer to a fragment’s center, which is offset by (1/2,1/2) from its lower left corner (and so lies on half-integer coordinates).

Rasterizers typically assume that pixel centers lie on the integer grid. Since I am attempting to implement a correct OpenGL triangle fill I want to know if the following procedures seems sound.

Let's take the simple case of a triangle with clip coordinates (-1,-1), (+1,-1), (0,+1) as shown on the left of the figure below (assume orthographic projection and z=0). Assume we have a (small 5x5 frame buffer) that we map our triangle to via glViewport(0,0,5,5) as shown on the right yielding the triangle in device coordinates with vertices (0,0), (5,0), (2.5,5).

pixels centered at half integers

As you can see, the 13 fragments (shaded pixels in image) with centers inside the triangle should be generated by the rasterizer. Note that the fragment centers are on half-integer coordinates. To implement the OpenGL spec, this is what the result needs to be.

A scan-line polygon fill would determine the x-spans where the scan lines intersect the triangle, but the scan lines are at half-integer y-values as shown in the following figure:

triangle fill OpenGL

A hardware/firmware rasterizer will assume the pixel centers are on the integer grid since this is the most efficient way to perform the fill. In the figure below I have shifted the devices coordinates of the triangle by (-0.5, -0.5) to place the centers on the integer grid:

enter image description here

Note that the pixels centers are now indeed on the integer grid. This rasterizer would simply add back (0.5,0.5) to each fragment center before being passed to the fragment shader. At least that is my plan.

Handling texture coordinates seems to be straight-forward. Imagine the I assigned texture coordinates (0,0), (1,0), (0.5,1) as shown below. The image on the left is using half-integer pixel-centers (the OpenGL way) and the image on the right is using integer pixel centers (the hardware way). The texture coordinates (any attached fragment attributes for that matter) end up having the same values either way -- i.e., nothing special needs to be done.

enter image description here

So does my approach seem correct?

  • Add (-0.5,-0.5) to each fragment coordinate,
  • use the hardware efficient fill,
  • add (0.5, 0.5) back in when generating fragment centers, and
  • don't sweat the other fragment attributes (they just work out).

来源:https://stackoverflow.com/questions/25457323/how-to-rasterize-opengl-triangle-on-half-integer-pixels-centers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!