【发布时间】:2015-07-30 02:32:10
【问题描述】:
所以我对一个矩形图像应用了水效果,这是我的水,以在其上应用正弦波函数。仅适用于此TextureRegion:
Water.java
public void updateshaders(){
float dt = Gdx.graphics.getDeltaTime();
if(waterShader != null){
time += dt ;
float angle = time * (2 * MathUtils.PI);
if (angle > (2 * MathUtils.PI))
angle -= (2 * MathUtils.PI);
Gdx.gl20.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.gl20.glEnable(GL20.GL_BLEND);
waterShader.setUniformMatrix("u_projTrans", gs.cam.combined);
waterShader.begin();
waterShader.setUniformf("timedelta", -angle);
waterShader.end();
}
}
@Override
public void draw(SpriteBatch g) {
g.end();
updateshaders();
g.setProjectionMatrix(gs.cam.combined);
g.setShader(waterShader);
g.begin();
g.draw(gs.gsm.rm.water_top, x, y + height - gs.gsm.rm.water_top.getRegionHeight(), width, gs.gsm.rm.water_top.getRegionHeight());
g.draw(gs.gsm.rm.water, x, y, width, height - gs.gsm.rm.water_top.getRegionHeight());
g.end();
g.setShader(null);
g.begin();
}
我想将此效果添加到红色矩形中的所有内容。我正在考虑刷新SpriteBatch 并切出该区域的图像,应用失真然后在原始图像上重新绘制它,然后完成我的渲染线程的其余部分。
更新: 所以我的解决方案奏效了……有点。它非常慢。它看起来是正确的,但会使游戏无法玩且速度慢。 (在 gif 中可能有点难以注意到,但在游戏中看起来不错。)
新代码:
Water.java
public void draw(SpriteBatch g) {
g.end();
updateshaders();
//Distortion
coords = gs.cam.project(new Vector3(x,y,0));
if(scr != null){scr.getTexture().dispose();}
scr = ScreenUtils.getFrameBufferTexture(
(int)coords.x,(int)coords.y,
(int)(width * scaleX),(int)((height - gs.gsm.rm.water_top.getRegionHeight() / 4) * scaleY));
if(scr != null){
g.setShader(waterShader2);
g.begin();
g.draw(scr,
x,y,
width,height- gs.gsm.rm.water_top.getRegionHeight() / 4);
g.end();
}
//SURFACE WAVES
g.setShader(waterShader);
g.begin();
g.draw(gs.gsm.rm.water_top, x, y + height - gs.gsm.rm.water_top.getRegionHeight(), width, gs.gsm.rm.water_top.getRegionHeight());
g.end();
//BACK TO NORMAL
g.setShader(null);
g.begin();
g.draw(gs.gsm.rm.water, x, y, width, height - gs.gsm.rm.water_top.getRegionHeight());
}
更新: 我尝试了 Tenfour04 的解决方案,它奏效了……有点。虽然存在失真效果,并且游戏以全 FPS 运行,但失真会使背景显示出来。这是因为着色器被应用于纹理,而不仅仅是在我抓取的区域范围内:
scr = new TextureRegion(((PlayGameState) gs).frameBuffer.getColorBufferTexture(),
(int)coords.x, (int)coords.y,
(int)(width * scaleX),(int)((height - gs.gsm.rm.water_top.getRegionHeight() / 4) * scaleY));
【问题讨论】: