写在前面

最近又开心又担心,因为我的书马上就要上市了,开心当然是因为等了这么久终于可以如愿了,担心是因为不少人对它的期待都很大,我第一次写书,能力也有限,不知道能不能让大家满意,让大家也都喜欢上它。不过有不少朋友和前辈鼓励我,还是很开心滴~

之前有一些朋友觉得这次封面很漂亮,问我书的封面是不是我渲染的,以及怎么渲染的:

其实这封面并不是在Unity里渲染的,是男朋友在C4D里面渲染的。我特别喜欢他上学时候的一次作品(有机会放个视频哈哈),就是这种low polygon的风格,所以当时想要设计书的封面的时候就想要用这个素材。构图是我们讨论后的结果,我特意要他把Unity的Logo放到旗帜上面,然后让画面中间的男孩停在走进屋子的位置上,以此来寓意“入门”。之后就发给一些朋友看,问他们觉得怎么样,会不会太粉嫩、女生化?大家反馈说,这样放在书架上会很显眼,让人有想看的欲望,还有一些人说挺好的,不少游戏都这种风格,不过大部分技术人员说无所谓……技术书内容好就行~Anyway,之后发给了编辑,经过出版社美编同学的一些修改后就成了现在这个样子,希望大家还满意 :)

说到游戏里面low polygon风格的渲染,一直都是一种很有特色的渲染。因为男朋友是设计师,所以他总会拿一些美图来熏陶我,我每次看到这种风格的就会想多看几眼,大概是因为我还没度过小女生的年纪吧……例如下面这张(更多这种风格的设计图案可以参见这个网站):

Low polygon风格其实是一种复古风格,在早期的不支持插值渲染的年代,这种风格随处可见,因为模型简单、渲染也不复杂,在早期游戏中被大量使用。

回到技术上来,那么这种low polygon风格在游戏里怎么渲染呢?

原理

Low polygon风格的渲染也被称为flat shading。虽然把这篇文章归到Shader类别里,但其实是完全可以用非Shader的方法来解决的。下面两张图片,左边是我们不希望得到的结果,而右边是我们想要得到的效果。

做美术的同学都知道上面模型的区别就是“硬边”和“软边”的问题。左图里就是软边的效果,软边意味着相邻三角形之间共用顶点,这些被共用顶点的法线(蓝线)通常是根据毗连三角形的面法线加权平均计算得到的,如下图所示(图片来源):

由于共用顶点的存在,光栅化阶段的插值使得这些三角面片中间每个点的点法线都是有三个顶点的法线插值得到的,而这三个法线各不相同, 使得面片有平滑过渡的效果,从而形成软边。在其他风格的渲染中,模型大多都会使用软边,这不仅可以减少顶点数目提高性能,还能让渲染效果更加平滑。

但flat shading显然不想要平滑的渲染效果,我们希望就算光栅化插值后同一个三角面片中每个点的法线都应该是相同的(都等于面法线),只有这样它们光照计算的结果才会是相同的。如下图所示(图片来源):

要实现这样的效果就是把所有相连的边在建模软件中设置成硬边,Hard Edge。这样软件背后就会进行拆顶点的工作,每个三角形有各自属于自己的三个顶点,不与他人共用,这三个顶点的点法线计算不会受毗连三角形的影响,而仅仅是由该三角面片的面法线决定。

因此,我们有了解决方案一:在建模软件中把边设置成硬边

直接使用Unity

值得高兴的是,就算你在建模软件里忘记了设置硬边,Unity也是可以直接帮我们做到软硬边的转换的。它的原理其实就是重新拆点、重新计算点法线。

在我们导入一个模型后,可以在模型的导入面板中的Normals & Tangents块中,把Normals设置成Calculate模式、把Smoothing Angle设置成0就可以得到硬边的效果。如上图所示。

这样的模型可以直接使用任何普通的Shader进行渲染,就会得到flat shading的效果。

程序产生的网格

