webgl--平面阴影效果

来源:互联网 发布:秦淮数据有限公司招聘 编辑:程序博客网 时间:2024/05/16 16:56

        在特定的3D场景中,阴影效果有时还是显得十分重要的,在一般的3D引擎当中设置阴影可以直接通过对物体设置属性来实现,十分的方便,这里我们就用webgl来实现一下平面效果。

        平面阴影是通过灯光将物体的阴影投射在一个平面内,但是物体之间没有阴影的叠加,也就是说A物体的阴影不会投射到B物体上,在本案例中我们主要是通过着色器来实现平面阴影的效果的,这里首先介绍一下平面阴影的计算公式:


V'=S+(V-S)(n·(A-S))/(n·(V-S))

上述公式中每一部分的含义如下。

V'代表沿光线投影到绘制阴影的平面上顶点的坐标。

S为光源的位置。

V为投影前顶点的实际位置。

n为法向量,其属于绘制阴影的平面。

A为任意一个点的坐标,其位于绘制阴影的平面上。

•代表向量的点积计算。

        下面介绍阴影的顶点着色器,其主要功能是根据有阴影的物体的位置和投影摄像机矩阵,通过平面阴影计算公式来计算阴影的位置和所在的平面。下面是顶点着色器的代码:

   uniform mat4 uMVPMatrix;              //总变换矩阵uniform mat4 uMMatrix;                 //变换矩阵uniform mat4 uMProjCameraMatrix;      //投影、摄像机组合矩阵uniform vec3 uLightLocation;            //光源位置uniform vec3 uCamera;              //摄像机位置attribute vec3 aPosition;                     //顶点位置void main(){      vec3 A=vec3(0.0,0.1,0.0);          //绘制阴影平面上任意一点的坐标      vec3 n=vec3(0.0,1.0,0.0);          //绘制阴影平面的法向量      vec3 S=uLightLocation;            //光源位置      vec3 V=(uMMatrix*vec4(aPosition,1)).xyz;        //经过平移和旋转变换后的点的坐标      vec3 VL=S+(V-S)*(dot(n,(A-S))/dot(n,(V-S)));//顶点沿光线投影到需要绘制阴影的平面上点的坐标      gl_Position = uMProjCameraMatrix*vec4(VL,1);     //根据组合矩阵计算此次绘制此顶点位置}


        片元着色器主要是对阴影的颜色进行赋值,所以顶点着色器不用给片元着色器传递任何参数,只需要一行代码即可。

precision mediump float;             //给出默认的浮点精度void main(){   gl_FragColor = vec4(0.2,0.2,0.2,1.0);        //片元最终颜色为阴影的颜色}

        最后放我自己踩的一个坑:当遇到如下图所示报错时一般是没有指定当前绘制使用的着色器,从而导致送入缓冲的数据不一致,最终导致错误。


        最后是演示图片与github:https://github.com/StringKun/WebGL-Shadow