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);
我正在尝试使用列出的着色器代码制作着色器支持的视差效果 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);