1. 程式人生 > >Libgdx中如何繪製帶透明度的3D模型相關實現程式碼 2種方案

Libgdx中如何繪製帶透明度的3D模型相關實現程式碼 2種方案

問題?如何解決在繪製帶透明度的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);