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

查看:374
本文介绍了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个纹素,让我们说 tx ty 0 转到 3

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

问题在于你的数学直接指向texels舍入错误使它选择一个texel或者另一个。选择纹素的中心将解决这个问题。如果图像在相邻纹素之间没有那么多对比,你可能没有注意到。

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天全站免登陆