使用 OpenGL / LibGDX 的后处理问题 - 黑屏(FBO、着色器、四边形)
Posted
技术标签:
【中文标题】使用 OpenGL / LibGDX 的后处理问题 - 黑屏(FBO、着色器、四边形)【英文标题】:Postprocessing problems using OpenGL / LibGDX - black screen (FBO, shaders, quad) 【发布时间】:2014-10-13 21:44:43 【问题描述】:我在将后处理阶段渲染到屏幕上时遇到了一些问题。我写了一些可以在屏幕上渲染好的代码,然后决定我需要一些后处理(棕褐色的绽放效果,但之后会出现)所以我决定将所有内容渲染到 FrameBuffer 对象,然后使用它的颜色纹理来渲染纹理,全屏四边形。问题是,即使使用一些简单的着色器,我要么得到一个黑屏(或者我用来清除颜色缓冲区的任何颜色),要么禁用深度测试,或者一些垃圾像素占据屏幕的左下四分之一,启用时深度测试(那只是盲测,我不确定是否需要在 2D 游戏中进行深度测试,但我的 OpenGL 理解很差)。
那么,我做错了什么?代码如下:
简单的顶点着色器:
attribute vec4 a_position;
attribute vec4 a_color;
attribute vec2 a_texCoord0;
varying vec4 vColor;
varying vec2 vTexCoord;
void main()
vColor = a_color;
vTexCoord = a_texCoord0;
gl_Position = a_position;
简单的片段着色器:
#ifdef GL_ES
precision mediump float;
#endif
varying vec4 vColor;
varying vec2 vTexCoord;
uniform sampler2D u_texture;
void main()
vec4 texColor = texture2D(u_texture, vTexCoord);
gl_FragColor = vColor.rgba * vec4(texColor.rgb, 1.0);
初始化:
FrambeBuffer fbo;
ShaderProgram focusShader;
Mesh focusQuad;
@Override
public void show()
camera1 = new OrthographicCamera();
camera1.setToOrtho(false);
camera1.zoom = 0.8f;
viewport = new ExtendViewport(Globals.VIEWPORT_WIDTH, Globals.VIEWPORT_HEIGHT, camera1);
batch = new SpriteBatch();
moveCamera(camera1, player.getX(), player.getY());
fbo = new FrameBuffer(Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
ShaderProgram.pedantic = false;
focusShader = new ShaderProgram(Gdx.files.internal("shaders/trivial_vshader"), Gdx.files.internal("shaders/trivial_fshader"));
focusQuad = createFullScreenQuad(); //TAKEN FROM https://github.com/manuelbua/libgdx-contribs/blob/master/postprocessing/src/main/java/com/bitfire/postprocessing/utils/FullscreenQuad.java
// Other game initialization...
渲染循环:
@Override
public void render(float delta)
// (UPDATE PHYSICS)...
fbo.begin();
/* DRAW THE PLAYER */
batch.setProjectionMatrix(camera1.combined);
batch.begin();
player.drawTrail(batch, delta);
player.draw(batch, delta);
batch.end();
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
shapeRenderer.setProjectionMatrix(camera1.combined);
shapeRenderer.begin(ShapeType.Filled);
map.drawEffects(camera1, shapeRenderer);
//(OTHER GAME STUFF AND EFFECTS...)
shapeRenderer.end();
Gdx.gl.glDisable(GL20.GL_BLEND);
fbo.end();
//NOW THE PROBLEM
Gdx.gl.glClearColor(0, 0.4f, 0.3f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glEnable(GL20.GL_BLEND);
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
fbo.getColorBufferTexture().bind();
focusShader.begin();
focusShader.setUniformi("u_texture", 0);
focusQuad.render(focusShader, GL20.GL_TRIANGLE_FAN, 0, 4);
focusShader.end();
【问题讨论】:
检查过你的帧缓冲中的内容了吗?尝试在 fbo.end() 之前获取 fbo 颜色纹理。这可能会有所帮助。如果其他一切正常。 感谢您的回复。我认为 FBO 具有正确的内容,因为在我绘制到 FBO 之前,我正在绘制到屏幕(并且它工作),并且,更重要的是,我可以使用SpriteBatch
(没有着色器),我可以看到它还不错(我没有尝试这么多,但缩放或视口仍然存在问题 - 一切都太大了 - 但我可以看到游戏正常运行)。
我查找了“createFullScreenQuad”代码,它创建了一个没有颜色属性的网格,但您使用的是顶点颜色。您是否修改了createFullScreenQuad
以使用颜色属性?深度测试不应该用于纯 2D 场景,除非您有不透明的精灵想要为您排序。另外,这个问题只在桌面还是安卓上?并非所有 android 设备都支持 RGBA8888。
谢谢,Tenfour04。这就是重点。我没有修改它。我现在可以看到现场了;它有一些意想不到的问题,因为在渲染循环内没有接触任何东西(原来的循环,现在在fbo.begin()
和fbo.end()
之间)现在我看不到正在渲染的灯光(我使用的是 Box2D 灯光;现在一切都是就像我没有灯时一样 - 一切都很明亮,原始颜色 - ),并且颜色缓冲区没有被正确清除。我在家时会详细说明答案,请随时将其发布为答案,以便我投票。
【参考方案1】:
您是否尝试过在 fbo.end 之前获取颜色纹理的参考。我不确定 fbo end 是否会自动处理它。
【讨论】:
鉴于我的最后一个答案,这不可能。结束 FBO 只不过是从渲染目标 AFAIK 中解除绑定,因此它不会处理它。另外,启用深度测试时我可以看到的“垃圾”与应该看到的内容有关(当我的播放器应该移动时它会改变或闪烁)。它一定是别的东西。以上是关于使用 OpenGL / LibGDX 的后处理问题 - 黑屏(FBO、着色器、四边形)的主要内容,如果未能解决你的问题,请参考以下文章
需要带有 FBO 扩展的 OpenGL 2.0 或更高版本 - LibGDX 错误