OpenGL渲染管线之光照

材质

材质也即物体的光照属性,我们使用材质(Material)来模拟物体在真实光照环境下的光照表现。

#version 330 core
struct Material {
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
    float shininess;
}; 
uniform Material material;
  • ambient:环境光照下物体反射光颜色
  • diffuse:漫反射光照下物体反射光颜色
  • specular:镜面反射光照下物体反射光颜色
  • shininess:影响镜面高光的散射/半径
struct Light {
    vec3 position;
    vec3 ambient;
    vec3 diffuse;
    vec3 specular;
};
uniform Light light;

几种现实世界中的材质

 

三个组成部分的计算方法:

// 环境光
vec3 ambient = Light.ambient * Material.ambient;

// 漫反射, lightDir 是片元到光源的方向向量
float diff = max(dot(lightDir, Normal), 0.0);
vec3 diffuse = Light.diffuse * diff * Material.diffuse;

// 镜面反射, viewDir 是片元到摄像机的方向向量
// 计算反射光线时,入射光线是从光源到片元
vec3 reflectDir = reflect(-lightDir, Normal); 

// 幂次越大,坡越抖,也即反射的亮斑越小,镜面程度越高
float spec = pow(max(dot(reflectDir, viewDir),0.0), 32.0);
vec3 specular = Light.specular * spec * Material.specular;

// 累加三个部分即可
vec3 resultColor = ambient + diffuse + specular;

光照贴图

我们可以使用贴图来更加近似地模拟真实环境,同样为了更加容易区分出物体表面的漫反射以及镜面反射,我们可以使用漫反射贴图和镜面反射贴图来控制反射的颜色,同样对于某些自发光的物体,我么你还可以使用mission纹理来模拟自发光。 

上面是一张漫反射纹理,我们再获取对应坐标的位置后,使用纹理颜色替换材质颜色进行漫反射计算即可。

与漫反射贴图类似,我们可以将镜面反射纹理颜色乘到原来的镜面反射颜色部分。

投光物

顾名思义就是将光线投出去的东西,也即光源。

  1. 生活中所有的光源都是点光源,太阳就是无数的点光源组成的,因为距离很远,我们可以把太阳看成一个点光源。假设光源上两个点距离Dis,光源到物体距离R,那么这个两个点光源到该物体的夹角为Dis/R,由于R很大,所以夹角近似为0,可以认为从两个光源来的光线重合,也即可以认为是一个点光源。可以得出结论,当距离足够远时,可以把多个点光源看成一个点光源。
  2. 同样,当半径非常大时,圆上两个距离很近的点,这两个点之间的角度差(Dis/R)近似为0,也即圆心到这两点的直线夹角为0,也即不相交(以上都是近似)。可以得出结论,当距离足够远时,可以把点光源看成平行光源。
  3. 考虑到真实环境中的光线衰减(散射、折射、频率降低等等),我们可以使用线性函数近似莫斯这个过程,通过指定多项式的因子,来控制衰减速度变化,通常我们使用二次就足够了,公式:1.0 /(1.0 + a * D + b * D^2),D是到光源的距离,通过指定不同的a、b值,我们就可以模拟不用的衰减变化曲线。
  4. 经过遮挡物,遮挡物后的光线会被阻挡,我们使用聚光来模拟这种情况(类似手电筒),也即一个点光源加上限制的光源散射角度范围。一般情况下可投影的范围是个圆形,这时只需要比较片元到光源的方向是否在限制角度内即可,但是也存起可投影范围不是圆形的情况,例如方形,那么这个时候,可以控制模板测试?
  5. 但是真实情况手电筒并不是点光源,当距离比较近时,半影区会比较明显,这时可以使用近似方法模拟这种半影,例如半影区一次线性变化(角度or余弦值?)等等。

多光源

灵活利用之前提到的光源即可。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值