OpenGLES入门笔记 :OpenGLES光照基础总结3 点光源的实现

背景

前两篇文章谈了光照的原理,本文记录了在了解了原理后调试代码的过程及遇到的一些问题和想法,实现主要参考了红宝书上点光源着色器的代码。

需求是这样的,我们现在要实现一个点光源,让这个点光源照亮天空盒的表面。实现效果如下图。

这里写图片描述

图中红色的小灯笼代表光源的位置,它可以照亮近处的天空盒,由于天空盒的是中间凸起的,所以近处天空盒的边缘是无法被照亮的。而远处天空盒的其他面也被照亮了。我们可以在天空盒空间中任意移动红色小灯笼(光源),实现对天空盒不同位置的照射。

原理

光照颜色的渲染

在实现过程中走了不少弯路,主要是由于没有理解片元着色器的工作原理。
如果要实现光照,我们必须找到当前要照亮面的法线。对于点光源来说仅有法线是不够的。点光源的光照强度是随着距离的增大而衰减的,所以,除了法线,我们还需要一个顶点来计算距离。

这里写图片描述

这里我是这样理解的。如上图,假设这是天空盒的一个面,我们用两个三角形来绘制这个面,在这6个顶点上绘制纹理。我们知道,此时只有一个平面,也就是说法线只有一条。但是我们有6个顶点,如果要计算每个顶点出的光照,我们可以直接把法线用在每个顶点上,这样,根据前两篇文章的知识,我们就可以计算出顶点的颜色,也就是图中标出的Color1,Color2,Color3,Color4四个颜色。

注意,这里是顶点的颜色,我们需要的是平面上的颜色来实现光照,那么这两个颜色有什么关系呢?Opengl会在三角形片元上对颜色进行线性插值,使其颜色可以实现平滑过渡。实验中得出的结论是此时我们并不需要关系每个中间照亮部分的颜色,只需要对三角形的顶点进行光照计算,最终得到的光照结果就是符合我们预期的光照效果。也就是说有了角上的光照颜色值,其余部分的色值直接由Opengl为我们生成即可。

光照方向的计算

光照方向的计算比较简单,根据理解,我们可以直接用光源点 - 物体顶点,得到的向量就是光向量。此处需要注意,我们必须同一这两个点的坐标系,否则也无法正确实现光照效果。
我们给gl_Position的顶点值是经过MVP变换后的,也就是说经过了投影变换,进行了归一化。而此处我们的光源点是手动指定的绝对坐标,所以物体顶点也应该使用透视前的坐标,所以,此时只需把物体顶点坐标经过MV变换即可

点光源衰减

据说点光源在实际中光强度是随着距离的平方衰减的,这也符合我们的生活经验,我们可以想象在漆黑的小屋子点一个蜡烛,蜡烛可以照亮周围墙壁,如果放到一个漆黑的大仓库中,那么周围依然会很黑,这就是光线的衰减,距离远了,光线变弱。所以,此时我们也需要对此进行模拟,否则每个屏面的光强度都是一样的,也无法呈现出点光源的效果。

float attentuation = 1.0/( uConstantAttenuation + uLinearAttenuation*lightDistance + uQuadraticAttenuation*lightDistance*lightDistance );

我们可以通过上述的式子,设置固定,线性,平方三个衰减系数,其中平方系数对距离最敏感。直观上讲,如果uQuadraticAttenuation值设置的越大,那么光源照到远处的能力就越弱。
最后的漫反射光我们就可以用如下代码表示:

vec3 scatteredLight = uAmbient + uLightColor * diffuse * attentuation;

上述三个问题就是我在调试过程中碰到的主要问题,明白了这些以后,我们就可以参照红宝书上的点光源着色器进行代码编写了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值