Cocos Creator 探照灯效果 Shader 实现
Editor's Note
很多游戏效果通过简单的 Shader 实现往往能达到事半功倍的效果,尤其对 2D 游戏来说,GPU 资源也有很大的利用空间,同时引擎也为开发者提供了方便自由定制的材质系统。——Cocos 刘航
The following article is from 代码与画家 Author ituuz
前言
探照灯实现
光照原理
着色器实现
下面是着色器的实现过程,不是完整代码,只有代码片段,熟悉 GLSL 语言的同学应该可以看懂,不了解的同学可以直接到文末获取完整代码再回头过来学习亦可。
首先是光照范围逻辑,根据两点距离和光照中心点来判断是否在光照范围内,光照范围内的点为目标颜色,范围外的点则设置成黑色:
运行效果:
此时一个大体的光照范围效果就有了,但是不太自然,光照的边缘没有过渡,并且有锯齿存在,下面我们通过插值来把光照的边缘增加过渡效果:
smoothstep 函数接收三个参数,第一个是范围的最小值,第二个是范围的最大值,第三个参数是需要计算的目标值 x,x 小于最小值则返回 0,大于最大值返回 1,其余返回 0 到 1 的插值。上面代码里的范围是光照半径及半径加 0.1 的范围内进行插值来实现光线边缘的过渡效果。修改完再看,效果已经不错了。
最后我们通过代码来设置 light_center 参数就能实现光源的移动了:
细心的朋友可能发现,如果你的场景或者目标图片不是正方形,那么光照的范围可能就不是个正圆了,而是一个椭圆。
这是因为 OpenGL 中的坐标范围是从 -1 到 1,但宽高长度并不一定是等比的。所以我们在计算圆的范围时,可以把场景或者图片的宽高比传入进来,然后计算圆范围时进行修正就可以了。
进一步优化
漫反射环境光
大家知道,无论我们在多么漆黑的屋子里,总是能隐约看见物体轮廓的,这就是因为有漫反射的环境光造成的。
物体表面都不是光滑的,都是凹凸不平的,总会把光源的光线,反射到各个方向,其它物体接收到反射光后会再次反射,反复循环,这就是漫反射,我们也叫环境光。
这就是为什么我们在没有光源的屋子里也能看见东西的原因,漫反射原理如下图:
这时运行效果就和教程开头的效果基本一样了。
光照强度和光源颜色
前面的实现过程中,我们对在光照范围内的目标颜色没有干预,保证了目标的固有色。
但有时我们也需要改变一些,比如上面讲到了环境光,没有光照的地方并不是漆黑一片了,那么反过来,有光照的地方就一定是亮的吗?有时我们也需要调整一下光照的亮度和光照的颜色。
先看光照的亮度,这个比较简单,逻辑和环境光强度一样,我们再定义一个光源强度的参数就可以了:
我们将光照部分和参与插值运算的光照边缘过渡部分都乘上光照强度,就可以实现我们的目标效果了。
不过这里需要注意的一个问题是,光照强度 result 如果小于环境光强度 ambient_strength 会是什么效果呢?大家可以试一下,并尝试修改。
接下来增加光源颜色的支持。根据教程开头讲的光照原理,我们可以直接把之前我们例子中的目标颜色乘以一个光源颜色就可以了,光源颜色我们就用上面说过的红光:
运行效果如下:
完整代码:
https://github.com/yue19870813/cocos_demo/tree/master/CocosDemo_2_3_3/assets/case/searchlight
以上是由 Cocos 开发者 ituuz 分享的优质技术教程,此文同时参加了 Cocos 中文社区征稿活动,入选优秀稿件。欢迎各位开发者点击【阅读原文】查看原文,为作者点赞,与作者进行交流学习!
如果您在使用 Cocos 引擎的过程中,获得了独到的开发心得、见解或是方法,并且乐于分享出来,帮助更多开发者解决技术问题,加速游戏开发效率,期待您与我们联系!