OpenGL阴影贴图详解(2)

//Calculate texture matrix for projection
 //This matrix takes us from eye space to the light's clip space
 //It is postmultiplied by the inverse of the current view matrix when specifying texgen
 static MATRIX4X4 biasMatrix(0.5f, 0.0f, 0.0f, 0.0f,
         0.0f, 0.5f, 0.0f, 0.0f,
         0.0f, 0.0f, 0.5f, 0.0f,
         0.5f, 0.5f, 0.5f, 1.0f); //bias from [-1, 1] to [0, 1]
 shadowMatrix=biasMatrix*lightProjectionMatrixLeft*lightViewMatrixLeft;

所以顶点着色器可以这么写:

uniform mat4 viewMatrix,modelMatrix,normalMatrix;
uniform mat4 shadowLeftMatrix,shadowRightMatrix;

varying vec4 shadowVertLeft,shadowVertRight;
......
......

shadowVertLeft = shadowLeftMatrix * modelMatrix * gl_Vertex;
     shadowVertRight = shadowRightMatrix * modelMatrix * gl_Vertex;
 
  viewVertex = vec3(viewMatrix * modelMatrix * gl_Vertex);
     gl_Position = gl_ProjectionMatrix * viewMatrix * modelMatrix * gl_Vertex; 

然后在片段着色器当中将传入的shadowVertLeft和shadowVertRight都除以它们的w坐标值就能得到正常渲染的片元在阴影贴图坐标系内的坐标值了,之后把这个坐标值的深度(也就是z值)与阴影贴图内的深度值用shadow2D做比较,这边我偷了个懒,用shadow2DProj做,使用proj函数可以实现齐次除法,也就是顶点值除以w.

片段着色器这么写:

uniform sampler2DShadow texShadowLeft,texShadowRight;

varying vec4 shadowVertLeft,shadowVertRight;
......
......
 vec4 texcoordOffset = shadowVertLeft;
    if(texcoordOffset.x >= 0.0 && texcoordOffset.y >= 0.0 &&
      texcoordOffset.x <= 1.0 && texcoordOffset.y <= 1.0 ) {
     
  texcoordOffset.z+=bias;
     float depth = shadow2DProj(texShadowLeft, texcoordOffset).z;
     if(depth<1.0 && factor>=0.2)
   factor-= 0.1;
  if(factor<0.4)
   factor=0.4;
 }

片段的z坐标要加上一个偏移量,原因如图所示:

OpenGL阴影贴图详解

最后返回的factor值即为阴影值,把它与环境颜色相乘就能够输出片段了.

最终效果如下:

OpenGL阴影贴图详解

还能够在渲染阴影贴图的那一步使用着色器对深度纹理进行过滤产生半影区,这边我使用了pcf法对阴影进行处理.

OpenGL编程指南(原书第7版)中文扫描版PDF 下载

OpenGL 渲染篇

Ubuntu 13.04 安装 OpenGL

OpenGL三维球体数据生成与绘制【附源码】

Ubuntu下OpenGL编程基础解析

如何在Ubuntu使用eclipse for c++配置OpenGL

《OpenGL超级宝典》学习笔记

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/c45a4fb311b3f1025dc5048f3e86f9b7.html