gpt4 book ai didi

opengl - 对渲染的 FBO 的纹理查找偏差了半个像素

转载 作者:行者123 更新时间:2023-12-02 02:21:26 30 4
gpt4 key购买 nike

我有一个通过 FBO 渲染为纹理的场景,我从片段着色器中对其进行采样,使用基元绘制它的区域,而不是绘制全屏四边形:我通过仅生成片段来节省资源会需要的。

为了测试这一点,我发出与纹理渲染完全相同的几何图形,这意味着生成的光栅化图案应该完全相同:当我的片段着色器使用给定的变化坐标查找其纹理时,它应该与给出的其他值完美匹配。

以下是我如何为片段着色器提供坐标,以使用全屏纹理自动为几何体添加纹理:

// Vertex shader
uniform mat4 proj_modelview_mat;
out vec2 f_sceneCoord;
void main(void) {
gl_Position = proj_modelview_mat * vec4(in_pos,0.0,1.0);
f_sceneCoord = (gl_Position.xy + vec2(1,1)) * 0.5;
}

我正在从事 2D 工作,所以我不关心这里的视角鸿沟。我只是使用从 [-1,1] 缩小到 [0,1] 的剪辑空间位置来设置 sceneCoord 值。

uniform sampler2D scene;
in vec2 f_sceneCoord;
//in vec4 gl_FragCoord;
in float f_alpha;
out vec4 out_fragColor;
void main (void) {
//vec4 color = texelFetch(scene,ivec2(gl_FragCoord.xy - vec2(0.5,0.5)),0);
vec4 color = texture(scene,f_sceneCoord);
if (color.a == f_alpha) {
out_fragColor = vec4(color.rgb,1);
} else
out_fragColor = vec4(1,0,0,1);
}

请注意,如果我的 alpha 不匹配,我会吐出一个红色碎片。纹理渲染将每个渲染对象的 alpha 设置为特定索引,这样我就知道什么与什么匹配。

抱歉,我没有图片可显示,但很明显我的像素偏离了 (0.5,0.5):我的对象周围有一个细长的、一个像素的红色边框,在它们的底部和左侧,可以弹出和弹出。看起来很“短暂”。赠品是它只显示在对象的底部和左侧。

请注意,我注释掉了一行使用 texelFetch 的内容:此方法有效,并且我不再显示红色片段。不过,我想让它与 texture 和标准化纹理坐标一起正常工作,因为我认为更多的硬件将支持这一点。也许真正的问题是,是否有可能在不通过制服发送我的视口(viewport)分辨率的情况下做到这一点?一定有办法避免这种情况!

更新:我尝试将纹理访问移动半个像素、四分之一个像素、百分之一像素,这一切都使情况变得更糟,并在边缘周围产生了错误值的实心边框:看起来像我的gl_Position.xy+vec2(1,1))*0.5 技巧设置了正确的值,但采样只是稍微偏离了一点点。这很奇怪……看到红色碎片了吗?当物体运动时,它们会轻微地进出。这意味着我设置的 Alpha 值与这些像素不完美匹配。

transient red fragments indicate a texture sampling mis-match

对于我的实际应用程序来说,获得 alpha 索引检查的像素完美精度并不重要,但这种行为并不是我所期望的。

最佳答案

好吧,首先考虑删除 f_sceneCoord 变化并仅使​​用 gl_FragCoord/screenSize 作为纹理坐标(您的示例中已经有了这个,但是 -0.5 是垃圾),而 screenSize 是统一的(可能是预先划分的)。这应该几乎准确地工作,因为默认情况下 gl_FragCoord 位于像素中心(意味着 i+0.5),并且 OpenGL 在对纹素中心采样纹理时返回准确的纹素值( (i+0.5)/textureSize)。

由于有限的精度等原因,这仍然可能会导致精确的纹素值(如果有)非常非常轻微的偏差。但话又说回来,无论如何,您可能希望使用 GL_NEAREST 过滤模式来进行这种一对一的纹理到屏幕映射。实际上,您现有的 f_sceneCoord 方法可能已经运行良好,而正是 GL_NEAREST 阻止的那些小舍入问题创建了您的伪影。但话又说回来,您仍然不需要 f_sceneCoord 东西。

编辑:关于texelFetch的可移植性。我认为该功能是在 GLSL 1.30(~SM4/GL3/DX10 硬件、~GeForce 8)中引入的。但您正在使用的新 in/out 语法已经需要此版本(与旧的 variing/attribute 语法相反)。因此,如果您不打算更改这些,假设给定的 texelFetch 绝对没有问题,并且可能比texture 稍快(这也需要 GLSL 1.30,与旧的 texture2D),通过完全规避过滤。

关于opengl - 对渲染的 FBO 的纹理查找偏差了半个像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8875587/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com