当前课程知识点:移动图形概论 > 第六章 光源与光照 > 6.2 光源模型 > 光源模型
各位同学大家好
今天的主要通过模型高光的展示
来介绍两种不同着色器编程的方法
首先
我们来看一下高光的基本物理原理
高光是物体表面的镜面反射分量产生的高亮效果
它与光源的形状 位置 物体表面的性质
相机或眼睛所在的位置相关
当光源发出的光
通过物体表面的镜面反射进入到相机时
就可以在反射位置看到一个高光点
实际物体的镜面反射效果
有点类似于从入射点沿镜面反射方向的聚光灯模型
如果是纯粹的镜子
那么只有反射方向有光强
否则
光强可以认为按指数规律衰减
物体表面越光滑 衰减越快
高光面积越小 能量越集中
物体表面越粗糙 则能量越分散
最终成为纯散射光
可使用冯氏模型计算镜面反射光分量
在冯氏模型中
N是模型的法线向量
L是光源的方向
E是视线方向
一个需要计算的量是H
它是L与E之间夹角的平分矢量
一般称为半程向量
高光的反射强度就与N矢量和H矢量之间的夹角有关
高光的强度可以用N点乘H的指数来表示
公式中的s越大
光强的能量越集中
一般
s可以取20左右的值
这个示例代码是片段着色器中对光照情况的计算
lightDirection是归一化的光源方向矢量
由光源位置和片段坐标相减获得
注意这里使用的依然是视图坐标系
使用的坐标都是在顶点着色器中变换过来的
lightBrightness是漫反射的光强值
与上节课中的计算方法相同
高光用specularLight变量来记录
它只有在漫反射大于零的时候才有意义
计算过程中
首先
归一化摄像机方向eyeDirection
由于摄像机位于原点
因此
它就是片段对应的坐标矢量的反方向
然后计算半程向量
它的方向
就是光源方向与摄像机方向的和
NdotH
就是法线与半程向量的点乘结果
同样它不能取负值
所以用max函数保证其最小值为0
Specular是高光的光强
它用NdotH的幂来计算
幂指数是cShininess
这里取值为常数16
最后
specularLight的值为specular与四维单位矢量的的乘积
最终的片段颜色由两部分组成
一部分是纹理数据与lightBrightness的乘积
另外一部分就是刚才计算的specularLight
在上节课中的漫反射模型中
我们是在顶点着色器中计算漫反射强度的
而这里
我们是在片段着色器中进行计算
两种方式分别被称为
逐顶点照明和逐片段照明
或者说逐像素照明
逐顶点照明的优点是效率很高
因为我们只需计算模型中每个顶点的照明
然后将得出的照明结果在片段着色器中插值即可
例如
一个三角形将只执行3次照明计算
因为它只有三个顶点
逐顶点照明的主要缺点是
我们假定
由顶点组成的三角形的表面上
照明强度的变化是线性变化的
这可能会产生一些不太真实的照明效果
降低照明模型的品质
这是逐顶点照明的示例
可以看到这个球体高光附近比较明显的不和谐部分
可以看出其组成的三角形
虽然每个三角形内部色彩是均匀变化的
但边界上的显示效果就非常不自然了
逐片段照明不如逐顶点照明高效
因为我们要计算对象在屏幕空间中占用的每个片段的照明信息
此时顶点着色器仅用于执行
计算照明所需要的法线
和空间变换等其他照明相关的计算
并通过varying将计算结果发送到片段着色器
随后 这些计算结果将在整个三角形内进行插值
以获得对应片段的值
例如
如果在屏幕空间中绘制的三角形占用24个像素
则在使用逐片段照明时我们将执行24次照明计算
而不仅仅是逐顶点照明中
3次照明计算
逐片段照明的主要优点是
我们可以计算
屏幕空间中多边形表面上每个片段的照明强度
这样可以使照明模型的效果更加有效和自然
这是逐片段照明的示例
每个像素的颜色单独计算
结果更平滑
从这个示意图可以更直观看出
逐顶点照明与逐片段照明的区别
这里
AB是一个三角形的两个顶点
从图中可以看出A点不会有高光
B点甚至照射不到
如果是逐顶点照明
C点的光照强度
是A点和B点插值而来
也就不会有高光
而如果是逐片段照明
A点法线与B点的法线经过插值在C点符合高光条件
C点将产生高光的中心
高光的强度在C点周围也会随指数规律递减
这样效果会更加符合实际情况
这里把逐顶点照明与逐片段照明的对比
显示出来
后者的效果明显比前者要好太多了
好 今天的课程就到这里
谢谢大家
-1.1 课程基本情况介绍
--课程基本情况介绍
-1.2 GPU 相关基础知识
-1.3 OpenGL ES 技术发展历史
-1.4 PowerVR SDK 安装和使用
-第一章测试
-2.1 OpenGL ES 基本概念
-2.2 编写第一个图形程序
-2.3 主要 API 介绍
-第二章测试
-3.1 矢量和矩阵知识基础
-3.2 旋转与位移变换
--旋转与位移变换
-3.3 OpenGL ES 变换基础
-第三章测试
-4.1 着色器编程语言介绍
-4.2 着色器编程实例
--着色器编程实例
-第四章测试
-5.1 颜色的基本概念
--颜色的基本概念
-5.2 纹理素材的使用
--纹理素材的使用
-5.3 立方体纹理
--立方体纹理
-第五章测试
-6.1 光照的基本概念
--光照的基本概念
-6.2 光源模型
--光源模型
-6.3 使用着色器渲染颜色
-6.4 反射与折射
--反射与折射
-第六章测试
-7.1 基于物理渲染的基本概念
-7.2 基于图像的照明
--基于图像的照明
-7.3 PBR 的实现
--PBR 的实现
-第七章测试
-8.1 Vulkan 介绍
-8.2 SDK 中的实用工具介绍
-综合测试