之前群里有人问程序产生的网格怎么实现这种效果。原理也是一样的,我们只需要保证不要共用顶点、正确计算顶点法线即可。在我的NPR项目里,有这样一个例子,把任何模型强制转化成没有共用顶点的模型。其中关键代码是长这个样子的:

Vector3[] oldVerts = mesh.vertices;
Vector4[] oldTangents = mesh.tangents;
Vector2[] oldUVs = mesh.uv;
int[] triangles = mesh.triangles;
Vector3[] newVerts = new Vector3[triangles.Length];
Vector4[] newTangents = new Vector4[triangles.Length];
Vector2[] newUVs = new Vector2[triangles.Length];
for (int i = 0; i < triangles.Length; i++) {newVerts[i] = oldVerts[triangles[i]];newTangents[i] = oldTangents[triangles[i]];newUVs[i] = oldUVs[triangles[i]];triangles[i] = i;
}
mesh.vertices = newVerts;
mesh.tangents = newTangents;
mesh.triangles = triangles;
mesh.uv = newUVs;
mesh.RecalculateBounds();
mesh.RecalculateNormals();

因此,如果你是通过程序方法产生网格的,可以使用类似上面的代码来进行网格转换,再使用普通的Shader即可。

更复杂的方法:Geometry Shader

上面转化硬边的方法会增加顶点数目,有一种完全不需要对网格进行任何处理的方法就是使用Geometry Shader。这种方法的原理就是在光栅化前、在Geometry Shader里给每个顶点增加一个属性,面法线faceNormal。由于Geometry Shader中可以知道同一个三角面片中的所有三个顶点的信息,因此我们可以为它们计算一个相同的面法线值。这样,即便在经过光栅化插值后,同一个三角面片中的面法线也是一样的。关键代码如下:

[maxvertexcount(3)]
void geom(triangle v2g IN[3], inout TriangleStream<g2f> triStream) {float3 A = IN[1].worldPos.xyz - IN[0].worldPos.xyz;float3 B = IN[2].worldPos.xyz - IN[0].worldPos.xyz;float3 fn = normalize(cross(A, B));g2f o;o.pos = IN[0].pos;o.uv = IN[0].uv;o.worldPos = IN[0].worldPos;o.faceNormal = fn;triStream.Append(o);o.pos = IN[1].pos;o.uv = IN[1].uv;o.worldPos = IN[1].worldPos;o.faceNormal = fn;triStream.Append(o);o.pos = IN[2].pos;o.uv = IN[2].uv;o.worldPos = IN[2].worldPos;o.faceNormal = fn;triStream.Append(o);
}

这种方法有点小题大做,因为geometry shader是SM 4.0中的特性,移动终端大多达不到这样的要求。

写在最后

如果大家真的想做low polygon风格的游戏,可以考虑一个插件PolyWorld,看着很不错的样子。

