我需要创建一些shader,但是在水shader方面遇到了问题。我想创建一个使用两个重叠的法线贴图的。
虽然在编辑器里一切看上去都没有问题,但是当发布到webplayer的时候,场景看上去是没有光亮的。
在编辑器中看起来是这个样子的:
但是到了webplayer中,就成了这个样子:
我需要创建一些shader,但是在水shader方面遇到了问题。我想创建一个使用两个重叠的法线贴图的。
虽然在编辑器里一切看上去都没有问题,但是当发布到webplayer的时候,场景看上去是没有光亮的。
在编辑器中看起来是这个样子的:
但是到了webplayer中,就成了这个样子:
我用过的vscode和atom都有glsl语言着色与代码提示的插件,还挺好用。插件库搜一下就能找到。
本文将由来自英国的游戏开发工程师Alan Zucconi分享如何在Unity中使用着色器制作近来流行的精灵涂鸦效果。
精灵涂鸦效果在过去几年逐渐流行起来,《GoNNER》和《Baba is You》等游戏大量使用了这种美术效果。
本文将展示在无需绘制多个不同图像的情况下,如何实现精灵涂鸦效果。本文将介绍从Unity着色器编程的基础到所应用的数学原理等所有必要知识。
本文会涉及一些比较高级的话题,包括:反向运动学的数学原理和大气的瑞利散射效果。但是既对这些内容感兴趣,又有理解所需的必备技术知识的开发者其实并不多。
在游戏开发者Nick Kaman的一则推文中,他展示了如何在Unity实现涂鸦效果。
Nick Kaman:我想分享一个在Unity实现“涂鸦”效果的技巧:
我们不必绘制相同精灵的不同帧,我们可以把精灵放到网格,然后使用法线贴图偏移顶点即可,该法线贴图会每秒X次大幅进行滚动。
这篇推文获得大量的点赞和转发,我们发现,让即使没有着色器编程知识的人也可以理解的简单教程是很有必要的。
如果想要制作2D精灵动画的专业而高效的方法,并且需要完整的艺术级控制功能,你可以使用Doodle Studio 95!资源。
如果Sprites-Diffuse文件不是默认的精灵着色器,该怎么办?
两者的区别在于:前者是无光着色器,而后者会对场景的光线做出反应。由于Unity的实现方法,相对无光着色器,漫反射着色器可以更简单地进行编辑。
在Sprites-Diffuse.shader文件中,有一个称为vert的函数,它就是之前提到的顶点函数。它的名称并不重要,只要它符合#pragma指令的“vertex: ”部分内的名称即可。
简单来说,顶点函数会在3D模型的每个顶点调用,并决定如何在2D屏幕空间进行映射。对于本文而言,我们仅对理解如何替换对象感兴趣。
参数appdata_full v包含名为vertex的字段,该字段包含对象空间中每个顶点的3D位置,修改它的数值会移动顶点。
例如:下面的代码会使用该着色器把对象沿着X轴平移一个单位。
默认情况下,使用Unity制作的2D游戏仅处理X轴和Y轴,因此我们需要修改v.vertex.xy,从而在2D平面上移动精灵。
结构appdata_full的vertex字段包含着色器在对象空间处理的当前顶点位置,如果对象处于游戏世界的中心点即(0,0,0)坐标,它就是该对象未经过缩放和旋转时顶点的位置。
相对地,在世界空间表示的顶点会反映顶点在Unity场景内的实际位置。
为什么对象不会以每帧1米的速度移动?
如果对C#脚本的Update方法内transform.position的x部分加1,我们会看到对象以每帧1个单位速度飞行,换算的速度约为每小时216千米。
发生这种情况是因为C#对位置的改动会改变位置本身。在顶点函数中,这种情况不会发生,着色器仅会改变模型的视觉效果,但不会更新或改变模型上已保存的顶点,因此给v.vertex.x添加+1仅会每次移动对象1米的距离。
别忘了以Tight类型导入精灵。
该效果会替换精灵上的顶点。传统情况下,精灵会作为四边形(即下图左侧)导入Unity。这意味着精灵仅有4个顶点。如果是这样,只有这些顶点可以进行移动,从而会减少涂鸦效果的总体强度。
为了实现更为紧密和逼真的扭曲效果,我们应该确保精灵以Mesh Type设为Tight的情况进行导入,这样会把精灵包装为凸面外壳(即下图右侧)。
这样做会提高顶点的数量,虽然这不总是理想的选择,但却是我们所需要的。
涂鸦效果会随机改变每个顶点的位置。在着色器采样随机数字是一件需要技巧的事,这是由于GPU的无状态架构,它使模拟大多数库使用的相同算法变得更加困难和低效。
Nick Kaman提供的方法是使用噪声纹理,该纹理在采样时会得到随机的感觉。对我们的情况而言,这种方法可能不是最高效的方法,因为它会加倍着色器必须执行的纹理查询次数。
因此,许多着色器需要使用比较模糊和混乱的函数,即使它们的效果是确定的,而且在我们看来没有任何模式。
由于函数必须是无状态的,每个随机数必须通过其自带的种子代码来生成。这种方法的效果很好,因为每个顶点的位置都应该是独特的。我们可以使用它关联每个顶点的随机数,我们会在后面讨论这种随机函数的实现方法,现在我们把该函数称为random3。
我们可以使用random3函数生成每个顶点随机的替换效果。在下面例子中,随机数会通过_NoiseScale属性调整,这样可以控制替换效果的强度。
现在我们要编写random3函数的代码。
着色器中最常用和最具标志性的伪随机函数来自W.J.J. Rey在1998年发表的论文。
该函数是确定性的,也就是说它不是真正具有随机效果,但是它的行为非常不规律,使它看起来完全是随机的,这类函数被称为伪随机函数。对于本教程,我使用了Nikita Miropolskiy编写的高级函数。
通过使用已经编写好的代码,我们现在可以实现每个点都会在每帧替换相同的次数。这样会实现摇摆的精灵,而不是涂鸦效果。
为了解决该问题,我们需要找到随时间改变效果的方法,最简单的方法是使用顶点位置和当前时间来生成随机数。
在这种情况下,我们添加了以秒为单位的当前时间值_Time.y到顶点位置。
更高级的效果需要更复杂的方法来集成时间到计算方程式中,但由于我们只想实现间隔的随机效果,因此添加两个数值就足够了。
添加_Time.y的主要问题是:它会造成精灵在每帧都发生变化。这是不理想的效果,因为大多数手绘的动画都有较低的帧率。
时间组件不应该有连续的效果,而是应该变得离散化,这意味着如果我们想实现每秒5帧,它应该仅在每秒改变5次。使用熟悉术语的话说,那就是:时间应该“对齐”为一秒的五分之一。因此,可以使用的数值应该为:0/5 = 0,1/5 = 0.2,2/5 = 0.4,3/5 = 0.6,4/5 = 0.8,5/5 =
下面的函数会接收数值x,对齐到Snap值的整数倍数。
因此,我们可以更新为以下代码:
大功告成,最后的效果如下图所示。
如何使用Unity着色器实现精灵涂鸦效果为大家介绍到这里,喜欢自定义着色器的朋友们不妨一试。
下载Unity Connect APP,请点击此处。观看更多Unity官方精彩视频,请关注“Unity官方”B站账户。
扫码在“技术交流“群聊组中提问,Unity社区和官方团队帮你解答。
使用Unity制作起雾的窗户效果着色器
使用Shader Graph着色器视图制作交互式顶点特效
创作类《塞尔达传说:旷野之息》风格的水着色器
使用Shader Graph实现《塞尔达传说:旷野之息》风格的着色器
Unite Shanghai 2020正式启动, 暖冬特惠票热销中 ,购票即可获得多款Asset Store特定精品资源5折优惠码。[了解详情......] AR应用创作大赛Unity与商汤科技强强联手举办AR应用创作大赛,帮助开发者了解使用商汤AR SDK进行开发的方法,高效的进行AR内容创作,推进AR应用创新与落地。[了解详情...]
喜欢本文,点击“在看”
版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。