老实讲,这个需求是老板提的。

游戏嘛,很多东西都可以做,但是做不做往往不是做的人可以决定的。这个效果虽然没见过有游戏实现过(一般实现的都是无方向的边缘光),但是在一些2D动画里是有的——比如一款叫轮舞曲DUO!的游戏,在一些过场和战斗画面里面出现了很正确的光照效果,比如一盏灯从胸口平移过去可以看到非常合理的沟渠明暗变化过程。

刚看到的时候很惊艳,想想也就是明白了。在2D画面上加一个法线图不就好了,变形后的图像,法线虽然会有一定偏移,但大方向是正确的,并不容易暴露。

网络上也是可以搜索到相关的内容的,完整的解决方案还需要再加上一张深度图,让光照效果在Z轴上也能比较精确,不过这就算了吧。

所以实现这个并没有什么难度,难的是制作上的问题。搞来搞去,法线图最后只给了5种颜色,分别对应中间,左,右,上,下。所以基本上没法获得正确的光照效果,只能做到将物体的不同区域做出区分单独让光线生效,如果是平行光,各区域之间是完全没有过渡的,但如果用点光源,倒是可以靠衰减和角度体现出过渡来,勉强说的过去。

实现方式就是将2D物体看作是个布告板,然后加上法线图直接用和法线贴图一样的方式处理。

但这样的话,就需要一个正常的光照系统了。在不用SRP的情况下,Unity多光源的方式是多PASS,显然没这必要。顶点光照又不可能用在法线贴图上。普通的Forward shader里,因为是用于多PASS的,能取到光照数据并不完整。不过好在Unity还保留了最早的Vertex Lit用的光照,可以获得最近8个光源的数据。

unity_LightColor[] 灯光颜色

unity_LightPosition[] 灯光位置,用w可以区分平行光和顶点光

unity_LightAtten[] 点光源范围,衰减参数

unity_SpotDirection Spot的数据

要注意的是,这些数据都是在视图空间内的,而且需要把LightMode设置成Vertex才会生效。

而利用的方法在Unity自己的shader里已经提供了,照抄就好:

float3 toLight = unity_LightPosition[k].xyz - i.viewPosition * unity_LightPosition[k].w;
float lengthSq = dot(toLight, toLight);
lengthSq = max(lengthSq, 0.000001);
toLight *= rsqrt(lengthSq);float atten = 1.0 / (1.0 + lengthSq * unity_LightAtten[k].z);
//if (false) //spotLight
//{
//  float rho = max (0, dot(toLight, unity_SpotDirection[k].xyz));
//  float spotAtt = (rho - unity_LightAtten[k].x) * unity_LightAtten[k].y;
//  atten *= saturate(spotAtt);
//}
float diff = max (0, dot (viewN, toLight));
lightColor += unity_LightColor[k].rgb * (diff * atten);

同时处理了点光源和平行光,并用一个可选分支来支持Spot光,不需要支持可以删掉。

需要说明的是,这段代码本身是用在顶点上的,直接移动到frag上是可以,但就需要靠考虑下性能问题。这组光源事先按距离排序过,所以取前几个就行了,也可以中途用break提前退出(不存在的光源会被填充为0,0,0,0,unity_LightColor[k].a == 0就表示后面没数据了),不过我也不清楚用break有没有提升,虽然这种用法同warp肯定在同一分支不会有浪费,但毕竟会多一个break的成本,而且会阻碍循环展开。

由于都是用在较小的2D人物上,即使光源多也不需要做精确的光照裁剪,就不用考虑那些麻烦事了,但是大块物体比如墙体和路面绝对不能这样用。现阶段由于手机上还无法放弃不支持Compute Shader的设备,基本没啥合适的方案,目前的foward+的光照裁剪部分基本无法脱离Compute Shader(Compute Buffer也是其中一部分),传统的TBDR也不清楚和手机的硬件TBR有没有冲突。SRP我没认真看过,不清楚它的HD管线(传统TBDR实现)是否能脱离Compute Shader,但不管怎么说,那毕竟也是个延迟渲染,很麻烦的。不支持Compute Buffer恐怕是下一个阻碍手游画面提升的节点。

扯远了,反正现在这做法只能处理人物,场景是不能受光照影响的,性能上浪费太多。控制光源上限就能限制成本,一般单物体最多3个光也差不多够了。

法线数据直接采样就行了,毕竟是布告板。

严格来讲,应该根据UV方向旋转贴图,这样物体旋转的时候才不会有问题。但是因为当初没商量好,都是在单个部件模型上绘制的法线方向,然后打图集的时候部件会被旋转,而Shader取不到这个旋转信息,就无法还原。如果法线图是在打图集后,根据图集里的方向来绘制本来是没问题的。

