OpenGLES demo - 15. 阴影贴图 Shadow Map 之点光源

来源:互联网 发布:好看的恐怖电影知乎 编辑:程序博客网 时间:2024/05/14 22:45

原创文章,转载请注明链接 http://blog.csdn.net/hoytgm/article/details/38374687

这章只是上一章的扩展。上章讲了怎么实现一个平行光的阴影,这章我们稍微改动一下,就可以完成一个点光源的阴影。点光源和平行光所产生的阴影有什么不同呢?平行光的阴影宽度是不会变的,而点光源产生的阴影,离光源越远就越宽。

和上一章平行光所用的Shader不同,先看看点光源所用的Shader

    char* texture_vs =    "precision mediump float;\n"    "attribute vec4 aPosition;\n"    "uniform mat4 uMvp;\n"    "uniform mat4 uShadowMvp;\n"    "varying vec4 vTexCoord;\n"    "void main() {\n"    "    gl_Position = uMvp*aPosition;\n"    "    vTexCoord = uShadowMvp * aPosition;\n"    "}\n";        char* texture_fs =    "precision mediump float;\n"    "uniform sampler2D uTex;\n"    "varying vec4 vTexCoord;\n"    "void main() {\n"    "    if(texture2DProj(uTex, vTexCoord).r < 1.0)\n"    "        gl_FragColor = vec4(0.2, 0.2, 0.2, 1.0);\n"    "    else\n"    "        gl_FragColor = vec4(0.7, 0.7, 0.7, 1.0);\n"    "}\n";
Vertex Shader和上一章一样,但是在Fragment Shader中,对阴影贴图的采样没有使用传统的texture2D,而是用了texture2DProj。这是因为点光源使用的是透视投影矩阵,那么做了变换之后,x, y, z, w都会变换,所以要对w做除法操作,因此就需要使用texture2DProj来完成。


除了Shader有一些变化,投影矩阵就变成了透视投影矩阵,而不是上一章的正交投影矩阵

    gmMatrixRotateY(&model, angle);    gmMatrixLookAtLH(&view, &shadow_eye, &shadow_at, &shadow_up);    gmMatrixPerspectiveFovLH(&proj, GM_PI / 2.0, (float)SHADOW_WIDTH / (float)SHADOW_HEIGHT, NEAR_PLANE, FAR_PLANE);

然后运行程序看看效果



把灯光的位置往上提高,影子就变小了



其实还有个问题,有没有发现在影子的边上是有锯齿的,由于采样的精度,这个是阴影贴图固有的问题,有一个很简单解决方案,就是把阴影贴图的尺寸变大,把512的阴影贴图改成2048看看效果。


好多了吧?


代码地址 :http://download.csdn.net/detail/hoytgm/7727831

0 0
原创粉丝点击