2015-11-01 22 views
10

Sto lavorando su un platform con libGDX, Tiled Map e Box2D. Voglio applicare alcuni shader.coordinata shader libGDX e posizione della telecamera

Voglio un effetto vignetta che si attenga all'eroe. Per l'effetto vignetta, ho usato this tutorial. Il problema che ho riscontrato è: se la fotocamera è fissa, ottengo esattamente quello che voglio. La vignetta si attacca all'eroe. Ma se la telecamera si muove, cosa che accade in un gioco a piattaforme a scorrimento, l'effetto vignetta non si attacca all'eroe.

Here is a video that illustrates my problem

Sembra che devo prendere in considerazione la posizione della telecamera di calcolare le coordinate del effetto vignetta, ma non ho idea di come fare. Ecco lo shader frammento che uso per la vignetta:

varying vec4 v_color; 
varying vec2 v_texCoord0; 

uniform vec2 u_resolution; 
uniform float u_PosX, u_PosY; 
uniform sampler2D u_sampler2D; 

const float outerRadius = 10, innerRadius = 1, intensity = .5; 

void main(){ 
    vec4 color = texture2D(u_sampler2D, v_texCoord0) * v_color; 

    vec2 relativePosition = gl_FragCoord.xy/u_resolution - vec2(u_PosX, u_PosY); //Position of the vignette 
    relativePosition.x *= u_resolution.x/u_resolution.y; //The vignette is a circle 
    float len = length(relativePosition); 
    float vignette = smoothstep(outerRadius, innerRadius, len); 
    color.rgb = mix(color.rgb, color.rgb * vignette, intensity); 

    gl_FragColor = color; 
} 

Nella schermata di gioco, il codice di riferimento è:

public TestScreen(final MyGdxGame gam){  

    camera = new MyCamera(); 
    camera.setToOrtho(false, width, height); 
    camera.update(); 

    vertexShader = Gdx.files.internal("Shaders/vVignette.glsl").readString(); 
    fragmentShader = Gdx.files.internal("Shaders/fVignette.glsl").readString(); 
    shaderProgram = new ShaderProgram(vertexShader,fragmentShader); 

    shaderProgram.begin(); 
    shaderProgram.setUniformf("u_resolution", camera.viewportWidth, camera.viewportHeight); 
    shaderProgram.end();    
} 


public void render(float delta) { 
    Gdx.gl.glClearColor(0.1f,0.1f,0.1f,1); 
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); 
    camera.update(); 

    //calculation of the position of the effect depending on the position of the hero 
    posX = (Gdx.graphics.getWidth()/camera.viewportWidth) * hero.bodyHero.getPosition().x/camera.viewportWidth; 
    posY = (Gdx.graphics.getHeight()/camera.viewportHeight) * hero.bodyHero.getPosition().y/camera.viewportHeight; 

    shaderProgram.begin(); 
    shaderProgram.setUniformf("u_PosX", posX); 
    shaderProgram.setUniformf("u_PosY", posY); 
    shaderProgram.end(); 
} 

Come ho detto, questo codice funziona perfettamente se la fotocamera non lo fa mossa. Ma dal momento che non funziona quando la telecamera si muove, ho pensato che il problema era legato alla proiezione macchina fotografica e ho provato questo codice, senza successo meglio, nel render() :

Vector3 PosHero = new Vector3(); 
PosHero.set(hero.bodyHero.getPosition().x, hero.bodyHero.getPosition().y, 0); 
camera.unproject(PosHero); 

posX = (Gdx.graphics.getWidth()/camera.viewportWidth) * PosHero.x/camera.viewportWidth; 
posY = (Gdx.graphics.getHeight()/camera.viewportHeight) * PosHero.y/camera.viewportHeight; 

shaderProgram.begin(); 
shaderProgram.setUniformf("u_PosX", posX); 
shaderProgram.setUniformf("u_PosY", posY); 
shaderProgram.end(); 
+1

Non hai fornito abbastanza informazioni, dare un'occhiata a http://stackoverflow.com/help/how -to-ask e soprattutto http://stackoverflow.com/help/mcve. – Xoppa

risposta

6

OMG .. Ho avuto quasi 2 settimane di difficoltà e il mio problema è stato un semplice errore:

Il problema era, come pensavo, legato alla proiezione della telecamera. Nel codice che ho fornito alla fine del mio messaggio, ho usato camera.unproject(PosHero);, ma ho invece bisogno di usare camera.project(PosHero);!

Infine ecco il codice che uso per dare la giusta coordinate allo shader frammento:

Vector3 PosHero = new Vector3(); 
PosHero.set(hero.bodyHero.getPosition().x, hero.bodyHero.getPosition().y, 0); 
camera.project(PosHero); 

posX = PosHero.x/camera.viewportWidth; 
posY = PosHero.y/camera.viewportHeight; 

shaderProgram.begin(); 
shaderProgram.setUniformf("u_PosX", posX); 
shaderProgram.setUniformf("u_PosY", posY); 
shaderProgram.end(); 
+0

Beh ... un odio ha ridimensionato la mia domanda E la mia risposta, senza dare una spiegazione a questo comportamento vigliacco. – vdlmrc

+0

Normalmente, direi che era o perché volevano la tua taglia o perché si trattava di un semplice errore di battitura dell'utente - e quindi potrebbe essere considerato non utile per il sito (* perché se tutti avessero variazioni dei loro errori di battitura sarebbe difficile per trovare buone informazioni qui *), ma personalmente penso che con la quantità di codice e dettagli che hai postato va bene. Lo ignorerei. – DoubleDouble

Problemi correlati