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

我正在尝试编写一个简单的片段着色器来在多边形上显示网格(或更确切地说是棋盘格图案)。我希望这个图案“保持在原位”,即当多边形本身移动时,正方形保持在同一位置,因此生成的图案会在图案的表面上滑动。

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

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

问题是:在本地,在我的电脑上,着色器工作完美,就像我想要的那样。但当我使用 ARM 时,图案会抖动、扭曲,并且构成多边形的两个三角形之间不同步。有趣的事实是,图案会根据相机位置而变化和移动,即使着色器仅使用模型矩阵和平面的顶点位置进行计算,这两者在帧之间保持完全相同(我检查过)。然而相机位置在某种程度上会极大地影响结果,这是不应该发生的。

这是我的顶点着色器:

#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,我可以保证我将它们连接起来,并且它们在着色器调用之间不会改变,但不知何故,相机移动最终会影响生成的片段颜色/图案。


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


largeQ
浏览 111回答 3
3回答

元芳怎么了

所以最终结果是两个问题的混合体:1) 运算符 % 在 OGL 3.2 和 OGLES 3.0 中的工作方式不同。在前者中,即使操作数为负数,它也始终返回正整数。即 3 % 2 = -3 % 2 = 1 然而,在 OpenGL ES 中,它实际上保留了符号。2)这是一个精度问题。我正在高正坐标中工作,因此我的 vertexPosition 坐标最终在 10k 正值范围内。当我计算总和时,它可能会达到20k。似乎即使是 highP float 也不足以在如此高的数字下保持足够的精度,所以它最终会崩溃。这是奇数,因为高精度范围显示为 -2^127~~2^127,这对于我的计算来说应该足够了。但事实并非如此。我的解决方案是标准化坐标,将值减小到 <10。如果有人可以进一步详细说明我可以做的事情 - 请告诉我!

白板的微信

我的着色器的问题仍然存在。多边形的“纹理”在某些视角下会变形。我在这里发现了另一个问题,它与我遇到的问题几乎完全相同,并且它有一些解决方法的答案。

炎炎设计

我将发布我对这个问题的最终答案,这是经过大量努力、搜索和反复试验的结果。实际上,屏幕截图中描绘了两个独立的问题,因此我将同时介绍这两个问题。关于多边形交叉点上奇怪的纹理偏移。已确认这是 Vivante 驱动程序问题。对于片段着色器来说,位于截锥体之外太远的点的坐标计算错误(请注意,它们在顶点着色器中完全正常,因此平面不会出现撕裂 - 只有纹理受到影响)。目前似乎没有驱动程序修复。但是,您可以实施一种解决方法。分割网格。不要使用由 2 个三角形组成的大四边形,而是用几个较小的四边形构建它。在我的例子中,我制作了一个 6x6 结构,总共 36 个四边形和 64 个三角形。这样,任何点都不会超出截锥体,并且精度看起来很好。是的,这远非理想,但它比让片段着色器产生视觉伪影要好。关于颜色。您可能会注意到,在屏幕截图中,颜色最终变为灰色和黑色,而它们应该是浅灰色和深灰色。解决方案并不容易达成。这是系统区域设置。你们中的一些人可能甚至没有意识到,在某些斯拉夫语言环境中,分隔符是逗号,而不是点。所以基本上是这样的:fragColor&nbsp;=&nbsp;vec4(vec3(c/2.0&nbsp;+&nbsp;0.3),&nbsp;1);变成fragColor&nbsp;=&nbsp;vec4(vec3(c/2&nbsp;,&nbsp;0&nbsp;+&nbsp;0&nbsp;,&nbsp;3),&nbsp;1);正如你可以猜到的,这是完全错误的。事实上,令我印象深刻的是,GLSL 似乎对此完全没问题,并且不会给出任何运行时错误。可能是因为 vec3 在创建过程中可以采用 3 个坐标,或者其他什么。无论如何,这个bug使得我代码中的所有浮点常量完全错误,并且得到的计算结果也是错误的。以防万一有人遇到这个问题。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java