片段着色器的行为异常(测试网格)

时间:2019-11-01 05:07:55

标签: java opengl-es arm fragment-shader imx6

我正在尝试编写一个简单的片段着色器,以在多边形上显示网格(或更确切地说是检查器图案)。我希望此图案“保留在原处”,即,当多边形本身移动时,正方形仍保留在同一位置,因此所得到的图案会在图案的表面上滑动。

我正在使用LWJGL在Java中针对基于ARM的嵌入式系统开发此程序,并且可以在连接到PC的ARM bevice上进行远程调试,也可以在PC本身上进行本地调试。我为此使用intelliJ。

在PC上,我的程序默认使用OpenGL 3.2。在ARM上,上下文是OpenGL ES 3.0。 ARM上的图形卡是Vivante GC 2000。

这是问题所在:在本地,在我的PC上,着色器可以完美运行,就像我想要的那样。但是当我使用ARM时-模式在抖动,扭曲并且在构成我的多边形的两个三角形之间不同步。 有趣的事实是,即使着色器仅使用ModelMatrix和平面的顶点位置进行计算,图案也会根据相机位置发生变化和移动,这在帧之间都保持完全相同(我检查过)。但是相机的位置会以某种方式显着影响结果,这是不应该发生的。

这是我的顶点着色器:

#version 300 es

layout (location=0) in vec3 position;

uniform mat4 projectionMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 modelMatrix;

out highp vec3 vertexPosition;

void main()
{   
    // generate position data for the fragment shader
    // does not take view matrix or projection matrix into account
    vec4 vp = modelMatrix * vec4(position, 1.0);
    vertexPosition = vec3(vp.x, vp.y, vp.z);

    // position data for the OpenGL vertex drawing
    gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}

片段着色器:

#version 300 es

precision highp float;

in highp vec3 vertexPosition;

out mediump vec4 fragColor;

void main()
{
    highp float c = float((int(round(vertexPosition.x/5.0))+int(round(vertexPosition.z/5.0))) % 2);

    fragColor = vec4(vec3(c/2.0 + 0.3), 1);
}

如您所见,我已经尝试过对浮动操作精度进行修补,可惜没有用。您还可以注意到,只有多边形的modelMatrix和Vertex位置会影响fragColor,我可以保证将它们缩窄,并且在着色器调用之间它们不会发生变化,但是相机移动最终会以某种方式影响所生成的片段颜色/图案。

还值得注意的是,场景中对象上的其他纹理似乎都没有受到问题的影响

这是几个屏幕截图:

它在本地的外观(一切正常):

enter image description here

这是它在ARM设备上的外观。 enter image description here

请注意,纹理在三角形之间移动,并且它们之间有一条奇怪的线,似乎完全被一组完全不同的规则所填充。并非在所有视角都出现问题,只有某些视角出现。如果我将相机指向其他方向,有时我可以相当自由地移动相机,而看不到任何伪像。

我注意到的另一件事是多边形越大,发生的抖动和伪影就越多,这使我相信这与顶点位置(在顶点着色器中)的精度/计算有关,或者片段位置相对于片段着色器部分中那些顶点位置的位置。

编辑:我已经使用glGetShaderPrecisionFormat(GL_FRAGMENT_SHADER,GL_HIGH_FLOAT,范围,精度)检查了浮点数的精度;在本地PC和MTU上都是一样的。因此,不应该这样,除非您必须以某种方式专门启用我所缺少的标志。

编辑:还有我注意到的另一件事是,在本地,在PC上,一个小的测试草块出现在一个正方形的中心。在ARM上,正方形移动了一半,因此它直接位于交叉点上(如果我对摄像机进行排列,以免发生伪影)。无法正确解释这一点,因为在我看来,计算应该得出相同的结果。

无论哪种方式,我实际上都需要以某种方式解决此问题,我将感谢您的答复。

3 个答案:

答案 0 :(得分:2)

所以最终结果是两个问题的混合体:

1)运算符%在OGL 3.2和OGLES 3.0中的工作方式不同。在前者中,即使操作数为负,它也始终返回正整数。即3%2 = -3%2 = 1 但是,在OpenGL ES中,它实际上会保持符号。

2)这是一个精度问题。我正在使用高正坐标,因此我的vertexPosition坐标最终在10k正范围内。当我拿到这笔款项时,最高可达20k。似乎即使highP float也不足以在如此高的数字下保持足够的精度,因此最终会损坏。这是ODD,因为highP精度范围显示为-2 ^ 127 ~~ 2 ^ 127,这对于我的计算应该足够了。但这不是。我的解决方案是对坐标进行归一化,将值减小为<10。

如果有人可以进一步阐述我可以做的事情-请告诉我!

答案 1 :(得分:0)

我的着色器的问题仍然存在。多边形的“纹理”在某些视角会发生变形。 我在这里发现了另一个与我所遇到的问题几乎完全相同的问题,并且有一个变通办法。我会在这里链接。 OpenGL Perspective Projection Clipping Polygon with Vertex Outside Frustum = Wrong texture mapping?

答案 2 :(得分:0)

我将发布对这个问题的最终答案,这需要大量的努力,搜索以及反复试验。屏幕截图上实际上有两个单独的问题,因此我将同时介绍它们。

关于多边形相交处的奇怪纹理偏移。已经确认,这是Vivante驱动程序问题。对于片段着色器,错误地计算了位于视锥范围之外的点的坐标(请注意,在顶点着色器中它们的坐标完全正确,因此该平面不会出现撕裂,只有纹理会受到影响)。

目前似乎没有驱动程序修复。

但是,您可以实施解决方法。分割网格。而不是拥有由2个三角形组成的大型四边形,而是从几个较小的四边形中构建它。就我而言,我制作了6x6结构,总共36个四边形和64个三角形。这样一来,没有任何点距离平截头体太远了,并且精度似乎不错。

是的,这是理想情况下的FAR,但这比让片段着色器产生视觉伪像要好。


关于颜色。您可能会注意到,在屏幕截图中,颜色最终为灰色和黑色,应为浅灰色和深灰色。

解决方案并不容易到达。这是系统区域设置。

有些人甚至可能不知道,在某些斯拉夫语言环境中,定界符是逗号而不是点。基本上就是这样:

fragColor = vec4(vec3(c/2.0 + 0.3), 1);

变成了

fragColor = vec4(vec3(c/2 , 0 + 0 , 3), 1);

您可以猜测,这完全是完全错误的。实际上,我对GLSL看起来完全满意并没有给出任何运行时错误印象深刻。可能是因为vec3在创建过程中可以获取3个坐标,或类似的东西。 无论如何,此错误使我代码中的所有浮点常量完全错误,并且结果计算也错误。

以防万一有人遇到这个问题。