Unity Shader 卡通渲染 基于退化四边形的实时描边

一、边缘检测算法

3D模型描边有两种方式,一种是基于图像,即在所有3D模型渲染完成一张图片后,对这张图片进行边缘检测,最后得出描边效果。一种是基于空间,即针对3D模型的三角面三个顶点构成的线条做边缘检测(注:和基于图像的边缘检测的检测方式是不同的,但都叫边缘检测)。在本文中使用的是基于空间的3D模型的描边。

空间的3D模型的描边的边是有类型的,大致总结有4种:轮廓边、边界边、折缝边、材质边。其中前3种是本文认为卡通渲染所必须有的。

图1 空间中的边分类 来自文献[1]

轮廓边的检测根据定义就是,1条边的2个邻接面的法线分别和视线方向的点乘结果再相乘,结果小于0就是轮廓边。数学上表达就是:(N1·V)*(N2·V) < 0,N1和N2是2个邻接面的法向量,V是视线方向。

边界边的检测比较简单,如果1条边只有1个面邻接,那么这条边就是边界边。

折缝边的检测需要使用1个角度参数α,1条边的2个邻接面的夹角和这个参数做大小比较。一般在0~180度,但本文选择在0~90度,并规定小于参数α的就是折缝边。

总结:要在3D模型上实现这3类边的绘制,只需要知道构成1条边的2个邻接面即可完成3类边的检测。在学术上有人把这2个邻接面当做1个点输入到着色器中,并作为1条边作为输出,并称这2个邻接面为退化四边形。

图2 退化四边形

二、具体实现

本文使用目前最主流的Uinty3D游戏引擎实现,由于这是脱离正常真实感渲染的算法,因此如果不能自定义这部分渲染流程,那么实现起来就无比困难,幸运Unity3D支持自定义渲染流程,其中使用到的关键类为CommandBuffer、ComputeBuffer。

由于不同的图形引擎,对图形接口的高级用法支持程度并不一致,例如Unity3D的几何着色器就没办法获取邻接三角形。因此预处理是有必要的。

实现步骤:

步骤1:预处理阶段,在这个阶段找出模型所有的边,以及边所对应的2个邻接面(默认所有边都是由2个邻接面相交构成,不规范的请自行处理)。

步骤2:把预处理阶段的数据保存下来,Uinty3D提供了很好接口ScriptableObject 。(注:默认保存退化四边形4个顶点的索引,如果保存的不是顶点索引,请自行处理)

步骤3:通过CommandBuffer、ComputeBuffer把预处理据保输入到显卡(GPU)中进行检测和绘制。

shader中边缘检测步骤:

步骤1:通过退化四边形4个顶点数据,计算出2个邻接面的法向量。如果顶点数不足4个则表明该边只有1个邻接面,因此它是边界边。

步骤2:计算出2个邻接面的法向量和视线方向的点乘结果dot(N1, V) * dot(N2, V),如果结果为负则是轮廓边。

步骤3:pow(dot(N1, N2) / cos(α), 2)在[0, PI/2]上单调递增, 可避免开方的特点,完成和dot(N1, N1) * dot(N2, N2)比较,如果小于则为折缝边。

三、实验结果

由于Uinty3D的帧数实在看不太懂,运算量低的时候帧数基本保持在90帧左右,运算量高一点点的时候就跑到120帧,估计是内部做了优化,因此运行结果仅供参考,并不准确,运行环境I5-4210M,GTX765M。

四、总结

这个描边算法在很早就被提出,这种基于空间的描边极大程度的得到模型丰富的描边细节,可惜在市面上貌似并不为人所知。某崩公司貌似是使用了这种算法,结合其他卡通渲染算法,画面效果惊人,把同行远远甩在后面。因此如果想让自己的作品更有竞争力,开发人员应该静下心来学习一下这些教科书上没有的论文想法。本文的后续工作是控制线条的大小,理论上应该是可以在裁剪空间实现近粗远细的线条算法,但由于刚刚踏足这一块,还有很多其他工需要去研究,本文到此结束,谢谢。

附:源码

参考文献:

[1]基于着色器技术实时卡通渲染的的研究

[2]基于GPU实时非真实感渲染的研究与实现

[3]3D日式卡通人物渲染的经验分享

[4]Unity网格编程篇(二) 非常详细的Mesh编程入门文章

[5]Unity Shader入门精要

[6]Geometry Shader Input: GL_TRIANGLES_ADJACENCY

[7]Adjacency information in geometry shaders

[8]Direct X 12 – Geometry Shader 几何着色器

[9]OpenGL 图元处理

从csdn转移过来,顺便把写过的文章改写一下转过来。原文在这,比较凌乱,不再建议阅读。

原文地址:https://www.cnblogs.com/lht666/p/11447199.html

时间: 2024-08-29 18:37:11

Unity Shader 卡通渲染 基于退化四边形的实时描边的相关文章

Unity酱~ 卡通渲染技术分析(二)

前面的话 上一篇Unity酱~ 卡通渲染技术分析(一) 写了CharaMain.cginc,服装的渲染是怎么实现的.这篇来分析一下头发跟皮肤的实现 头发 本来以为unitychan的头发会有各向异性的实现,没想到她也是用的CharaMain.cginc实现的.我们来看看头发的材质 其他实现都一样,也是通过高光反射贴图来控制高光区域跟反射区域 计算法线跟视角向量的点积,这样的效果是越垂直于视角向量的高光越大,然后用RGB贴图来控制哪些区域更容易出高光 反射依然是用A通道来控制,越白的地方,反射的越

