WebGL/Three.js - 移动相机时由纹理着色的粒子不规则闪烁 [英] WebGL / Three.js - Particles colored by texture flicker erratically while moving camera

查看:45
本文介绍了WebGL/Three.js - 移动相机时由纹理着色的粒子不规则闪烁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是一个 jsfiddle 我把使用纹理和相机移动时.

Here's a jsfiddle I put together showing the problem of particles "flickering" while being colored using a texture and while the camera is moving.

更新:粒子上不应该有动画或运动发生.如果当您在视口上单击并拖动时,粒子完全闪烁或改变颜色,那么您就会看到问题所在.这是我在 mac OS 10.9 和 windows 7 上的 firefox 和 chrome 上测试并看到的一个问题.

Update: There should be no animation or movement happening on the particles. If when you click and drag on the viewport and the particles are flickering or changing colors at all then you are seeing the issue. This is a problem I've tested and seen on both firefox and chrome with mac OS 10.9 and windows 7.

粒子没有以任何方式重叠或剪裁.如果使用常规着色器对粒子进行动画处理,则不会发生闪烁.只有当粒子使用纹理着色(在本例中使用 THREE.WebGLRenderTarget)时,闪烁才会明显.这样做是为了捕获先前的帧并将它们存储在缓冲区中(然后可以以更高级的方式使用,未在 jsfiddle 示例中显示).

The particles are not overlapping or clipping in any way. If the particles are animated with a regular shader the flickering does not happen. It's only when the particles are colored using a texture (in this case using THREE.WebGLRenderTarget), is the flickering evident. It is done this way in order to capture previous frames and store them in a buffer (that could then be used in more advanced ways not shown in the jsfiddle example).

实际上似乎片段着色器可能错误地抓取了相邻像素,而不是它的目标,但我不确定 - 这没有多大意义,因为目标坐标仅在 init() 上生成,并且在那之后它们不会改变.

It actually seems like the fragment shader might be mistakenly grabbing a neighbor pixel, instead of it's target, but I'm not certain - and that doesn't make much sense, because the target coordinates are only generated on init(), and they don't change after that.

每个粒子的目标像素坐标作为顶点属性原封不动地传递给片段着色器 1-1(作为变化但没有变化的值).

The target pixel coordinates for each particle are passed as a vertex attribute to the fragment shader 1-1 unaltered (as a varying but with no varying value).

uniform sampler2D colorMap; // The texture being used to color each particle
varying float v_geoX; // x,y coordinates passed as varyings
varying float v_geoY;

void main() {
    // Normally pulling the correct color, but this seems to get confused during camera movement.
    gl_FragColor = texture2D(colorMap, vec2(v_geoX, v_geoY));
}

有人对如何做到这一点没有闪烁有任何想法吗?当我将此技术应用于更大更快的动画时,问题似乎只会变得更糟.到目前为止,我检查过的所有浏览器都会发生这种情况.

Anyone have any ideas on how to do this without the flickering? When I apply this technique to larger and faster animations the problem only seems to get worse. It's happening on all browsers I've checked so far.

推荐答案

问题是您指向了纹素之间的边缘.

The issue is you're pointing at the edges between texels.

这些行

   geoX.push(tx / imageSize);
   geoY.push(1.0 - ty / imageSize); // flip y

计算纹素之间的精确边缘.我的意思是说 imageSize 是 4 个纹素,让我们说 txty03

compute the exact edge between texels. What I mean by that is lets say imageSize is 4 texels and lets say tx and ty go from 0 to 3

你的纹理坐标是这样的

   0    0.25  0.5   0.75       <- texture coords you're computing
   |     |     |     |     
   V     V     V     V     
   +-----+-----+-----+-----+
   |     |     |     |     |
   |     |     |     |     |   <- texels
   +-----+-----+-----+-----+

但是你想要的纹理坐标是这样的

But the texture coords you want are like this

     0.125 0.375 0.625 0.875   
      |     |     |     |   
      V     V     V     V  
   +-----+-----+-----+-----+
   |     |     |     |     |
   |     |     |     |     |   <- texels
   +-----+-----+-----+-----+

最简单的解决方法是添加 1/2 纹素

The easiest fix is to add 1/2 a texel

   geoX.push(tx / imageSize       + 0.5 / imageSize);
   geoY.push(1.0 - ty / imageSize + 0.5 / imageSize); // flip y

问题在于您的数学直接指向纹素舍入误差之间,使其选择一个纹素或另一个.选择纹素的中心将解决这个问题.如果图像在相邻纹素之间没有太大的对比度,您可能没有注意到.

The problem is with your math pointing directly between texels rounding errors make it pick one texel or the other. Choosing the center of the texel will fix that. If the image didn't have so much contrast between neighboring texels you might not have noticed.

这篇关于WebGL/Three.js - 移动相机时由纹理着色的粒子不规则闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