Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 10 of 10

Thread: Unexpected GPU triangle rasterization output

Hybrid View

  1. #1
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    130

    Unexpected GPU triangle rasterization output

    Hi,

    I'm trying to render the geometry that is shown in the following screenshot (wireframe mode):

    Click image for larger version. 

Name:	test_output_1175_zoomin.jpg 
Views:	131 
Size:	3.0 KB 
ID:	1081

    This geometry is issued from dynamic tessellation, with fixed tessellation factors. As you can see, all vertices nicely join up, the geometry is "watertight".

    Now let's see what this geometry looks like when rendered with a specific camera.

    In filled triangles mode:

    Name:  test_output_1175_filled_cropped.png
Views: 196
Size:  201 Bytes

    In wireframe mode:

    Name:  test_output_1175_wireframe_cropped.png
Views: 196
Size:  306 Bytes

    Backface culling is disabled in both cases.

    What a surprise! The GPU rasterizes more fragments/pixels in wireframe mode! It doesn't join up everything together when in filled triangle mode. In other words, filled geometry != wireframe fragments + some more fragments. How come?!
    Is this expected? I don't see any bug on my side so far.
    I'm on nVidia GTS 450 hardware and 320.18 drivers.

    Thanks,
    Fred

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    Apr 2009
    Posts
    590
    It's important to remember what GL is supposed to do when it comes to triangle raserization:

    • For rasterizing a triangle, a pixel gets filled if the center of the pixel is within the interior of the triangle.
      For those pixels whose center is on the boundary of a triangle, the rasterizer has to work so that if two triangles share an edge, only one of those triangles gets rasterized.
    • For lines, the rasterizer draws a line of the thickness specified by glLineWidth between the two pixels that contain the two end points.



    Now if most of the triangles are sub-pixel in size, it is quite likely that lines will rasterize more.


    However, the picture given for the triangle rasterization is little worriesome. Indeed the actual mesh is connected, so its rasterization should be too. Do you have anti-aliasing enabled? That could explain why it is not connected.

  3. #3
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    130
    Quote Originally Posted by kRogue View Post
    However, the picture given for the triangle rasterization is little worriesome. Indeed the actual mesh is connected, so its rasterization should be too.
    This is what I am surprised with. And I do render every single fragment (gl_FragColor = vec4(1,0,0,1)).

    Quote Originally Posted by kRogue View Post
    Do you have anti-aliasing enabled? That could explain why it is not connected.
    I don't have antialiasing enabled.

  4. #4
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    130
    Quote Originally Posted by kRogue View Post
    It's important to remember what GL is supposed to do when it comes to triangle raserization:

    • For rasterizing a triangle, a pixel gets filled if the center of the pixel is within the interior of the triangle

    Does this mean most fragments don't actually get rendered in my situation?
    This rule makes sense but sounds a bit odd to me. Afterall, fragments at triangle endpoints usually do not lie in the triangle! So based on this rule, they should only rarely get rendered. That can't be true...
    Is there a way to render fragments if the fragment intersects the triangle, and not if the fragment's center lies in the triangle?

  5. #5
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    Quote Originally Posted by fred_em View Post
    [/LIST]
    Does this mean most fragments don't actually get rendered in my situation?
    When a group of triangles cover a fragment, the fragment's centre will lie within one of the triangles, and thus be rendered. OpenGL's rasterisation rules require that, in this situation, the fragment is rendered exactly once; otherwise blending wouldn't work correctly.

    Quote Originally Posted by fred_em View Post
    [/LIST]This rule makes sense but sounds a bit odd to me. Afterall, fragments at triangle endpoints usually do not lie in the triangle! So based on this rule, they should only rarely get rendered.
    "Rarely" is overstating it. At any interior vertex, the fragment will lie within one of the triangles. The probability of it lying within a specific triangle is inversely proportional to the number of triangles surrounding the vertex. For a vertex at a silhouette edge, as the mesh resolution increases the angle between edges tends to 180 degrees and the probability of the fragment containing that vertex being rendered tends to 1/2.

    Quote Originally Posted by fred_em View Post
    [/LIST]Is there a way to render fragments if the fragment intersects the triangle, and not if the fragment's center lies in the triangle?
    If multi-sampling is enabled, the fragment shader is run for each fragment which intersects the primitive. Thus, for fragments which intersect shared edges, the shader will be run multiple times. However, the result of each invocation will only affect the samples covered by the primitive being rendered; it cannot modify samples which lie outside of the primitive (if gl_SampleMask is assigned to, the value is AND-ed with the actual coverage mask).

    As for what your original problem is, it would help if you provided more detailed images. My first suspicion is that you're only generating half as many triangles as you should be. If for every shared edge you render exactly one of the triangles sharing that edge, that won't affect the wireframe result but will affect the filled result.

  6. #6
    Junior Member Regular Contributor
    Join Date
    Jul 2010
    Posts
    130
    Quote Originally Posted by GClements View Post
    Quote Originally Posted by fred_em
    Does this mean most fragments don't actually get rendered in my situation?
    When a group of triangles cover a fragment, the fragment's centre will lie within one of the triangles, and thus be rendered. OpenGL's rasterisation rules require that, in this situation, the fragment is rendered exactly once; otherwise blending wouldn't work correctly.
    Have a look at the following image:

    Click image for larger version. 

Name:	rasterization.jpg 
Views:	96 
Size:	9.7 KB 
ID:	1084

    Squares represent fragments (and associated screen pixels) that intersect a single triangle primitive (in red). Green squares are fragments which center does not lie in the triangle. Is the GPU supposed to raster both white and green fragments, or just green fragments? (I hope the answer is both, here).

    "Rarely" is overstating it. At any interior vertex, the fragment will lie within one of the triangles. The probability of it lying within a specific triangle is inversely proportional to the number of triangles surrounding the vertex. For a vertex at a silhouette edge, as the mesh resolution increases the angle between edges tends to 180 degrees and the probability of the fragment containing that vertex being rendered tends to 1/2.
    As for what your original problem is, it would help if you provided more detailed images. My first suspicion is that you're only generating half as many triangles as you should be. If for every shared edge you render exactly one of the triangles sharing that edge, that won't affect the wireframe result but will affect the filled result.
    The problem I have here is that my rasterization is non-continuous. It is not a problem of shared edges or vertices, or something having to do with interior vertices.
    My geometry is a series of 6 GL_PATCHES, they are perfectly connected, and the tessellation factors is 5x5 for each of them.

  7. #7
    Member Regular Contributor
    Join Date
    Jun 2013
    Posts
    490
    Quote Originally Posted by fred_em View Post
    Squares represent fragments (and associated screen pixels) that intersect a single triangle primitive (in red). Green squares are fragments which center does not lie in the triangle. Is the GPU supposed to raster both white and green fragments, or just green fragments?
    Just the white fragments, i.e. the ones whose centre lies inside the triangle.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •