问题描述
我看到一个问题,如果所有顶点都保留在透视投影中的屏幕上,那么我可以正确绘制带纹理的多边形,但是如果我将四边形缩放到足够大的程度,以至于又有一个顶点远远落后于"查看体积,则可以正确绘制纹理多边形生成的OpenGL绘图不正确(请参见屏幕截图).纹理贴图变得偏斜,并且看起来好像屏幕外顶点移动"并且变得扭曲.我在符合GLES 3.0的驱动程序上使用GLES 2.0代码(详细信息在底部).我现在将更详细地解释我的测试-
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 --
我正在绘制一个由两个简单多边形组成的GL_TRIANGLE_STRIP'正方形',然后在四边形上应用简单的纹理贴图(该纹理仅一次完美地映射到该四边形上,没有重复.UV坐标0-> 1就像您将要绘制的一样期待.
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.
分别地,我正在使用GLM函数为矩阵转换提供帮助,随后使用glm :: PerspectiveFov()来设置查看体积(平截头体).这样一来,摄像头会略微向下看向四边形,从而在其表面上创建一个类似地面"的表面,上面带有棋盘格花纹纹理.
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.
从这里开始,如果我进一步增加四边形上的比例变换因子,或者旋转相机以使屏幕外角顶点距查看区域再往后",我会突然发现极端的怪异行为,就像纹理一样贴图更改,或者多边形的一个顶点移动不正确.看到这里:
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:
对于摄像机旋转,我使用glm :: lookAt()-有效地移动了眼睛"位置,同时将场景中的目标保持在0(0)(多边形的中心).
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信息:
GL供应商:Vivate Corporation
GL Vendor: Vivante Corporation
GL渲染器:Vivante GC2000
GL Renderer: Vivante GC2000
GL版本:OpenGL ES 3.0 V5.0.11.p8.41671
GL Version: OpenGL ES 3.0 V5.0.11.p8.41671
GLSL版本:OpenGL ES GLSL ES 3.00
GLSL Version: OpenGL ES GLSL ES 3.00
推荐答案
对我的原始问题的一些研究和评论使我相信,观察到的效果是Vivante GPU GC2000上OpenGL驱动程序实现中的错误的结果..显然,此类错误在嵌入式GPU硬件驱动程序上很常见-由于此类ES实现的源代码永远不可用,这一问题使问题更加严重.
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.
要通过一种变通办法解决这一问题,我可以采用原始正方形的尺寸,而是创建一个带纹理的正方形的网格数组,以使所有多边形最终都足够小,可以足够"靠近观看区域(或者完全删除,以避免错误行为).C ++中的代码:
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;
}
这篇关于视锥外顶点的OpenGL透视投影剪切多边形=错误的纹理贴图?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!