您的位置:首页 > 编程语言

Libgdx中如何绘制带透明度的3D模型相关实现代码 2种方案

2017-12-01 18:11 387 查看
问题?如何解决在绘制带透明度的3D模型时候,深度和透明度混合之间的矛盾问题。

第一种方法:

采取透明度测试,在glsl里面,先开启透明度测试只通过不透明的部分,然后再绘制绘制透明的部分即可。

public void draw (Batch batch, float parentAlpha) {
batch.flush();
batch.end();
Gdx.gl.glDisable(GL20.GL_BLEND);
Gdx.gl.glDepthMask(true);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
matrix4.idt().set(getStage().getCamera().combined);
if (isEnableRatate) {
rotateAxisAngle(matrix4, xToAngle(deltaX), xToAngle(deltaY), 0);
} else {
deltaX = 0;
deltaY = 0;
}
shader.begin();
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformi("alphatest", 1);//glsl实现开启透明度测试
this.texture.bind();
glCircle.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP,0,glCircle.getIndexCount());

Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDepthMask(false);
shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformi("alphatest", -1);
this.texture.bind();
glCircle.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP,0,glCircle.getIndexCount());

batch.begin();

}

第二种方式(我采用的第二种实现):

采取绘制2次做法,需要绘制2次因为如果图片不带透明度就比较吃亏了。

第一次绘制:开启前面裁剪模式,绘制后面。

第二次绘制:开启背面裁剪模式,绘制前面即可。

代码如下:

Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
shader.begin();
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_ONE, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDepthMask(false);//禁用深度缓冲
Gdx.gl.glEnable(GL20.GL_CULL_FACE);
Gdx.gl.glCullFace(GL20.GL_FRONT);

shader.setUniformMatrix("u_projTrans", matrix4);
shader.setUniformi("alphatest", 0);
shader.setUniformf("t_colorAlpha", parentAlpha);//实现透明度渐变
shader.setUniformi("preAlpha", -1);//不需要预乘alpha
if(texturebg==null) {
shader.setUniformi("hasbg", -1);
textureRegion.getTexture().bind();
}else{
shader.setUniformi("hasbg", 1);
shader.setUniformf("bgAlpha", radio);
//注意该纹理的绑定顺序,有点奇葩,必须前后对调,感觉很不爽
//绑定图标层
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
textureRegion.getTexture().bind(1);
shader.setUniformi("u_texture", 1); //passing first texture!!!
//绑定背景
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);
texturebg.getRegion().getTexture().bind(0);
shader.setUniformi("u_texture2", 0); //passing first texture!!!

}

this.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP, 0, spriteVertices.length / 6);

Gdx.gl.glCullFace(GL20.GL_BACK);
shader.setUniformMatrix("u_projTrans", matrix4);

shader.setUniformf("t_colorAlpha", parentAlpha);//实现透明度渐变
shader.setUniformi("preAlpha", -1);//不需要预乘alpha
if(texturebg==null) {
shader.setUniformi("hasbg", -1);
textureRegion.getTexture().bind();
}else{
shader.setUniformi("hasbg", 1);
shader.setUniformf("bgAlpha", radio);
//注意该纹理的绑定顺序,有点奇葩,必须前后对调,感觉很不爽
//绑定图标层
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
textureRegion.getTexture().bind(1);
shader.setUniformi("u_texture", 1); //passing first texture!!!
//绑定背景
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);
texturebg.getRegion().getTexture().bind(0);
shader.setUniformi("u_texture2", 0); //passing first texture!!!

}

this.mesh.render(this.shader, GL20.GL_TRIANGLE_STRIP, 0, spriteVertices.length / 6);
shader.end();
Gdx.gl.glDisable(GL20.GL_CULL_FACE);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthMask(false);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