代码改变世界

WebGL学习笔记(八):光照

2019-09-02 12:08 阿诚de窝 阅读(...) 评论(...) 编辑 收藏

局部光照与全局光照

局部光照

只考虑光源到模型表面的照射效果,运算量较小;

全局光照

考虑到环境中所有表面和光源相互作用的照射效果,即让没有直接受光照射的位置也会受周围反射光的影响,运算量较大;

Phong反射模型

Phong光照模型是真实图形学中提出的第一个有影响的光照明模型,该模型只考虑物体对直接光照的反射作用,认为环境光是常量,没有考虑物体之间相互的反射光,物体间的反射光只用环境光表示。Phong光照模型属于简单光照模型。

Phong光照模型是由环境反射、漫反射和镜面反射相互作用得到的光照效果。

环境反射

环境光,是没有方向的光,也不考虑观察者的视线方向,可以直接作用于模型的每一个点上,因为Phong反射模型是没有考虑物体之间相互的反射光的,所以使用环境光来简单的模拟一下物体之间相互的反射光;

漫反射

漫反射是模拟光照到粗糙的物体表面的效果,会考虑到光的射入方向,但是不考虑观察者的视线方向,垂直射入的光线会比斜着射入的光线更加的明亮;

点积的应用

对三角形面片的法线和漫反射的射入光线两个向量取点积,可以得到一个值(如果该值为0,表示两向量相互垂直),通过点积就可以确定当前面片的光照亮度。

镜面反射

镜面反射是模拟光照到光滑的物体表面的效果,会产生明亮的斑点或强光,除了需要考虑到光的射入方向也要考虑观察者的视线方向;

光泽度

光泽度也会影响到镜面反射的最终结果。

公式

ka为环境反射系数,kd为漫反射系数,ks为镜面反射系数,对所有特定光源求和,并有kd+ks=1。由上式看出,一旦反射光中三种分量的颜色以及它们的系数ka,kd和ks确定以后,从景物表面上某点达到观察者的反射光颜色就仅仅和光源入射角和视角有关。因此可以说,Phong光照模型实际上是纯几何模型。

如果有多个光线,则将每个光线的结果进行累加即可。

代码实现

有两种方式来实现,一种是光照代码写在顶点着色器中,还有一种是光照代码写在片段着色器中,下面我们分别看看两种方式的实现效果:

顶点着色器实现:https://hammerc.github.io/dou3d-ts/examples/learningNotes/lesson_6/index.html

片段着色器实现:https://hammerc.github.io/dou3d-ts/examples/learningNotes/lesson_7/index.html

通过上面的例子,可以看出来,由于顶点的数量较少,所以片段实现的光照更加的真实。

法线

我们程序中,为每个面指定了一个法线,在实际的使用中,一般来说是每个顶点都有一个法线;

法线可以使用叉乘来进行运算:

// 可以通过下面的代码获取法线, a 和 b 两个向量可以确定一个面,out即为该面的法线
glMatrix.vec3.cross(out, a, b)

法线一般在3D编辑器中输出模型时,就会存在了,一般不用再程序中运算;

光源的类型

常见的光源类型有下面3种:

点光源

一般是离模型较近的光源,向四周发射,比如室内的吊灯之类,我们上面代码中已经实现;

平行光

一般是离模型较远的光源,只有一个方向,比如太阳光;

示例:https://hammerc.github.io/dou3d-ts/examples/learningNotes/lesson_8/index.html

聚光灯

手电筒或汽车灯光之类的光源,锥形光源;

示例:https://hammerc.github.io/dou3d-ts/examples/learningNotes/lesson_9/index.html