【问题标题】:Libgdx Parallax shaderLibgdx 视差着色器
【发布时间】:2018-09-27 17:20:20
【问题描述】:

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

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

我以前从未见过在不将其设置为批处理的情况下使用 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。谢谢!

【问题讨论】:

    标签: libgdx glsl shader parallax


    【解决方案1】:

    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() 都没有帮助。您能否建议如何取消应用着色器?
    • 如果您已经在 parallax.render 之前调用了 batch.begin,则需要在开始使用着色器或使用 FuScreenQuad 进行渲染之前调用 batch.end。
    • 感谢您的提示。最后选择了 RenderingContext。不确定性能开销(因为使用了 RenderingContext),但我计划稍后看看为什么 batch.end 不适用于这种情况。
    猜你喜欢
    • 2021-10-06
    • 1970-01-01
    • 1970-01-01
    • 2012-04-26
    • 2020-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-02
    相关资源
    最近更新 更多