我正在尝试渲染纹理粒子,我遇到了问题。 纹理透明像素做一个奇怪的事与回报。 看起来像是最接近(相机)粒子的粒子根本不会渲染。 但并非总是如此,其中一些是渲染和期待。 我试图使用深度和混合选项,但没有结果。
也许可以通过修改此部件代码找到解决方案。
gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
下面的变体修复了我的问题,但没有给我需要的结果。颗粒变得透明并相互重叠。
// gl.enable(gl.DEPTH_TEST);
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
所以我的问题是jsfiddle。
答案 0 :(得分:1)
问题是z缓冲和深度测试。
您有效地以随机深度顺序绘制四边形。因此,首先绘制一个近似粒子,它会在快乐面的角上绘制透明像素,并为这些像素设置zbuffer。后来一些粒子被吸引但是zbuffer说不要画它们。
一些解决方案,每个都有自己的问题
对您正在绘制的所有透明内容进行排序,然后绘制最远到最近的内容。
另外:它有效
减:它真的很慢,特别是对于成千上万的粒子。
使用添加剂或其他混合模式。
Plus:适用于某些情况,如火灾和可能冒烟
减号:仅适用于火灾和烟雾等特定情况
丢弃透明像素
更改着色器以丢弃像这样的透明像素
void main() {
float alphaThreshold = 0.1;
vec4 color = texture2D(u_sampler, gl_PointCoord);
if (color.a <= alphaThreshold) {
discard;
}
gl_FragColor = color;
}
Plus:适用于100%透明像素的不透明纹理
减:对于少于100%透明像素的抗锯齿,它是否真的有效。
如果您try #3 on your sample you'll see it mostly works但是当粒子非常大时,您仍然可以在仍然通过alphaThreshold
测试的半透明像素上看到问题。您可以将alphaThreshold
更改为更高的数字以丢弃更多像素,它可能看起来更好或更差。
同样仅供参考:请注意,GL对POINTS
的大小有依赖于实现的限制,因此您的示例将无法在许多实现中按预期工作。您可能需要考虑切换到quad based particles。