【问题标题】:explosion shockwave effect on entire screen in libgdx with opengl shaders and framebuffers trouble with coordinates带有opengl着色器和帧缓冲区的libgdx中整个屏幕的爆炸冲击波效果坐标问题
【发布时间】:2016-11-04 18:56:05
【问题描述】:

我正在尝试为我的 2d 游戏中的爆炸实现冲击波效果 这些是我正在尝试的步骤 1)将所有东西绘制到帧缓冲区(纹理区域和网格) 2) 从帧缓冲区获取纹理并垂直翻转 3) 使用 http://empire-defense.crystalin.fr/blog/2d_shock_wave_texture_with_shader 中的着色器将生成的纹理绘制到屏幕上

这是我的渲染方法

    resultBuf.begin();
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    Gdx.gl20.glViewport(0, 0, resultBuf.getWidth(), resultBuf.getHeight());
    Gdx.gl20.glEnable(GL20.GL_TEXTURE_2D);

    batch.begin();
    renderbackground();
    batch.setProjectionMatrix(camera.combined);



    if(imageObjDraw){
        for(Integer type:imageObjects.keySet()){
            if(type!=ImageObject.mountains&&type!=ImageObject.steelbridge1&&type!=ImageObject.steelbridge2&&type!=ImageObject.steelbridge3)for(ImageObject o:imageObjects.get(type))if(o.isInSquare(camRec))o.draw(batch);
        }
    }
    batch.end();

    if (meshDraw) {
        //DRAWING MESHES
        shaderPassThrough.begin();
        Gdx.graphics.getGL20().glEnable(GL20.GL_BLEND);
        shaderPassThrough.setUniformMatrix("u_projTrans", camera.combined);
        shaderPassThrough.setUniformi("u_texture", 0);
        for(Integer key:meshes.keySet()){
            if(key!=MeshInfo.bridge){
                LinkedList<myMesh> mlist=meshes.get(key);
                Texture tex=meshTextures.get(key);
                if(tex!=null)tex.bind(0);
                for(myMesh m:mlist){
                    m.render();
                }
            }
        }
        shaderPassThrough.end();
    }

    batch.begin();
    if(drawObjEnable){
        drawObjects(batch);
        vehicle.drawState0(batch);
        drawParticles(batch);
    }

    if(particleDraw)PushTheLimits.animMan.render(batch);
    if(bulletEnable)BulletManager.render(batch);

    if(imageObjDraw){
        for(Integer type:imageObjects.keySet()){
            if(type==ImageObject.steelbridge1||type==ImageObject.steelbridge2||type==ImageObject.steelbridge3)for(ImageObject o:imageObjects.get(type))if(o.isInSquare(camRec))o.draw(batch);
        }
    }

    batch.end();

    if (meshDraw) {
        //DRAWING MESHES
        shaderPassThrough.begin();
        Gdx.graphics.getGL20().glEnable(GL20.GL_BLEND);
        shaderPassThrough.setUniformMatrix("u_projTrans", camera.combined);
        shaderPassThrough.setUniformi("u_texture", 0);
        for(Integer key:meshes.keySet()){
            if(key==MeshInfo.bridge){
                LinkedList<myMesh> mlist=meshes.get(key);
                Texture tex=meshTextures.get(key);
                if(tex!=null)tex.bind(0);
                for(myMesh m:mlist){
                    m.render();
                }
            }
        }
        shaderPassThrough.end();
    }

    resultBuf.end();

    batch.begin();
    batch.setShader(shaderWave);
    shaderWave.begin();
    shaderWave.setUniformMatrix("u_projTrans", camera.combined);
    shaderWave.setUniformi("sceneTex", 0);
    shaderWave.setUniformf("center", new Vector2((explCoorX-camera.position.x+camera.effectivewidth/2f)/camera.zoom/screenW,(explCoorY-camera.position.y+camera.effectiveheight/2f)/camera.zoom/screenH));
    shaderWave.setUniformf("time", waveElaps);
    shaderWave.setUniformf("shockParams", new Vector3(10.0f, 0.8f, 0.1f));
    resultTexReg.setRegion(resultBuf.getColorBufferTexture());
    resultTexReg.flip(false, true);
    resultTexReg.getTexture().bind();
    batch.draw(resultTexReg, camera.position.x-camera.effectivewidth/2f,camera.position.y-camera.effectiveheight/2f,camera.effectivewidth,camera.effectiveheight);
    batch.end();
    batch.setShader(null);

这里是着色器 片段着色器

 #ifdef GL_ES
