yang131

导航

OpenGL之ShadowMap

流程:先创建一个RenderTexture,然后用灯光的视口渲染。

然后切换到正常相机,进行渲染,使用RenderTexture中的深度或者颜色纹理,然后还原当前顶点在灯光中的深度,两者对比,比缓存中的大,则为阴影,两个相等则可以直接光照计算。两者都可以不过有一些区别:

1.使用ColorTextureShader中需要使用Sampler2D,在灯光的视图中需要对深度进行编码,即颜色等于深度,当然有一个转换关系。 vec3  color = EncodeDepth(depthj);

2.使用DepthTexture,Shader中使用的是Smapler2DShadow,这里通过texture2DProj,获取到的是一个float的值,即深度值。当然DepthTexture需要做以下设置,特别是GL_Compare_MODE和GL_NEARST

   glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, w, h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LESS);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

 

切换到正常相机渲染的时候需要注意:

     如果你用的是BIAS矩阵,那么从刚才灯光生成的纹理中取值,需要的坐标是 B*P*V*M

     如果用的是Shadow Matrix,那么坐标值为: 坐标: S*P*V*M;

        其中ShadowMatrix的值,如下

0.5   0    0    0.5
0    0.5   0    0.5
0     0   0.5   0.5
0     0    0     1

 需要注意的是Shader中的Shadow2D在400版本已经不能使用了,只能用textureProj。

以上来自于自我总结,书中的例子也不是很完善,但是根据理论应该是这样子的,

 扩展:基于PCF的阴影或者柔化阴影,还有基于模板的阴影都有待探索。

          ---------------------------------《3D绘图程序设计  使用Direct3D和OpenGL》  (使用了gl_TextureMatrix,用的shader比较早)

          --------------------------------- 《OpenGL Shading Language 3rd Edith》  (提出ShadowMatrix理论,但是例子很糟糕)

          ----------------------------------《OpenGL Shading Language  4th Edith》  (例子不够完善)

 

posted on 2022-10-10 10:06  NoNight  阅读(96)  评论(0编辑  收藏  举报