找回密码
 立即注册
查看: 478|回复: 3

[笔记] OpenGL实现实时光照,阴影和体积光

[复制链接]
发表于 2021-12-7 14:15 | 显示全部楼层 |阅读模式
OpenGL不同于成熟的游戏引擎,作为一个图形接口。它是没有光照等一些基础特效的。(固定管线倒是有光照的接口,但是由于不能支持多光源,效果也很差。所以一般不会使用)。得益于可编程管线的强大能力。我们这些特效采用可编程管线实现。我们来先说光照。
光照主要有三个方面:环境光,漫反射,镜面反射。环境光很好理解,就是环境所散发出来的光,在基于物理的渲染方法里环境光应该会有一套复杂的公式去计算。而普通的方法就是把材质本身的颜色和环境光rgb值简单相加即可。有点类似于"自发光"。如下图。


一个黑色的球简单加上环境光。shader代码为
gl_FragColor = ambientColor * ambientMaterial;计算漫反射需要的东西就更多了。当前点的法向量与光线求夹角。如果夹角小于90°便不添加光照。夹角越大受到的光照强度越大。如图。


很容易理解不是么。
镜面反射增加了一个眼睛的概念。光线经过反射到眼睛的效果。具体体现为一个亮光斑。


而glsl里reflect可能耗费性能。所以可以采用blinn-phong光照模型。Blinn-Phong模型与Phong模型的区别是,把dot(V,R)换成了dot(N,H),其中H为半角向量,位于法线N和光线L的角平分线方向。Blinn-Phong模型可表示为:
Ispecular = Ks*Is* pow(( dot(N,H), n )


总的来说效果差不多。这让我愈发感受到图形学就是一个字 "骗"。只要骗得了人它就是真实图形(这个骗字在我之前的文章里也总是提到)。

第二部分我们提到的是阴影。阴影的实现在OpenGL中主要是使用shadow mapping方法。具体概念我就不解释了。简单的说就是把光源位置设置一个相机。然后相机显示的视角存到深度缓存中。然后渲染正常模型并且计算深度缓存和实际模型的深度值 如果某个点深度值大于深度缓存里对应的值。那就显示阴影反之则显示正常的亮面。如图。



shadow map



阴影效果

这里有个需要注意的点是计算的时候需要减去一个bias值 否则会出现阴影计算不准的情况。
而这个值太大正常的阴影可能受影响。太小可能毫无作用。具体的值还是要经过自己调整。



无bias的情况

第三部分我们来讲体积光。
游戏中,遮光物体被光源照射时,在其周围呈现的光的放射性泄露,称其为体积光。例如太阳照到树上,会从树叶的缝隙中透过形成光柱。之所以称之为体积光,是因为这种特效下的光照相比以往游戏中的光照给人视觉上以空间的感觉。体积光让游戏玩家更真实的感觉。有时也指实现这一特效的技术。丁达尔效应也能产生体积光的效果。



地平线零之曙光的体积光效果

我参考的是GPU GEMS3的效果。而那本书上给出了个公式。用了那个公式获得一张纹理与真实目标混合就可以产生以假乱真的体积光效果。具体原因我也不知道。这可能是码农和计算机科学家的差别吧。计算机科学家创造出一些先进的概念。而程序员采用一些方法去实现。同时也感概gpu gems的先进之处。要知道那本书是2000年左右的书籍。而现在你想实现3A游戏的效果还是大部分参照那本书上的效果。





甚至还有HDR效果



另一个角度

其实说到这已经说了不少了。而我这篇文章只是阐述大体思路。具体实现大家还是去看对应的论文才能理解。如果大家想要源代码请私信我。
接下来我想要制作一个自己的游戏。由于熟悉OpenGL才深知不可能用这种低级的api去写。我准备用unity这种东西去实现自己的思路,有了OpenGL的知识。用起unity才能事半功倍(我设想是类似于风之旅人的游戏,但是美术是我的薄弱点,慢慢来吧)。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
发表于 2021-12-7 14:18 | 显示全部楼层
固定管线应该最多能支持八个光源。最近接手的工作里,就是用的固定管线,用的是OpenSceneGraph,光照和阴影搞的我,参数很难调啊。
发表于 2021-12-7 14:19 | 显示全部楼层
把光写在管线里绝对是走了弯路
发表于 2021-12-7 14:26 | 显示全部楼层
OpenSceneGraph是2000年的库了,感觉对现代OpenGL适配不够,也有我太弱的原因。写点简单的需求还好,写到阴影这,真的头疼。
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-5-11 03:55 , Processed in 0.238339 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表