[Unity&#160;Shader笔记]渲染路径--Forward渲染路径

[Unity Shader笔记]渲染路径--Forward渲染路径 (2014-04-22 20:08:25) 转载▼ 标签: shader unity renderingpath forward 游戏 分类: UnityShader *ForwardBase.ForwardAdd的LightMode只能运行在Came为Forward.DeferredLighting的渲染模式下 *ForwardAdd这个Pass需要和ForwardBase一起使用,否则会被Unity忽视掉 * Forward

【我的书】Unity Shader的书 — 目录(2015.09.04更新)

写在前面 感谢所有点进来看的朋友.没错,我目前打算写一本关于Unity Shader的书. 出书的目的有下面几个: 总结我接触Unity Shader以来的历程,给其他人一个借鉴.我非常明白学Shader的艰难,在群里也见了很多人提出的问题.我觉得学习Shader还是一件有规律可循的事情,但问题是中文资料难觅,而大家又不愿意去看英文...这对我有什么好处呢?强迫我对知识进行梳理,对细节问题把握更清楚. 第二个原因你懂的. 关于本书的定位问题: 面向Unity Shader初学者,但要: 有一定的

【我的书】Unity Shader的书 — 目录(2016.1.29更新)

写在前面 感谢所有点进来看的朋友.没错,我目前打算写一本关于Unity Shader的书. 出书的目的有下面几个: 总结我接触Unity Shader以来的历程,给其他人一个借鉴.我非常明白学Shader的艰难,在群里也见了很多人提出的问题.我觉得学习Shader还是一件有规律可循的事情,但问题是中文资料难觅,而大家又不愿意去看英文...这对我有什么好处呢?强迫我对知识进行梳理,对细节问题把握更清楚. 第二个原因你懂的. 关于本书的定位问题: 面向Unity Shader初学者,但要: 有一定的

【我的书】Unity Shader的书 — 文件夹(2015.12.21更新)

写在前面 感谢全部点进来看的朋友.没错.我眼下打算写一本关于Unity Shader的书. 出书的目的有以下几个: 总结我接触Unity Shader以来的历程,给其它人一个借鉴.我非常明确学Shader的艰难,在群里也见了非常多人提出的问题. 我认为学习Shader还是一件有规律可循的事情,但问题是中文资料难觅,而大家又不愿意去看英文...这对我有什么优点呢?强迫我对知识进行梳理,对细节问题把握更清楚. 第二个原因你懂的. 关于本书的定位问题: 面向Unity Shader刚開始学习的人,但要

Unite 2018 | 《崩坏3》:在Unity中实现高品质的卡通渲染(下)

http://forum.china.unity3d.com/thread-32273-1-1.html 今天我们继续分享米哈游技术总监贺甲在Unite Beijing 2018大会上的演讲<在Unity上实现高品质卡通渲染的效果>下篇,上篇请点击此处阅读. 下面为演讲内容: 接下来我们就来介绍一下头发的渲染.头发是卡通渲染角色较为重要且独特的部分.我们想要实现根据光源动态变化的高光和阴影渐变,并且这个实现还应具备直观的所见即所得的色彩调节能力. 和皮肤的材质一样,对于头发的漫反射渲染我们同样

【Unity Shader】(九) ------ 高级纹理之渲染纹理及镜子与玻璃效果的实现

笔者使用的是 Unity 2018.2.0f2 + VS2017,建议读者使用与 Unity 2018 相近的版本,避免一些因为版本不一致而出现的问题. [Unity Shader](三) ------ 光照模型原理及漫反射和高光反射的实现 [Unity Shader](四) ------ 纹理之法线纹理.单张纹理及遮罩纹理的实现 [Unity Shader](五) ------ 透明效果之半透明效果的实现及原理 [Unity Shader](六) ------ 复杂的光照(上) [Unity

【我的书】Unity Shader的书 — 目录(实时更新中)

写在前面 感谢所有点进来看的朋友.没错,我目前打算写一本关于Unity Shader的书. 出书的目的有下面几个: 总结我接触Unity Shader以来的历程,给其他人一个借鉴.我非常明白学Shader的艰难,在群里也见了很多人提出的问题.我觉得学习Shader还是一件有规律可循的事情,但问题是中文资料难觅,而大家又不愿意去看英文...这对我有什么好处呢?强迫我对知识进行梳理,对细节问题把握更清楚. 第二个原因你懂的. 关于本书的定位问题: 面向Unity Shader初学者,但要: 有一定的

【Unity Shader编程】之十五 屏幕高斯模糊(Gaussian Blur)后期特效的实现

本系列文章由@浅墨_毛星云 出品,转载请注明出处.   文章链接:http://blog.csdn.net/poem_qianmo/article/details/51871531 作者:毛星云(浅墨)    微博:http://weibo.com/u/1723155442 本文工程使用的Unity3D版本: 5.2.1  本篇文章将分析如何在Unity中基于Shader实现高斯模糊屏幕后期特效. 首先放出最终的实现效果.如下几幅图,是在Unity中使用本文所实现的Shader得到的高斯模糊屏幕