使用制服时 Xamarin OpenGL 片段着色器的奇怪行为

Posted

技术标签:

【中文标题】使用制服时 Xamarin OpenGL 片段着色器的奇怪行为【英文标题】:Xamarin OpenGL fragment shader weird behaviour when working with uniforms 【发布时间】:2016-09-01 09:07:09 【问题描述】:

我目前正在处理的片段着色器有一些非常奇怪的行为,这让我抓狂。我有一个正在渲染的帧缓冲区对象。在片段着色器中,我还使用自己编写的“texelFetch”(默认情况下未实现,因为我使用的是 OpenGL ES)从相同的纹理中读取:

vec4 texelFetch(sampler2D tex, ivec2 size, ivec2 coord)

    vec2 texCoord= vec2((2.0*float(coord.x) + 1.0)/(2.0*float(size.x)), (2.0*float(coord.y) + 1.0)/(2.0*float(size.y)));
    return texture2D(tex, texCoord);

这意味着当我调用这个函数时,我还需要知道我正在渲染的纹理的大小。纹理的大小为 1440x900,在我的着色器中由统一表示:

uniform vec2 screenImageSize;

我在我的程序中设置这个值如下:

if (imageProgram != null)
            imageProgram.Use();

screenImageSizeUniform = imageProgram.GetUniformIndex("screenImageSize");
GL.Uniform2(screenImageSizeUniform, 1440.0f, 900.0f);


// Draw triangles that represents frame buffer rectangle
GL.DrawArrays(BeginMode.Triangles, 0, 6);

奇怪的是,当我使用这件制服时,我没有收到正确的输出。但是,当我对值进行硬编码时,我确实收到了正确的输出。此外,如果我执行检查以查看值是什么,我会发现制服设置正确:

//Following line does not give me the correct result as it seems to shift pixel values
//ivec2 test=ivec2(int(screenImageSize.x),int(screenImageSize.y));

//Following line does give me the correct result
ivec2 test=ivec2(1440,900);

if(test.x==1440 && test.y==900)
    gl_FragColor=texelFetch(previousFullImage,test,ivec2(gl_FragCoord.x,gl_FragCoord.y));
else
    gl_FragColor=vec4(1.0,0.0,0.0,1.0);

谁能看到我做错了什么?非常感谢任何帮助

注意:中间的图片有轻微的旋转,但那是因为我截错了。

【问题讨论】:

什么是“正确结果”,什么是“错误结果”?您正在从 float 转换为 int 很多,这取决于默认精度,这可能会“抵消”一些东西 感谢您的回复!我已经在帖子中包含了图像,并使较低的代码块更加明确。据我所知,这不是由于转换。我只进行了一次转换,我尝试过使用: - 对所有值都使用了 highp - 将属性更改为 GL.Uniform2(screenImageSizeUniform, 1440.5f, 900.5f); 两者似乎都没有效果 你读写的是同一个纹理吗? ...你在什么硬件平台上运行? 是的,我正在从/向同一个纹理读取和写入它。我在 iPhone 6+ 上运行它。 【参考方案1】:

根据@Isogen74 提供的信息,我得出结论,这可能确实是GPU 堆栈中某处的错误。因此,我决定寻找一种解决方法并更新到 opengl es 3.0。 texelFetch 已经在那里实现,不需要纹理的尺寸。现在它就像一个魅力!感谢所有的帮助=)!真的很感激!

【讨论】:

以上是关于使用制服时 Xamarin OpenGL 片段着色器的奇怪行为的主要内容,如果未能解决你的问题,请参考以下文章

片段着色器不会在 OpenGL GLSL 中创建像光一样的渐变

OpenGL均匀采样器2D具有相同的图像

opengl getUniformLocation

具有多个缓冲区的片段着色器颜色错误

片段着色器中未使用纹理数据 - OpenGL

创建一个 GLSL 制服数组?