我进入了LibGDX的着色器,发现有一些属性只在LibGDX中使用。
来自https://github.com/libgdx/libgdx/wiki/Shaders的标准顶点和片段着色器非常适用于我的SpriteBatch。
当我尝试使用像https://github.com/SupSuper/OpenXcom/blob/master/bin/common/Shaders/HQ2x.OpenGL.shader这样的HQX着色器时,我会遇到很多错误。
可能是因为我需要将一些LibGDX因变量发送到着色器,但我无法找出应该是哪个。
我想在大屏幕的桌面上使用这些着色器,这样游戏在这些屏幕上看起来很棒。
我使用此代码加载着色器:
try {
shaderProgram = new ShaderProgram(Gdx.files.internal("vertex.glsl").readString(), Gdx.files.internal("fragment.glsl").readString());
shaderProgram.pedantic = false;
System.out.println("Shader Log:");
System.out.println(shaderProgram.getLog());
} catch(Exception ex) { }
着色器日志输出:
No errors.
提前致谢。
答案 0 :(得分:0)
这是一个后处理着色器,所以你的流程应该是这样的:
使用SpriteBatch的默认着色器以像素完美分辨率将场景绘制到FBO。
使用升级着色器将FBO的纹理绘制到屏幕的帧缓冲区。如果修改着色器以匹配SpriteBatch使用的属性和制服,则可以使用SpriteBatch执行此操作。 (您也可以使用着色器期望的属性名称创建一个简单的网格,但SpriteBatch可能最简单。)
首先,我们没有使用SpriteBatch的典型着色器,因此您需要在加载任何内容之前在某处调用ShaderProgram.pedantic = false;
。
现在你需要一个合适尺寸的FrameBuffer。它的大小应该是你的精灵像素完美(纹理的一个像素缩放到世界的一个像素)。像这样:
public void resize (int width, int height){
float ratio = (float)width / (float) height;
int gameWidth = (int)(GAME_HEIGHT / ratio);
boolean needNewFrameBuffer = false;
if (frameBuffer != null && (frameBuffer.getWidth() != gameWidth || frameBuffer.getHeight() != GAME_HEIGHT)){
frameBuffer.dispose();
needNewFrameBuffer = true;
}
if (frameBuffer == null || needNewFrameBuffer)
frameBuffer = new FrameBuffer(Format.RGBA8888, gameWidth, GAME_HEIGHT);
camera.viewportWidth = gameWidth;
camera.viewportHeight = GAME_HEIGHT;
camera.update();
}
然后你可以像绘制屏幕一样绘制到帧缓冲区。然后,将帧缓冲区的纹理绘制到屏幕上。
public void render (){
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
frameBuffer.begin();
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.setShader(null); //use default shader
batch.begin();
//draw your game
batch.end();
frameBuffer.end();
batch.setShader(upscaleShader);
batch.begin();
upscaleShader.setUniformf("rubyTextureSize", frameBuffer.getWidth(), frameBuffer.getHeight());//this is the uniform in your shader. I assume it's wanting the scene size in pixels
batch.draw(frameBuffer.getColorBufferTexture(), -1, 1, 2, -2); //full screen quad for no projection matrix, with Y flipped as needed for frame buffer textures
batch.end();
}
您还需要对着色器进行一些更改,以便它可以与OpenGL ES一起使用,并且因为SpriteBatch连接了特定的属性和统一名称:
在顶点着色器的顶部,添加此项以定义顶点属性和变化(链接着色器不需要它,因为它依赖于GL ES中不可用的内置变量):
attribute vec4 a_position;
attribute vec2 a_texCoord;
varying vec2 v_texCoord[5];
然后在顶点着色器中,将gl_Position
行更改为
gl_Position = a_position; //since we can't rely on built-in variables
并将所有gl_TexCoord
替换为v_texCoord
,原因相同。
在片段着色器中,要与OpenGL ES兼容,您需要声明精度。您还需要声明相同的变化,因此将其添加到顶部:
#ifdef GL_ES
precision mediump float;
#endif
varying vec2 v_texCoord[5];
与顶点着色器一样,将所有出现的gl_TexCoord
替换为v_texCoord
。并且还将所有rubyTexture
替换为u_texture
,这是SpriteBatch使用的纹理名称。
我认为这就是一切。我实际上并没有对此进行测试,而且我会记忆犹新,但希望它可以让你接近。