precision highp float;
#endif
uniform sampler2D sceneTex; // 0
uniform vec2 center; // Mouse position
uniform float time; // effect elapsed time
uniform vec3 shockParams; // 10.0, 0.8, 0.1
varying vec2 v_texCoords;
varying vec2 proj;
void main() 
{ 
  float distance = distance(v_texCoords, center);
  if ( (distance <= (time + shockParams.z)) && (distance >= (time - shockParams.z)) ) {
    float diff = (distance - time); 
    float powDiff = 1.0 - pow(abs(diff*shockParams.x), shockParams.y); 
    float diffTime = diff  * powDiff; 
    vec2 diffUV = normalize(v_texCoords-center); 
    v_texCoords = v_texCoords + (diffUV * diffTime);
  }
  gl_FragColor = texture2D(sceneTex, v_texCoords);
}

顶点着色器

    attribute vec4 a_position;
attribute vec2 a_texCoord0;
uniform mat4 u_projTrans;
varying vec2 v_texCoords;
varying vec2 proj;
void main() {     
 //proj=u_projTrans.xy;
 v_texCoords = a_texCoord0;
 gl_Position =  u_projTrans * a_position; 
} 

关于定义问题 冲击波效果始终适用于屏幕坐标我的意思是我传递给片段着色器的中心变量 - 即 0,0 - 必须是我的 box2d 世界坐标的原点,但效果始终适用于屏幕的左下角,即使我移动相机到地图效果结束在屏幕的左下角,但我希望它在世界原点的屏幕左下角,即 0,0 我怀疑这个问题与我在相机的位置绘制生成的纹理有关,而且我在着色器中使用相机作为投影矩阵,但我对这个着色器主题和图形坐标不太了解,实际上我研究得很好,这似乎对我来说是正确的,但我现在看不到错误并且需要帮助 提前感谢,如果我没有把问题说得足够清楚,请发表评论,我会编辑并添加所需的信息,即使你可能想看一些屏幕截图?

【问题讨论】:

    标签: android opengl-es libgdx 2d-games


    【解决方案1】:

    片段着色器中名为“center”的制服未在世界坐标中指定。当您将渲染到纹理传输到屏幕时,它会在纹理坐标中指定。

    因此,无论您的世界相机在哪里,坐标 0,0 始终是屏幕的左下角,而 1,1 是右上角。

    为了给 vec2 'center' 传递一个合适的值,你必须将爆炸的坐标(或任何引起冲击波的因素)从你的世界空间坐标系转换到纹理空间。

    这样做的一种方法是将世界坐标乘以您的相机 WVP 矩阵 (camera.combined)。如果是透视相机,您可能需要将结果的 xy 除以 w。这应该为您提供从 -1,-1 到 1, 1 的剪辑空间坐标。然后您需要通过添加 1 和减半将这些坐标重新映射到纹理坐标。您可以在顶点着色器中执行此操作并将结果通过变量传递,或者您可以在 CPU 上执行此操作并将结果作为统一传递。

    【讨论】:

    • 感谢您的快速回复,我完全按照您所说的进行操作,现在可以使用,但不幸的是,现在只能在桌面上使用坐标没有问题,但是在爆炸过程中发生爆炸时,我只看到黑屏,我使用此代码当在应用冲击波效果时发生爆炸但没有爆炸时,我只从缓冲区绘制纹理,而不将着色器设置为批处理,只是使用默认着色器和相机组合绘制它有什么问题?我需要在 android manifest 中启用某些东西吗?并且 logcat 中没有错误,只有一个警告说 gl state 启用了无效的枚举..
    • 我在 windows 上使用 eclipse neon,我在 samsung galax s5 mini 和 general mobile gm 5 plus 上都试过了,我只看到黑屏
    • 一个重要通知:我开始着色器和结束着色器的位置不同,我在批量绘制纹理之前结束它,它在桌面上也变成黑屏,所以它可能与开始-结束顺序有关着色器和批处理也许这会有所帮助。你觉得这和这些有什么关系?
    • 对不起我的错误我说logcat很清楚但实际上有一个错误我错过了片段着色器未编译它给出了这个错误错误:0:14:'assign':l-value required "v_texCoords" (不能修改变量)然后我将通过变量传递的纹理坐标分配给局部变量 vec2 现在屏幕根本不是黑色而是棕色我看到它在挥动的效果,但颜色很奇怪
    • 好的,我的问题是精确我在片段着色器中使用 mediump 现在改为 highp 没关系我会将代码编辑为工作版本并在明天接受您的回答,谢谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-21
    • 1970-01-01
    相关资源
    最近更新 更多