Javascript WebGL/Three.js-移动相机时,由纹理着色的粒子不稳定地闪烁
这是我放在一起的一个例子,展示了当使用纹理着色和相机移动时粒子“闪烁”的问题 更新:粒子上不应出现动画或运动。如果在视口上单击并拖动时,粒子在闪烁或改变颜色,则您会看到问题。这是我在firefox和chrome上用MacOS10.9和Windows7测试和发现的问题 粒子不会以任何方式重叠或剪切。如果使用常规着色器对粒子设置动画,则不会发生闪烁。只有当粒子使用纹理(在本例中使用THREE.WebGLRenderTarget)着色时,闪烁才会明显。这样做是为了捕获以前的帧并将它们存储在缓冲区中(然后可以以JSFIDLE示例中未显示的更高级方式使用缓冲区) 事实上,碎片着色器可能会错误地捕捉到一个相邻像素,而不是它的目标,但我不确定-这没有多大意义,因为目标坐标仅在init()上生成,并且在那之后不会更改 每个粒子的目标像素坐标将作为顶点属性传递给片段着色器1-1,不作更改(作为一个可变但没有可变值)Javascript WebGL/Three.js-移动相机时,由纹理着色的粒子不稳定地闪烁,javascript,three.js,webgl,Javascript,Three.js,Webgl,这是我放在一起的一个例子,展示了当使用纹理着色和相机移动时粒子“闪烁”的问题 更新:粒子上不应出现动画或运动。如果在视口上单击并拖动时,粒子在闪烁或改变颜色,则您会看到问题。这是我在firefox和chrome上用MacOS10.9和Windows7测试和发现的问题 粒子不会以任何方式重叠或剪切。如果使用常规着色器对粒子设置动画,则不会发生闪烁。只有当粒子使用纹理(在本例中使用THREE.WebGLRenderTarget)着色时,闪烁才会明显。这样做是为了捕获以前的帧并将它们存储在缓冲区中(然
有人知道如何做到这一点而不闪烁吗?当我将此技术应用于更大更快的动画时,问题似乎只会变得更糟。到目前为止,我检查过的所有浏览器上都会出现这种情况。问题是您指向的是texel之间的边缘 这些线
geoX.push(tx / imageSize);
geoY.push(1.0 - ty / imageSize); // flip y
计算texel之间的精确边。我的意思是说,imageSize
是4个texel,也就是说tx
和ty
从0
到3
你的纹理坐标是这样的
0 0.25 0.5 0.75 <- texture coords you're computing
| | | |
V V V V
+-----+-----+-----+-----+
| | | | |
| | | | | <- texels
+-----+-----+-----+-----+
0.125 0.375 0.625 0.875
| | | |
V V V V
+-----+-----+-----+-----+
| | | | |
| | | | | <- texels
+-----+-----+-----+-----+
问题在于数学直接指向texel之间,舍入错误使它选择一个texel或另一个texel。选择纹理的中心将修复此问题。如果图像在相邻纹理之间没有太多对比度,您可能不会注意到。我没有看到任何闪烁。在这个演示中需要彩色动画吗?演示这个问题需要渲染目标吗?这里也没有闪烁,Chrome和Firefox-Linux。您使用的是什么GPU、浏览器和操作系统?是否应用了任何驱动程序解决方法(关于:gpu)?@WestLangley渲染目标是必需的,因为我需要捕获最后几帧以用于动画。我将JSFIDLE简化为问题出现的基准示例。没有闪烁。显示闪烁是否需要动画?如果没有,关闭它并简化演示。动画对我有帮助,但我已经简化了它,这样动画就不会更新,应该不会有任何移动。移动相机时,您是否仍然看不到闪烁?这就解决了!谢谢@gman!我怀疑这与抓取错误的相邻像素(texel)有关!我正在研究一个暴力解决方案,通过将像素加倍来提供填充空间和出错空间,但您所拥有的要好得多,可以直接解决问题。顺便说一句,这里是一个更新的小提琴为任何人看到闪烁,并希望测试这个解决方案。另外,我很确定这种闪烁只发生在装有NVIDIA GeForce图形卡的机器上(不管是哪种浏览器)。
0.125 0.375 0.625 0.875
| | | |
V V V V
+-----+-----+-----+-----+
| | | | |
| | | | | <- texels
+-----+-----+-----+-----+
geoX.push(tx / imageSize + 0.5 / imageSize);
geoY.push(1.0 - ty / imageSize + 0.5 / imageSize); // flip y