基础就不记录了,只记录有关数学的东西
彩色光源
红绿蓝分量
环境光ambient
漫反射diffuse
镜面反射specular
环境光
表征场景中每一处的Ia都是相同的
点光源
理想的电光源向所有方面发射的光线强度都相等。
一个位于P0的点光源
点p从点光源接收到的光线强度(反比于光源到改点所在平面之间距离的平方)
仅利用点光源来照明往往会使场景的亮暗反差太大,可以看到,一些区域完全处于本影中,而另一些区域处于半影中。通过设置环境光,可以减弱由点光源照明引起的过高的对比度。
衰减因子实际应用中通常用形如
通过选择常数a,b,c的值来获得柔和的照明效果
聚光灯
限制点光源的发射光线来得到,如图,如果角度为180,就是点光源。
更逼真的是通过其发光强度在圆锥内的分布来描述,通常越接近圆锥中心,所发射光线的强度越大。通常定义为
指数e决定了随着角度增大而衰减的速度
指数的影响
计算技巧:两个单位向量的点积就是它们之间角度cos的值。
远距离光源
非常远。直接看作平行光源
用一个方向向量描述。
Phong反射模型
Phong反射模型用4个向量来计算表面上任一点p的颜色值。如果表面是曲面,那么这4个向量都随着表面上位置的不同而改变。
n:表面在p点处的发向量。
v:p指向观察者(cop)的向量。
l:p指向扩展光源上任意一点的向量。
r:沿着向量l的方向入射的光线按照反射定律的出射方向。
Phong反射模型考虑了光线和材质之间的三种相互作用:环境光反射、漫反射、镜面反射。
第i个光源的表示如下
rgb表示红绿蓝
ads表示环境光分量、漫反射光分量、镜面反射光分量。
代码表示:
vec3 light_i_ambient, light_i_diffuse, light_i_specular;
vec4 light_i_ambient, light_i_diffuse, light_i_specular;
每个颜色分量在改点的反射率。
对于第i个光源的漫反射光的红色分量Lird,可以计算出一个反射率Rird,于是前者对p点处光线强度的贡献为RirdLird。
Rird的值取决于材质属性、表面的方向、光源的方向以及光源与观察者之间的距离。
第i个光源对p点处的红色的光照强度。
p点处的红色的光照强度。
某点的光照强度
代码表示:
vec4 reflect_i_ambient, reflect_i_diffuse, reflect_i_specular;
环境光反射
前面说过-所有点处的环境光强度都是相同的。
被反射的部分又环境光反射系数Ka确定,此时:
一个表面有3个环境光反射系数Kar,Kag,Kab。并且这3个反射系数可以不相同。
漫反射
理想的漫反射表面粗糙,以至向各个方向反射的光线强度都相等。有时被称为Lambert表面,可以用Lambert定律来建模。
箭头方向为光线方向。
可见Rd应该和cosθ成正比。cosθ可以通过两个单位向量的点积来求。
法向量n和光源的方向l(参考前面的Phong模型)。
漫反射系数为Kd,如下公式很好推出
上面有一个问题,如果光源在水平面以下会取负值,此时希望取0
镜面反射
高光。
观察者看到的光线强度取决于理想反射器反射光线的方向r和观察者的方向v这两者之间的夹角。公式如下:
系数Ks大于等于0小于等于1,表示入射的镜面反射光中有多大一部分被反射。指数α是高光系数。
无限大的α对应于镜子,在100~500之间的α对应大多数金属的表面,小于100的对应于高光区域比较大的材质。下列公式中rv代表的意思参照Phong模型。
包含衰减因子的Phong模型可以用下列来表示
改进的Phong模型
和Phong模型相比多了一个h,h就是l和v的中间向量,并且是一个单位向量(全部都是单位向量,为了方便运算)。
把Ψ称为半角,h称为半角向量。
一个简单的证明可以得到2Ψ=Φ
如果把rv替换成nh,就无需计算r。半角Ψ比Φ小,为了减小对明暗绘制带来的影响,改变指数使之更接近rv的e次方。至于在什么情况下计算量会减少,这里先不解释了(先记录基础)。
这也被称为Blinn-Phong模型。
下列使用改进的Phong模型绘制的一组Utah茶壶
计算向量
基本数学知识,只写个大概
(1)法向量
1、不共线的三个点,它们分成2个向量的叉积确定法向量,注意叉积中的顺序确定方向。
2、梯度向量,高数那门课最开始的,对x、y、z求导。
3、参数形式,同样求导。
在OpenGL中,通常把法向量设置为顶点的属性
typedef normal vec4;
normal n = vec4(nx, ny, nz, 0.0);
反射角
下图字母代表的具体意思看前面的Phong模型,这里直接写推导。
αβ
r=αl+βn
nr=αln+β=ln
1=rr=α平方+2αβln+β平方
然后得到r=2(ln)n-1
我推了好久都没推出来。。。看图推得话很快就能推出来。
下面都只是简单介绍
递归生成球面
从一个四面体,取每条边中点,中点归一化,递归。
然后就出来个单位球了。拓展半径r的球很简单,归一化改成归r化。
注意逆时针方向朝外。
光源
代码如下,很好理解,前面说过很多了
color4 light_diffuse, light_specular, light_ambient;
point4 light_position = vec4(1.0, 2.0, 3.0, 1.0);
point4 light_position = vec4(1.0, 2.0, 3.0, 0.0);
float attenuation_constant, attenuation_linear, attenuation_quadratic;
\\其他光源通过设置相应项,可以把点光源转换到目的光源,前面已经解释过。
材质
color4 ambient = color4(0.2, 0.2, 0.2, 1.0);
color4 diffuse = color4(1.0, 0.8, 0.0, 1.0);
color4 specular = color4(1.0, 1.0, 1.0, 1.0);
float shininess;
color4 back_ambient, back_diffuse, back_specular;
color4 emission = color4(0.0, 0.3, 0.3, 1.0);
可以通过定义结构体或者类来定义材质
typedef struct materialStruct{
color4 ambient;
color4 diffuse;
color4 specular;
color4 emission;
float shininess;
}materialStruct;
currentMaterial = &brassMaterials;