我在透明度和3d粒子方面遇到了一些奇怪的问题。一个简短的视频来说明: https://youtu.be/ZHKI1X3MjhY 如你所见,我有一个三维粒子效果,燃烧。里面是一个3模型,没有alpha混合,它显示很好。然后在远处有一个小骨架(混合和alphatest打开),它也显示在火上很好。然后我转动相机,看着战士骨架,它就消失了,相反,你看到了他背后的东西。我再次转动相机并且法师骨架也消失了,但你可以看到更远的树木就好了,它们具有完全相同的混合和alpha测试设置。如果我移动角色说20码之外它也会开始显示火焰效果。
所以它似乎与距离三维粒子效果有关...
3d粒子批次是扩展的BillboardParticleBatch,如下所示:
protected Renderable allocRenderable(){
BlendingAttribute ba=new BlendingAttribute(GL20.GL_SRC_ALPHA, GL20.GL_ONE,1f);
Renderable r = super.allocRenderable();
r.material = new Material( ba,
// new DepthTestAttribute(GL20.GL_LEQUAL, 0.0f, 0.5f, true),
// r.material.set(new FloatAttribute(FloatAttribute.AlphaTest, 0.0f),
TextureAttribute.createDiffuse(texture));
return r;
}
使用以下属性创建所有字符和树:
if (alpha) {
FloatAttribute floatAttribute = new FloatAttribute(FloatAttribute.AlphaTest, 0.5f);
BlendingAttribute blendingAttribute = new BlendingAttribute(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, 1f);
for (int i = 0; i < bulletEntity.modelInstance.materials.size; i++){
bulletEntity.modelInstance.materials.get(i).set(blendingAttribute);
bulletEntity.modelInstance.materials.get(i).set(floatAttribute);
}
}
首先绘制模型然后绘制粒子,我尝试改变顺序但没有区别。我已经为alphatest,depthtest和blendattribute尝试了很多不同的设置,但找不到任何有效的设置。
修改的 我从3d模型中删除了Blending属性,现在看起来应该关于粒子效果。但是我需要在我的角色模型上使用大多数材料进行混合设置..
当我启用混合时,任何人都知道为什么会发生这种情况?
我还尝试使用BillboardParticleBatch而不延长它,以防我在那里做了什么,但效果更糟。所有具有混合功能的模型都会出现在粒子效果的前面,即使它们位于它后面。
答案 0 :(得分:0)
ModelBatch
对您的渲染调用进行排序(检查this link,确实,这是必读的),以避免不正确的行为(正如您所经历的那样)。实际的排序/呈现在调用ModelBatch#end
时发生。默认情况下,它使用DefaultRenderableSorter
,这是默认实现。当然,因为该实现不了解您的场景,所以它可能不完全符合您的需求。
DefaultRenderableSorter
尝试根据变换矩阵猜测每个模型的位置。根据该位置和相机的位置,它将对它们进行排序,以便:
要确定对象是否透明,请使用BlendingAttribute#blended成员。 (所以如果你真的想,可以将该成员设置为false以强制它被处理(排序),就像它是不透明的一样)
因此,您调用ModelBatch#render
的顺序不一定是它们实际执行的顺序。如果您想强制渲染您在中间添加到批处理中的任何内容,请调用ModelBatch#flush()
。当然,这样做很多事情首先会破坏ModelBatch的一些目的。
相反,您可以实现自己的RenderableSorter
,它对您的场景有更多的了解,因此可以比默认实现更好地进行排序。 (但如果flush()
适用于您并且没有其他问题,那么只有flush
可能是最简单的解决方案。)
也就是说,您可以尝试其他各种解决方案。例如。粒子的区域是完全透明的,因此片段着色器也可以将它们全部丢弃。尝试将FloatAttribute.AlphaTest
的值0.5f
添加到粒子中。如果这与你的混合混淆,那么逐渐减少到例如0.05f
。
此外,您可以添加DepthTestAttribute depthMask
设置为false
(new DepthTestAttribute(false)
)。这将防止粒子写入深度缓冲区。 (但也可能导致其他事物出现在粒子前面。)