ShadowMap无法使用着色器

时间:2017-02-06 18:59:10

标签: java opengl libgdx shader vertex-shader

我目前正在尝试创建一个游戏,您可以在LibGDX for Java中访问行星。要做到这一点,我使用TiledMap,它基本上只是一个瓦片数组来代表行星本身。为了获得必要的曲率,我使用着色器;它的工作原理是为每个顶点指定一个角度并根据摄像机位置放置它。它看起来像这样:

片段:

precision highp float;  

varying vec2 uv;
varying vec4 v_color;

uniform sampler2D u_texture;

void main() {
    vec4 color = texture2D(u_texture, uv) * v_color;
    gl_FragColor = color;
}

顶点:

attribute vec4 a_color;
attribute vec3 a_position;
attribute vec2 a_texCoord0;

uniform mat4 u_projTrans;
uniform float WORLD_WIDTH;
uniform float CAM_X;

varying vec2 uv;
varying vec4 v_color;

const float PI = 3.14159265;

void main() {
    uv = a_texCoord0;
    v_color = a_color;

    float radius = a_position.y;

    float angle = 2.0 * PI * ((a_position.x-CAM_X)/ WORLD_WIDTH);
    float camAngle = 2.0 * PI * (CAM_X / WORLD_WIDTH);

    vec3 newPos = vec3(a_position);
    newPos.x = CAM_X + cos(-angle + 0.5 * PI) * radius ;
    newPos.y = sin(-angle + 0.5 * PI) * radius;

    gl_Position =  u_projTrans * vec4(newPos, 1.0);
}

在没有任何其他内容的情况下应用此着色器如下所示:

我现在使用阴影贴图来照亮游戏。这是通过在纹理上绘制灰色阴影并在此之后在游戏玩法上拉伸纹理(特别是FrameBuffer)来完成的。没有任何着色器,它看起来像这样:

如果我现在不仅将着色器应用于平铺,而且还应用于阴影贴图,我会得到一个扭曲的阴影贴图:

我相信这是由于着色器使用顶点来实现曲率。阴影贴图只有四个顶点,实际上不能拉伸以实现曲率,而地图中的每个贴图都有四个顶点,这样可以产生很好的效果。我目前还不知道,曲率效果如何仍然可以实现,所以如果你有想法或其他一些建议让我知道,你不一定要发布任何代码,只是一般方法也会很好。

编辑:我现在尝试使用片段着色器:

这是我尝试用来渲染阴影贴图的片段着色器,结果是this。你可以看到它有一个基本的圆形形式,但有点扭曲(我知道问题出现的角度如何使用,但我不知道如何解决它)。这是在着色器中使用uv表示纹理的方式:http://i.imgur.com/pTQp8AJ.png

precision highp float;

uniform sampler2D u_texture;

uniform float TEXTURE_WIDTH;
uniform float TEXTURE_HEIGHT;
uniform float VIEWPORT_WIDTH;
uniform float VIEWPORT_HEIGHT;
uniform float CAM_X;
uniform float CAM_Y;

varying vec2 uv;
varying vec4 v_color;

void main() {

    // THE RATIO OF TEXTURE WIDTH TO TEXTURE_HEIGHT WHICH YOU MULTIPLY WITH UV.X TO NOT ALLOW STRETCHING
    // (LOOK AT HOW THE TEXTURE IS REPRESENTED TO UNDERSTAND)
    float k = TEXTURE_WIDTH / TEXTURE_HEIGHT;
    uv.x *= k;

    // THE CENTER OF THE PLANET RELATIVE TO TEXTURE_HEIGHT AS 1
    vec2 m;
    m.x = (k * VIEWPORT_WIDTH) / (2.0 * TEXTURE_WIDTH);
    m.y = - ((CAM_Y - 0.5 * VIEWPORT_HEIGHT) / TEXTURE_HEIGHT);

    // THE DISTANCE FROM CURRENT UV COORDINATE TO CENTER
    float d = distance(uv, m);

    // THE RANGE OF ANGLES
    float a = abs(atan(m.x/m.y)) * 2.0;

    // THE ANGLE OF THE CURRENT UV COORDINATE
    // + THE LEFTOFER ANGLE FROM HOW MUCH THE PLAYER HAS MOVED FROM THE CLOSEST INTEGER POSITION
    float angle = atan((uv.x - m.x)/(uv.y - m.y)) + (CAM_X - floor(CAM_X)) * (a / VIEWPORT_WIDTH);

    // ASIGN THE DISTANCE AND ANGLE TO ONE POINT IN THE TEXTURE
    uv.x = ((angle + 0.5 * a) / a)*(VIEWPORT_WIDTH / TEXTURE_WIDTH);
    uv.y = d + m.y;

    // GET THE COLOR OF THE TEXTURE AT THIS POINT
    vec4 color = texture2D(u_texture, uv) * v_color;
    gl_FragColor = color;
}

0 个答案:

没有答案