FBO模拟着色器中的纹理查找

3
我正在尝试通过在单独的通道中计算位置来制作FBO粒子系统。
现在使用这篇文章中的代码http://barradeau.com/blog/?p=621。我渲染了一个没有任何移动的粒子球:

目前我所添加的唯一内容是在模拟片段着色器中加入一种纹理:

void main() {
    vec3 pos = texture2D( texture, vUv ).xyz;
    //THIS LINE, pos is approx in -200..200 range
    float map = texture2D(texture1, abs(pos.xy/200.)).r;
    ...
    // save map value in ping-pong texture as alpha
    gl_FragColor = vec4( pos, map );

texture1是:一半黑色,一半白色。

然后在渲染顶点着色器中,我读取了这个贴图参数:

map = texture2D( positions, position.xy ).a;

然后在 渲染 片段着色器中使用它来查看颜色:

vec3 finalColor = mix(vec3(1.,0.,0.),vec3(0.,1.,0.),map);
gl_FragColor = vec4( finalColor, .2 );

我希望看到的是:(通过在渲染着色器中设置相同的纹理实现)

但我真正看到的是:(通过在模拟着色器中设置纹理)

颜色混杂在一起,尽管大多数情况下你会看到更多的红色颗粒在它们应该出现的地方,但是在中间有很多绿色颗粒。
我也试着用简化的贴图和相同的想法制作了自己的演示,结果如下:

同样的错误,混乱的但是你仍然可以猜测出图片。 我认为我错过了一些显而易见的东西。但是我已经挣扎了几天,自己找不到错误。
非常感谢有人能指点我正确的方向。预先感谢您!
带有错误演示:http://cssing.org.ua/examples/fbo-error/ 完整代码参考:https://github.com/akella/fbo-test

1
你尝试过使用GL_NEAREST禁用纹理过滤吗? - keaukraine
1
好的,它起作用了!我今晚稍后会确认一下,但到目前为止,我已经提交了 https://github.com/akella/fbo-test,并按照我理解的方式进行了操作,效果很好!我会问自己为什么在渲染通道中默认工作,但在模拟中不是这样。但如果我今晚确认了,我正式欠你一杯啤酒! - Yurii Artyukh
确认了!那就是问题所在。你能把这个加到你的答案里,这样我就可以标记它为正确的了吗?现在可以用了!http://cssing.org.ua/examples/fbo-particles/ - Yurii Artyukh
2个回答

1
你应该使用GL_NEAREST最近点采样来禁用纹理过滤。

0

我的猜测是THREE.TextureLoader()使用mipmaps加载纹理,而在顶点着色器中调用texture2D使用最低分辨率的mipmap。在顶点着色器中,您应该使用texture2DLod(texture, texCoord, 0.0) - 注意第三个参数lod,它指定了0 mipmap级别。


1
谢谢您的想法!但是我实际上是在模拟中在片段着色器中加载纹理。 =( 我尝试了map = texture2DLod(texture1, abs(vec2(pos.x/100.,pos.x/100.)), 0.0);但它没有改变这个模糊问题。 - Yurii Artyukh
哎呀,原来是缓存问题。就我所知,texture2DLod 只能在顶点着色器中使用,对吗?但是我在片段着色器中进行了查找。 - Yurii Artyukh
是的,texture2DLod仅在顶点着色器中可用。您可以参考Khronos组织的官方GLSL速查表 - https://www.khronos.org/opengles/sdk/docs/reference_cards/OpenGL-ES-2_0-Reference-card.pdf - 它非常方便。 - keaukraine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接