设为首页收藏本站

微软Hololens全息现实网

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

一键登录:

查看: 816|回复: 1

巧用Shader,游戏玩法新思路

[复制链接]
发表于 2017-7-10 15:28:42 | 显示全部楼层 |阅读模式

今天为大家分享由学生组成的游戏开发小型团队,在为期5天的课堂Game Jam中使用Unity制作小游戏《Color Wars》的过程,以及其中使用着色器为游戏画面添加各种颜色的方法。他们制作的《Color Wars》是一款非常简单的2.5D多人对战游戏,玩家可以射击敌人,为敌人或者为场景加上颜色。游戏效果如下: ...

今天为大家分享由学生组成的游戏开发小型团队,在为期5天的课堂Game Jam中使用Unity制作小游戏《Color Wars》的过程,以及其中使用着色器为游戏画面添加各种颜色的方法。

他们制作的《Color Wars》是一款非常简单的2.5D多人对战游戏,玩家可以射击敌人,为敌人或者为场景加上颜色。游戏效果如下:

ab27ac991d45b5462a881f432428f79f.gif

图形部分所有游戏的特效魔法背后,都是最原始的3D模型、图片与人物精灵来组成整个场景。这些组成场景的元素都有其颜色及纹理。


b4ccc44b8bc24517d8f5ba16a05b318a.jpg

其中比较棘手的部分是需要在Alpha通道中屏蔽所有元素的颜色。换而言之,默认情况下,屏幕的整个Alpha通道都是黑色的,直到玩家开始喷射油漆,才会使被油漆溅到区域的Alpha通道变为白色。然后图像效果就是其原有颜色与灰度进行混合。 如下:

7db721af414ea95d7ce28069ec8fed31.jpg


fd93182ee0d5cfc0d757e97349610e3f.jpg

从上图可以看出,使用Projector将喷漆绘制到物体表面并创建颜色遮罩。每个Projector都使用程序化动态生成,在子弹(空中飞行的白点)接触到某个表面时进行初始化。Projector带有一个盒式碰撞体,当子弹落在Projector上时,不会初始化新的Projector,而是让原先的Projector变大。这样漆量会变多,而场景中的Projector数量却保持不变。 默认情况下,Unity标准着色器会为所有不透明对象的Alpha通道写入1。所以下面使用自定义着色器来替换Unity标准着色器。新建一个标准表面着色器,将其表面函数替换为如下:

0c5f44da7a7d0ad8bb19c8c0d4a8644b.jpg

下面这行很重要,用于避免Unity更改自定义的Alpha值。将#pragma那行代码改为如下:
3ec612642a7aa82b6af024a73684f06a.jpg

注意,该技巧不可用于Unity中的延迟渲染管线,因为它重写了G-Buffer中的Alpha通道来存储遮罩数据。 油漆喷射当子弹撞击某个表面时就会在撞击处动态生成Unity Projector。这些Projector带有自定义材质与自定义着色器。材质纹理是一张带有Alpha通道喷溅形状图,本文示例使用的纹理如下图:


d655b757a7e9bdc852c7e0e098e4d222.jpg


注意,纹理导入设置中要将Wrap Mode设为“Clamp”而非“Repeat”。用于Projector材质的着色器从Unity提供的ProjectorLight修改而来,代码如下:

45e830742cdfa4e15f8ed6ac57807054.jpg


ad824a1e427244175b5e52c6dc12023d.jpg


下面来介绍其中最为重要的混合部分。 混合原理当着色器计算某个像素的颜色时,该颜色必须作用于屏幕上该点已经存在的像素颜色之上。默认情况下,新的像素会完全覆盖原有像素,但新像素也可以与原有像素进行混合。混合通常用于让对象呈透明或半透明效果,当然也可以实现很多其它的炫酷特效。 关键字Blend可以包含在Subshader或Pass标签中,甚至对同一个着色器的不同Pass进行混合。添加Blend关键字后,必须写入混合因子。混合因子如下:

016261e2ee97623da1e9303d6ac9bbd6.jpg


Src指向着色器用于计算的颜色。Dst指向屏幕上已有的像素颜色。着色器用于计算的颜色会与第一个因子相乘,而屏幕上已有颜色会与第二个因子相乘。将两个结果相加,就是最终写到屏幕的颜色。 所以"Blend SrcAlpha One"会将自身Alpha值与当前着色器计算的颜色相乘,此时屏幕上的颜色暂未改动。然后再将屏幕颜色计算后的结果与前者相加。还可以使用逗号分隔两组因子,逗号前的混合选项用于计算颜色,逗号后的混合选项仅计算Alpha通道。可以查阅Unity文档了解更多关于混合的内容。 用于Projector的着色器就是“Blend Zero One, One One”,“Zero One”移除了飞溅纹理的颜色,使用子弹所飞溅到的表面颜色。“One One”将飞溅物的Alpha值与表面Alpha值相加。 现在使用上面的着色器与材质来生成Projector,应该将场景视图的Alpha通道设为白色。 颜色与灰度现在可以随意修改Alpha通道,但还未达到最终效果。下面利用Alpha遮罩来创建游戏所需的图像特效。 首先,创建要使用图像特效的着色器。在Unity中新建默认的Image Effect Shader,然后将片段代码替换为如下:

a9c33d52f9cd7d333d3ebb0d19401722.jpg


可以随意更改bnw(Black&White)变量以达到理想的混合效果。最后还需要新建脚本来运行该图像特效。脚本非常简单,代码如下:

c16e912107b86bb33ce327ec45dd3977.jpg


注意,这里用到了ImageEffectBase,该资源在Unity标准资源库中(Unity 5.5及以上版本推荐使用Post Processing Stack资源库代替ImageEffects)。导入标准资源库后,将脚本绑定到相机(确保将相机的渲染模式设为Forward)上,并将公共的着色器变量设为前面提到的着色器。 到此就可以向场景中喷射油漆啦! 已知限制本文提到的实现方式还存在一些限制,不一定适合所有的应用场景,但对于《Color War》这款游戏来说已足够。主要存在以下两点限制:采用Alpha遮罩就意味着没有Alpha通道,也不支持延迟渲染。这也许可以使用模板、命令缓冲区甚至多渲染目标来解决。项目使用的自定义着色器过多,这种做法并不推荐。如果您的项目可以使用延迟渲染解决其它问题,那么这个问题也就不存在了。 结语本文为大家分享了在Unity中利用着色器来实现喷绘效果的过程,文中的解决方法仅作为一种思路参考,不一定适用于所有项目。大家也可以按照项目的实际需求,来选取更加适合的解决方案。

论坛(HoloLens全息现实网): http://hololens8.cn

VR/AR/HoloLens开发者QQ群:220104582
VR/AR资源分享QQ群:281921834
HoloLens/VR/AR交流QQ群:433190386





上一篇:Unity教程 | 自制简易的游戏存档系统
下一篇:游戏开发中的AI (入门篇)
发表于 2017-7-10 16:05:26 | 显示全部楼层
值得期待。。。
*滑动验证:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

注册验证邮件查收提醒:

由于各大邮箱政策原因,

如果没收到邮件提醒,

您的注册验证邮件可能

被投送到您邮箱的垃圾箱,

请注意查收验证哦


QQ|小黑屋|Hololens全息现实网 ( 京ICP备15026232号   点击这里给我发消息

GMT+8, 2018-11-21 05:32 , Processed in 0.511541 second(s), 30 queries .

Powered by Hololens全息现实网 X3.2

© 2001-2017 Hololens全息现实网

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