Libgdx视差着色器

Libgdx视差着色器,libgdx,glsl,shader,parallax,Libgdx,Glsl,Shader,Parallax,我正在尝试使用列出的着色器代码制作一个着色器支持的视差效果。但我得到的只是一个白色的屏幕 论坛帖子还说“代码不使用SpriteBatch,它使用着色器中设置的纹理参数直接渲染网格” 我以前从未见过在不将着色器程序设置为批处理的情况下使用着色器程序,因此可能我在这里遗漏了一些非常基本的东西 public class Parallax { private final ShaderProgram parallaxShader; private final Fulls

我正在尝试使用列出的着色器代码制作一个着色器支持的视差效果。但我得到的只是一个白色的屏幕

论坛帖子还说“代码不使用SpriteBatch,它使用着色器中设置的纹理参数直接渲染网格”

我以前从未见过在不将着色器程序设置为批处理的情况下使用着色器程序,因此可能我在这里遗漏了一些非常基本的东西

 public class Parallax {

        private final ShaderProgram parallaxShader;
        private final FullscreenQuad fullscreenQuad;
        private final Array<Texture> backgrounds;

        public Parallax(final String parallaxTexturesSubfolderName) {
            parallaxShader = initShader();
            fullscreenQuad = new FullscreenQuad();

            backgrounds = populateBackgrounds(parallaxTexturesSubfolderName);
        }

        private Array<Texture> populateBackgrounds(String parallaxTexturesSubfolderName) {
            final Array<Texture> textures = new Array<Texture>();
            for (int i = 0; i < 4; i++) {
                final Texture texture = new Texture(Gdx.files.internal("parallax/" + parallaxTexturesSubfolderName + "/" + "img" + i + ".png"));
                  texture.setWrap(Texture.TextureWrap.MirroredRepeat, Texture.TextureWrap.MirroredRepeat);
                textures.add(texture);
            }
            return textures;
        }


        private ShaderProgram initShader() {
            ShaderProgram.pedantic = false;
            final String vertexShader = Gdx.files.internal("shaders/parallax-vert.glsl").readString();
            final String fragmentShader = Gdx.files.internal("shaders/parallax-frag.glsl").readString();

            final ShaderProgram shader = new ShaderProgram(vertexShader, fragmentShader);
            if (!shader.isCompiled()) {
                Gdx.app.log("ShaderTest", shader.getLog());
                Gdx.app.exit();
            }
            return shader;
        }


        public void render(final Camera camera, final SpriteBatch batch) {
    //        batch.setShader(parallaxShader); //tried with batch also - doesn't seems to work
    //        batch.begin(); 

            for (int i = 0; i < backgrounds.size; i++) {
                backgrounds.get(i).bind(i);
            }

            float travelDistance = camera.position.x / 800f / 15f;
            parallaxShader.begin();
//            parallaxShader.setUniformMatrix("u_projTrans", camera.combined); 
            parallaxShader.setUniformf("travelDistance", travelDistance);
            parallaxShader.setUniformi("u_texture0", 0);
            parallaxShader.setUniformi("u_texture1", 1);
            parallaxShader.setUniformi("u_texture2", 2);
            parallaxShader.setUniformi("u_texture3", 3);
            fullscreenQuad.render(parallaxShader);
            parallaxShader.end();
    //        batch.setShader(null);
    //        batch.end();
        }

        public void dispose() {
          ...
        }
    }
公共级视差{
私人最终着色器程序视差着色器;
私人最终FullscreenQuad FullscreenQuad;
私有最终数组背景;
公共视差(最终字符串parallaxTexturesSubfolderName){
视差着色器=initShader();
fullscreenQuad=新的fullscreenQuad();
背景=大众背景(视差xtexturessubfoldername);
}
专用数组populateBackgrounds(字符串parallaxTexturesSubfolderName){
最终阵列纹理=新阵列();
对于(int i=0;i<4;i++){
最终纹理=新纹理(Gdx.files.internal(“parallax/”+parallaxTexturesSubfolderName+“/”+“img”+i+”.png”);
texture.setWrap(texture.TextureWrap.MirroredRepeat,texture.TextureWrap.MirroredRepeat);
纹理。添加(纹理);
}
返回纹理;
}
私有着色器程序initShader(){
ShaderProgram.pedantic=false;
最终字符串vertexShader=Gdx.files.internal(“着色器/视差vert.glsl”).readString();
final String fragmentShader=Gdx.files.internal(“shaders/parallax frag.glsl”).readString();
最终着色器程序着色器=新着色器程序(顶点着色器、碎片着色器);
如果(!shader.isCompiled()){
Gdx.app.log(“ShaderTest”,shader.getLog());
Gdx.app.exit();
}
返回着色器;
}
公共无效渲染(最终摄影机、最终SpriteBatch批处理){
//batch.setShader(parallaxShader);//也尝试使用batch-似乎不起作用
//batch.begin();
对于(int i=0;i

已列出FullscreenQuad。谢谢

FullscreenQuad类使用
a_texCoord0
作为UV名称,但教程中的着色器使用
a_texCoords
。这些名字需要匹配

为了避免像这样难以调试的问题,我建议在进行开发构建时不要关闭
ShaderProgram.pedantic
。但一定要在发布时使用它,以避免硬崩溃

与您的问题无关: 本教程中片段着色器的最后三行为非保证编译时优化带来了很大希望。GLSL已经有一个优化的线性插值函数。只计算RGB可能会更快,因为最终alpha将不被使用。最后一行应该改成这样

gl_FragColor.rgb = mix(gl_FragColor.rgb, texel1.rgb, texel1.a);
gl_FragColor.rgb = mix(gl_FragColor.rgb, texel2.rgb, texel2.a);
gl_FragColor.rgb = mix(gl_FragColor.rgb, texel3.rgb, texel3.a);

多谢各位!成功了!但是,现在所有其他纹理都渲染为白色。batch.setShader(null)和batch.end()都没有帮助。您可以建议如何取消应用着色器吗?如果您已经调用了batch.begin before parallax.render,则需要在开始使用着色器或FuScreenQuad进行渲染之前调用batch.end。感谢您提供的提示。最后是RenderingContext。不确定性能开销(因为RenderingContext的使用),但我计划稍后再查看batch.end为何不适用于这种情况。