Così ho un effetto acqua applicata a un'immagine rettangolare che è la mia acqua per applicare una funzione d'onda peccato attraverso di esso. Si applica solo per questo TextureRegion
:LibGdx Esiste un modo per applicare lo shader a una sezione del batch sprite per un effetto acqua?
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();
}
voglio aggiungere questo effetto per tutto nel rettangolo rosso. Stavo pensando di lavaggio del SpriteBatch
e tagliando fuori l'immagine della regione, applicando la distorsione poi ridisegnare sopra l'originale, poi finire il resto del mio thread di rendering.
UPDATE: Così la mia soluzione ha funzionato ... sorta. È incredibilmente lento. Sembra corretto ma rende il gioco ingiocabile e lento. (potrebbe essere un po 'difficile da notare in gif, ma si guarda bene nel gioco.)
Nuovo codice:
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());
}
UPDATE: ho provato La soluzione di Tenfour04 e ha funzionato ... in qualche modo. Mentre c'è un effetto di distorsione e il gioco gira a pieno regime, la distorsione rende lo sfondo mostrato. Questo perché lo shader viene applicato alla struttura, non solo entro i confini della regione che afferro utilizzando:
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));
L'unica cosa è che ho dovuto ricollocare la matrice di proiezione sulla fotocamera prima che l'acqua venga pescata, inoltre ho dovuto prendere una regione della texture del frame buffer per raggiungere il mio obiettivo –
La vostra soluzione è stata eccezionale per la parte performance , ma come posso assicurarmi che lo shader sia applicato solo alla "TextureRegion" nella casella rossa? –
L'intera trama viene disegnata sullo schermo e quindi la classe dell'acqua ridisegna le regioni che richiedono l'effetto. Immaginavo che tu avessi già quel pezzo che lavorava con la texture delle dimensioni dello schermo che ricevevi da ScreenUtils. Non sei sicuro di come funziona la tua classe d'acqua a causa di tutte le variabili. – Tenfour04