OpenGL Perspective Projection Clipping Polygon with Vertex Outside Frustum = Wrong texture mapping?

两盒软妹~` 提交于 2021-02-05 09:02:29

问题


I see an issue where I can correctly draw a textured polygon if all vertices remain onscreen within a perspective projection, BUT if I scale the quad large enough such that one more more vertices fall 'too far behind' the viewing volume, then the resulting OpenGL drawing is incorrect (see screenshots). The texture mapping becomes skewed, and it appears as though the offscreen vertex 'moved' and becomes distorted. I am using GLES 2.0 code on a GLES 3.0 compliant driver (details at bottom). I will now explain my test in more detail --

I am drawing a GL_TRIANGLE_STRIP 'square' made of two simple polygons, and applying simplistic texture map on the quad (the texture maps perfectly onto the quad once only, with no repeats. UV coordinates 0->1 mapped as you would expect.

Seperately, I am using GLM functions to give me helpers for matrix transformations, and subsequently using glm::PerspectiveFov() to set up the viewing volume (frustum). The result is a camera looking slightly downward onto the quad, creating a 'ground' like surface with a checker patterned texture on it.

correctly drawn view of quad screenshot

From here, if I increase the scale transformation factor on the quad any further, or rotate the camera such that the offscreen corner vertices lie 'further back' from the viewing area, I see suddenly extreme weird behavior, as though the texture mapping changes, or if one vertex of the polygon is shifting incorrectly. See here:

polygon texture mapping becomes wrong

For the camera rotation I am using glm::lookAt() -- effectively I move the 'eye' position while keeping the target at 0,0 in the scene (center of the polygon).

Also note that when I cross this threshold, I see the red debug line I draw connecting all the vertices suddenly shift its orientation from where it should be.

Does anyone know how this problem originates? Is there a way to solve it so I can draw a big huge quad and have vertices offscreen without these problems/artifacts? Thanks!!!

GPU Info:

GL Vendor: Vivante Corporation

GL Renderer: Vivante GC2000

GL Version: OpenGL ES 3.0 V5.0.11.p8.41671

GLSL Version: OpenGL ES GLSL ES 3.00


回答1:


Some research and comments on my original question have led me to believe that the observed effect is the result of a bug in the OpenGL driver implementation on the Vivante GPU GC2000. Apparently such bugs are common on embedded GPU hardware drivers - a problem exacerbated by the fact that the source code for such ES implementations is never available.

To solve this one via a workaround, I was able to take the dimensions of my original square and instead create a grid array of textured squares so that all polygons end up being small enough to 'fit' close enough to the viewing area (or alternatively be completely clipped, avoiding the bug behavior). Code in C++:

// measurements we will add as we move along the grid
float tile_size = 1.0 / num_grid_subdivisions; // square width 1
float tile_uv_dist = 1.0 / num_grid_subdivisions; // assume 0->1 texture mapping
XY curr_bl = XY(-0.5, -0.5); // quad from -0.5 to 0.5 in x and y (1x1)
float cu = 0; //current texture coordinates in x dimension
float cv = 0; //current texture coordinates in y dimension
for (int row = 0; row < num_grid_subdivisions; ++row)
{
        for (int row_item = 0; row_item < num_grid_subdivisions; ++row_item)
        {
            // GL_TRIANGLES to keep simple, but could use STRIP later
            VertXYUV bl(curr_bl, cu, cv); // bottomleft
            // if we know bottomleft, we know the rest of the points of the square
            VertXYUV tl(XY(curr_bl.x, curr_bl.y + tile_size), cu, cv + tile_uv_dist);
            VertXYUV br(XY(curr_bl.x + tile_size, curr_bl.y), cu+ tile_uv_dist, cv );
            VertXYUV tr(XY(curr_bl.x + tile_size, curr_bl.y + tile_size),
            cu + tile_uv_dist, cv + tile_uv_dist);
            // our square tile is two triangle polygons
            AddVert(bl); AddVert(tl); AddVert(br); // triangle 1
            AddVert(br); AddVert(tl); AddVert(tr); // triangle 2

            // current info should always be tracking 'bl' of current tile
            // increment row item, moving across to the right (+x)
            cu += tile_uv_dist;
            curr_bl.x += tile_size;
        }

        // current info should always be tracking 'bl' of current tile
        // incrementing row, moving up (+y)
        cv += tile_uv_dist;
        cu = 0; // reset x space texture coordinate back to left side (0)
        curr_bl.y += tile_size;
        curr_bl.x = grid_bl.x;
}


来源:https://stackoverflow.com/questions/44512396/opengl-perspective-projection-clipping-polygon-with-vertex-outside-frustum-wro

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