最后,希望大家喜欢《Unity Shader入门精要》这本书(源码下载),任何问题欢迎联系我的邮箱(lelefeng1992 # gmail DOT com)或在Github上发issue。再次感谢大家的支持 :)

参考链接:

  • http://gamedevelopment.tutsplus.com/tutorials/go-beyond-retro-pixel-art-with-flat-shaded-3d-in-unity–gamedev-12259
  • http://answers.unity3d.com/questions/798510/flat-shading.html

【Unity Shader】新书封面 — Low Polygon风格的渲染相关推荐

  1. Unity Asset Store精品Low Poly风格素材资源合集

    本文介绍Unity Asset Store里优质的Low Poly风格素材,会从人物.环境.动物和通用四个方面的素材分别进行介绍. 一:人物素材 本部分包含幻想类.城市类和Q版人物素材三个子类别. O ...

  2. Unity Shader PostProcessing - 5 - PixelSyle 像素化风格

    我的童年乐趣,基本上,都是花在:小霸王游戏机.红白机.街机里,很多那种像素化的游戏. 今天在研究别的东西时,看到一些像素化的游戏,有想起,之前想要试试这个后处理效果的.今天就试试吧. 先上个图,下图是 ...

  3. Unity shader的StencilTest、ZTest与半透明渲染

    着色器完成顶点编程和片元编程操作之后得到的颜色值,最后像素能不能够渲染出来还要经过最后一步逐片元操作,其中包括模板测试,深度测试等,只有通过了测试的像素点颜色才有资格进入颜色缓冲进行覆盖写入或者与已有 ...

  4. Unity Shader入门精要学习笔记 - 第14章非真实感渲染

    转载自 冯乐乐的 <Unity Shader 入门精要> 尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感渲染的一个 ...

  5. unity shader 后处理实现水墨风格渲染「Low Poly 」变「水墨画 」

    #水墨风格渲染 这次学校的比赛打算做一个中国古代背景的游戏,所以尝试做了水墨风格的渲染. 主要按以下四步来实现的效果: 根据色调和饱和度调整饱和度. 对图像进行模糊 水墨风格的物体边缘 物体内画笔笔触 ...

  6. Unity Shader 学习笔记(27)渲染轮廓线(描边)方法、卡通风格渲染、素描风格渲染

    Unity Shader 学习笔记(27)渲染轮廓线(描边)方法.卡通风格渲染.素描风格渲染 参考书籍:<Unity Shader 入门精要> 渲染轮廓线(描边) 五种方法: 基于观察角度 ...

  7. Unity Shader 之 像素风格(马赛克风格)的简单实现

    Unity Shader 之 像素风格(马赛克风格)的简单实现 目录 Unity Shader 之 像素风格(马赛克风格)的简单实现 一.简单介绍

  8. (二十二)unity Shader——————非真实感渲染:上篇(卡通风格的渲染)

    尽管游戏渲染一般都是以照相写实主义作为主要目标,但也有许多游戏使用了非真实感渲染(NPR)的方法来渲染游戏画面.非真实感的一个主要目标是,使用一些方法使得画面和某些特殊的绘画风格相似的效果,例如卡通. ...

  9. 【我的书】Unity Shader的书 — 目录(2016.5.19最后一次更新)

    写在前面 感谢所有点进来看的朋友.没错,我目前打算写一本关于Unity Shader的书. 出书的目的有下面几个: 总结我接触Unity Shader以来的历程,给其他人一个借鉴.我非常明白学Shad ...

最新文章

  1. matlab已知散点图求方程,已知空间离散点,想求出曲面方程,怎么办?
  2. App-V 4.6中文版首测体验
  3. python给多个子图加总标题
  4. ElasticSearch和mysql对比
  5. 开源软件 Nagios 曝11个漏洞,可使IT 基础设施遭接管引发供应链攻击
  6. 物理学报 LaTeX模板(自编)
  7. sql 行政区划关联查询优化_民政部:四季度继续开展优化行政区划设置研究
  8. 朗文当代高级词典LONGMAN.Dictionary
  9. c语言中内存分配方式
  10. 【Unity】四叉树/八叉树管理和动态加载场景物件
  11. JS的Date函数汇总
  12. ElementUI Plus
  13. 像《我是歌手》一样说我是程序员
  14. 克里斯蒂安贝尔_马特达蒙和克里斯蒂安贝尔 出演福特vs法拉利的传记片
  15. 尚硅谷Redis6从入门到精通
  16. 小爱同学指令大全_小爱同学有哪些隐藏功能?小爱同学实用隐藏功能大汇总
  17. google学术出现错误
  18. 手机二维码业务行业报告
  19. 沟通——职场生存的润滑剂
  20. Linux(常用)命令篇

热门文章

  1. ( 22美赛C题)基于投资最优交易策略的研究(部分内容)
  2. Scratch软件编程等级考试二级——20210320
  3. 人脸识别之insightface开源代码使用:训练、验证、测试(2)
  4. 内外部函数和内存模型
  5. 微信小程序 springboot农产品在线商城系统java 助农电商
  6. 利用Vlookup函数在Excel中根据一列来筛选信息
  7. 香肠派对手游怎么在电脑上玩 香肠派对电脑版玩法教程
  8. kibana服务器性能要求,kibana 性能监控 apm
  9. 3.在地图上标记位置
  10. Android音频子系统(十二)------抖音直播功耗问题解析