Libgdx 视差着色器

Libgdx Parallax shader

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

论坛 post here 也说 "code doesn't use a SpriteBatch, it renders the Mesh directly with the texture parameters set up in the shader".

我以前从未见过在不将其设置为批处理的情况下使用 ShaderProgram,所以我可能在这里遗漏了一些非常基本的东西。

 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 已列出 here。谢谢!

FullscreenQuad class 使用 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);