不过旋转不常见,也就无所谓了,应用了旋转还可能出现预料之外的情况。但完整的方案应该是要旋转的,需要乘一个切线空间到视图空间的矩阵,和普通的法线贴图一样。

但依然需要乘一个物体空间到视图空间的矩阵。这里遇到了一个坑。按说这里直接用normalize(mul((float3x3)UNITY_MATRIX_IT_MV, norm))处理方向就好,但实际运行的时候会在特定位置和角度会出现频闪现象,我查了下UnityShader的源码,发现它所有转换角度的地方都是这样的

inline float3 UnityObjectToViewNormal( in float3 norm )
{#ifdef UNITY_ASSUME_UNIFORM_SCALINGreturn normalize(mul((float3x3)UNITY_MATRIX_IT_MV, norm));#elsereturn normalize(mul(norm, (float3x3)UNITY_MATRIX_MV));#endif
}

用了个宏来区分UNIFORM和非UNIFORM的情况,而且全走的下面那行,虽然我的模型确实是UNIFORM的。下面那行……看上去完全没有道理,所以我只能认为UNITY_MATRIX_MV被做了什么手脚,先不管它。

替换了之后就正确了。但实际运行的时候,在某些特定机型执行下面那条Shader会直接崩掉而且没有任何反馈,FallBack也无法捕获,表现出来的是整个面片大幅度随机扰动(一段写在frag的代码竟然能影响顶点你敢信?)

也没办法只能改回上面那行偶尔错误的代码。

我也不清楚这算是Unity还是设备的错,但输入再怎么错,设备也不应该让frag影响顶点吧?所以以下机型能不能主动去世?

OPPO R9s,华为 荣耀畅玩5X(KIW-AL10),vivo X9,华为 荣耀畅玩5A(CAM-AL00),OPPO A57,华为 米兰;麦芒5(MLA-AL10),三星 GALAXY A700(SM-A7000),小米 -(HM 4X),vivo Xplay5A,vivo X6SPlus D,乐视 乐Max 2(X820),努比亚 Z11 mini(NX529J),三星 GALAXY A7(SM-A7100),三星 GALAXY Note 4(SM-N9108V),三星 GALAXY Note 4(SM-N9109W),乐视 乐1 Pro(X800),三星 -(SM-G6100),中兴 新AXON天机(A2017),锤子 Smartisan T2(SM801),谷歌 hamu;XT1100,Moto Nexus 6(Nexus 6),三星 GALAXY Note 4(SM-N9106W),奇酷 Q5(1515-A01),vivo PD1516A(Xplay5S),努比亚 Z17 mini(NX569J),中兴 天机7 Max(C2017),酷派 锋尚N1S(5380CA),海信 A1 ivvi i3P-02(i3P-02),OPPO R9st,华为 Nova(CAZ-TL10),乐视 乐2(X528)

总得来讲,这个效果表现尚可。设计的时候是在夜间低亮度下使用的,但是高亮度下也不是一点效果都没有,只是效果差很多罢了。光照本来也就是这样的东西。

实现的时候用的都是Unity自己的东西,倒是挺简单的,不费啥工夫。主要的人力在于画法线图那边的人。但是图那么难的都画了,划分5个方向的朝面涂色也不算太麻烦吧。

如果量少,绘制更细致的法线就能获得更高的品质。不过要这样做的话,可能3D建模生成法才反而才是效率最高的做法。

厉害的人还可以考虑立绘或者CG绘制法线。讲真的,那个效果才是真的牛批。(不要找我要图,你觉得我能发吗?)


一句题外话,现在日式卡通的NPR的可参考例子太少了,其实真想做日式卡通的NPR,除了MMD,真有必要翻下日本那边的卡通渲染的3D动画,嗯,我指的就是那种。

游戏也有,也是那种的。

谁让日本游戏业不行了呢,他们也只能做这个了。

max unity 方向_在2D游戏中实现方向光照相关推荐

  1. 【个人UNITY笔记】{基础} 2D游戏中使用Shader或Camera解决Sprite前后遮挡关系

    因为个人制作的奇葩游戏2D游戏是用Sprite当作角色和物体,然而Unity里不应该使用带透视的相机来渲染Sprite,因为会2个Sprite距离太近会出现闪烁,但是我就是想保留透视,同时使用Spri ...

  2. [Unity学习笔记]2D游戏中的触碰/OnMouseDown

    [Unity学习笔记]2D游戏中的触碰/OnMouseDown 这种情况多用于2D游戏的触屏 1.给2D游戏对象加上collider 2D,让其能够被检测到

  3. 【中英双语】Unity:从零开始构建2D游戏

    [中英双语]Unity:从零开始构建2D游戏 通过制作 Unity 2D 游戏来学习 C# 编码 此教程共14.0小时,中英双语字幕,画质清晰无水印,源码附件全 课程英文名:Building 2D G ...

  4. unity3d 2D游戏中摄像机投影类型

    我们盘点一下unity3d 2D游戏中必备的几个元素. 摄像机:无论是3D游戏还是unity3d 2D游戏摄像机都是非常重要的属性,移动摄像机即可更改屏幕中显示的内容,游戏地图的坐标永远都不会发生改变 ...

  5. java2d游戏代码_Java 2d游戏中的“JUMP”

    我有这个代码,我想在java 2d游戏中启动一个跳转,事情是我的对象没有去任何地方,它只是停留在那里...我想我的对象跳,当我按下键和程序显示我的图像上下移动..我试图通过简单的repaint()方法 ...

  6. unity图片变成马赛克如何取像素并改变颜色_聊聊 2D 游戏的像素化中的问题

    来indienova官网,挖掘独立游戏的更多乐趣 引言 既然我是在做像素游戏,这次就聊一聊在对 2D 游戏像素化的过程中都会碰到的问题吧. 1. 照相机的投影 对于引擎来说,其实不管是 2D 游戏还是 ...

  7. Unity - 2D游戏中掉帧严重问题解决

    目的:解决unity2D中游戏掉帧严重问题 这个问题的出现一开始我并不知道什么原因,于是在unity-profiler中寻找答案. 一开始我发现这个问题 然后我在网站上搜索"Animator ...

  8. Unity3D 2D游戏中寻径算法的一些解决思路

    需求 unity3d的3d开发环境中,原生自带了Navigation的组件,可以很便捷快速的实现寻路功能.但是在原生的2d中并没有相同的功能. 现在国内很多手机游戏都有自动寻路的功能,或者游戏中存在一 ...

  9. Unity和Cocos2D在2D游戏开发上的对比

    游戏开发的最好技术是什么:Unity还是Cocos? 在网上你可以找到很多这两种技术的对比.在我们开发游戏之前,我们要了解相关数据和信息并决定使用那种技术.但是人们对这两种技术的对比大多都比较主观.擅 ...

最新文章

  1. JS~对img标签进行优化,使用onerror进行默认图像显示
  2. 【二分图最大匹配】【HDU2063】过山车
  3. 引用log4j.jar包后,出现告警
  4. 【机器学习算法专题(蓄力计划)】十、机器学习中必备的高等数学和线性代数基础
  5. 长度最小的子数组--滑动窗口
  6. React Native开发学习笔记——常用命令
  7. Android 5.1 API 22 所有sdk文件下载地址
  8. python实战项目前后端分离flask_Flask Vue 构建前后端分离的应用
  9. 矩形分割(洛谷P1324题题解,Java语言描述)
  10. linux yum imagemagick,CentOS7安装 ImageMagick
  11. c语言汉诺塔动画程序,汉诺塔问题算法(c语言控制台动画演示版)
  12. 网络编程项目——在线电子词典
  13. matlab的罗马数字怎么写好看图解,【我想知道1—100的罗马数字怎样写啊就是ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩⅪ这些等】作业帮...
  14. 图像算法学习 - 计算图像均方差(MES),峰值信噪比(PSNR)
  15. cad绘制正八边形_软件CAD | 各种“线”工具
  16. IDEA怎么开两个编辑窗口
  17. 樱花庄的宠物女孩AtCoder Grand Contest 015E - Mr.Aoki Incubator
  18. 图书借阅管理系统微信小程序的开发 报告+开题报告+PPT+SSM项目源码及数据库文件+演示视频
  19. 腾讯会议 for Mac(云视频会议软件)
  20. [JavaScript]多个表单中文件上传网址的获得的代码示例

热门文章

  1. axios 的简单使用
  2. 如何使用 backupninja 来备份 Debian 系统
  3. 【noi 2.6_2421】Exchange Rates(DP)
  4. AIX操作系统基本命令
  5. Linux内核空间-用户空间通信之debugfs
  6. 杭电ACM 2017
  7. [C++基础]037_编写不可被继承的类
  8. SQL Server2005还原数据库攻略
  9. 2021衢二中高考成绩查询入口,2021衢州市地区高考成绩排名查询,衢州市高考各高中成绩喜报榜单...
  10. 锯木棍(51Nod-2143)