引言
Cocos游戏开发中的贴花效果
不知道小伙伴们有没有玩过CS
这款游戏呢?笔者能回忆到的是和小伙伴们在网吧连坐B41
、B51
对喷的画面。
在这款经典的FPS
游戏中,有一个比较有意思的系统,那就是喷漆(贴花、Decal
)系统。它就是一个能够在墙、地面等等地方进行涂鸦喷涂的功能。
言归正传,这样有趣有意思的功能,在我们游戏开发中是怎么实现的呢?
今天重点给大家介绍一下如何在Cocos游戏开发中实现贴花效果,感谢小伙伴们一直以来的支持阅读与分享。
本文源工程在文末获取,小伙伴们自行前往。
1. 实现贴花的方法有哪些?
贴花效果常用于游戏开发中的涂鸦、弹孔、纹身等等效果。
但与2D
游戏不同,在3D
游戏开发中,我们要实现3D
贴花需要考虑物体的深度和透视效果。
这意味着在实现时需要考虑顶点的位置、法线方向等因素。
下面是笔者想到的几种在3D
游戏中实现贴花效果的方法:
基于面片:我们可以把图片制作成一个面片,在游戏场景中将面片放置到指定坐标调整旋转即可,它的缺点就是仅支持一些平面例如墙、地板。
通过动态创建网格实现:我们可以利用射线和长方体去对模型的
Mesh
进行切割裁剪出来我们需要的Mesh
信息,然后把我们贴花的纹理映射上去,在通过utils.MeshUtils.createMesh
进行创建。通过Shader实现:我们可以利用深度图重建世界坐标的方式,来实现我们基于屏幕空间的贴花效果。
本文重点给介绍一下屏幕空间贴花效果。
2. 屏幕空间贴花
基于屏幕空间的贴花效果,比较巧妙,但需要一定的时间去理解。
它的原理是,利用一个长方体对象,与场景中的模型进行相交,然后把贴花的纹理影射到场景模型的表面。
我们需要在片元着色器中,利用深度图计算出屏幕空间坐标对应在世界空间中的位置,最后再转回到模型空间去,进行长方体裁剪和映射纹理。
有了解过渲染原理的小伙伴可以知道,我们正常的渲染流程大概如下:
模型空间中的顶点->通过变换矩阵M->世界空间->通过变换矩阵V->视图空间->通过变换矩阵P->裁剪空间->通过透视除法->NDC->通过屏幕映射->屏幕空间中的片元。
我们只要把上述过程反过来,就可以把屏幕空间的坐标转回模型坐标。
这里面的核心问题就是,如何通过深度图去重建世界坐标。
大家可以通过玉兔、Cocos、深度图、重建世界坐标、Shader、贴花、Decal等关键词进行搜索对核心原理涉及的内容先了解一下,会更容易理解贴花实现的原理。
3. 一起来实现贴花效果
1.资源准备
我们先去找美术妹子要一些贴花的纹理和简洁的场景,关键是凹凸不平的地面,比较好展示贴花的效果。
-
环境:CocosCreator
-
版本:3.8.2
2.构建Shader
首先我们复制一个builtin-unlit.effect
快速创建并自定义我们的Shader
。
然后在顶点着色器中添加一个v_screenPos
,把坐标传到片元着色器中去处理。
接着在片元着色器接收v_screenPos
,并根据以下片段进行处理:
其中depthTexture
就是我们的深度图,因为没办法直接在Shader中获取,我们需要额外操作一下在脚本中把深度图传入到Shader,这套流程比较繁琐。
3.深度图的获取
先把场景和我们进行贴花的长方体划分层级,分别为SCENE
和VIEWBOX
。
把主摄像机的可见性改成SCENE
和VIEWBOX
。
添加一张RenderTexture
用于接收摄像机渲染的深度图。
在主摄像机下添加一个子摄像机,可见性改成仅SCENE
并绑定RenderTexture
,其他参数保持与主摄像机一致。
最后编写一个简单的脚本,完成将深度图传入Shader。
添加脚本和材质。
4.注意事项
由于在Shader中没有直接获取cc_matWorld
的逆矩阵的方法,我们需要自己计算一下。
在深度图的学习中还会接触到线性深度与非线性深度,可以了解一下。
5.效果演示
这样我们就成功地将我们的贴花贴在不平的地面上啦。
由于效果不够直观,我们添加一个拖拽脚本和碰撞体,实现简单地拖拽。
这样我们的贴花就可以动起来啦。
各种各样的贴花。
结语
曾几何时,我们以为我们怀念的是只是那几个经典的游戏,后来我们才明白我们怀念的只不过是童年的自己,是与小伙伴们相处的那一段无忧无虑的时光,如今都已不在。
以上就是在Cocos游戏开发中实现贴花效果的全部介绍。
需要完整源码的小伙伴可下方链接或者通过阅读原文获取,付费只为正反馈,原创不易,感谢大家的支持。
往期回顾: