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

前面的话
unitychan是日本unity官方团队提供的一个Demo,里面有很好的卡通渲染效果,值得参考学习

上图是我整理出来的shader结构,可以看到Unity娘被拆分成了很多个小的部件,我想主要是为了挂动态骨骼吧。因为有很多部件的材质,shader其实都是一样的可以合并成少数几个
我打算分3个部分来学习
- CharaMain.cginc 主要用于衣服等材质
- CharaSkin.cginc 皮肤效果
- Hair 头发、眼睛、睫毛等部位的渲染
CharaMain.cginc
本篇先写第一部分body材质。CharaMain.cginc中包含漫反射、高光、反射、边缘光、阴影等效果的实现,接下来我们详细拆解
基础着色效果(模拟漫反射)
这里是用视角向量跟法线点积(但这样的做法就不会受光照角度变化),然后用结果采样一张类似这样的衰减纹理
// Falloff. Convert the angle between the normal and the camera direction into a lookup for the gradient
float_t normalDotEye = dot( normalVec, i.eyeDir.xyz );
float_t falloffU = clamp( 1.0 - abs( normalDotEye ), 0.02, 0.98 );
float4_t falloffSamplerColor = FALLOFF_POWER * tex2D( _FalloffSampler, float2( falloffU, 0.25f ) );
float3_t shadowColor = diffSamplerColor.rgb * diffSamplerColor.rgb;
float3_t combinedColor = lerp( diffSamplerColor.rgb, shadowColor, falloffSamplerColor.r );
combinedColor *= ( 1.0 + falloffSamplerColor.rgb * falloffSamplerColor.a );

效果如下,边缘较白

但我感觉加上采样颜色后效果不是很明显,边缘颜色会深一些。

高光效果
// Use the eye vector as the light vector
float4_t reflectionMaskColor = tex2D( _SpecularReflectionSampler, i.uv.xy );
float_t specularDot = dot( normalVec, i.eyeDir.xyz );
float4_t lighting = lit( normalDotEye, specularDot, _SpecularPower );
float3_t specularColor = saturate( lighting.z ) * reflectionMaskColor.rgb * diffSamplerColor.rgb;
combinedColor += specularColor;
这个高光的计算很奇葩,也是用法线跟视角向量的点积,最后的效果就是有一点淡淡的高光。也是跟真正的灯光角度无关的。
这里还用到了一张贴图,高光会用到这张图的rgb通道,后面要写的反射,会用到这张图的a通道。
大概就是描出来那些地方高光强一些


反射
// Reflection
float3_t reflectVector = reflect( -i.eyeDir.xyz, normalVec ).xzy;
float2_t sphereMapCoords = 0.5 * ( float2_t( 1.0, 1.0 ) + reflectVector.xy );
float3_t reflectColor = tex2D( _EnvMapSampler, sphereMapCoords ).rgb;
reflectColor = GetOverlayColor( reflectColor, combinedColor );
combinedColor = lerp( combinedColor, reflectColor, reflectionMaskColor.a );
combinedColor *= _Color.rgb * _LightColor0.rgb;
float opacity = diffSamplerColor.a * _Color.a * _LightColor0.a;
这里是采样一张环境贴图,为啥用张这样的图呢?我觉得他主要是为了能反射出这种银色的色调罢了。你想要什么色调就换啥样的环境图。

GetOverlayColor这个函数是用来融合自身贴图颜色,跟反射环境贴图颜色的。里面用了很多小技巧
先来看看直接输出反射贴图是什么样

通过GetOverlayColor融合后的反射颜色

然后这里会用到高光反射贴图的A通道,来表示某些区域的反射的强度。

用alpha通道做差值后会发现,大部分区域的反射颜色都不见了,因为大部分是黑色。只有少数白色区域,能看到一些反射效果

接收阴影处理
这里是计算其他物体投射在身上的阴影,这里插入了一个自定义的阴影颜色,为了明显一点我直接调成纯黑,然后弄了一个物体挡住了unity酱~ 效果如图

使用LIGHT_ATTENUATION指令对阴影贴图采样并且返回数据供你使用。如果你想知道LIGHT_ATTENUATION指令具体做了些什么,检查 AutoLight.cginc文件
#ifdef ENABLE_CAST_SHADOWS
// Cast shadows
shadowColor = _ShadowColor.rgb * combinedColor;
float_t attenuation = saturate( 2.0 * LIGHT_ATTENUATION( i ) - 1.0 );
combinedColor = lerp( shadowColor, combinedColor, attenuation );
#endif
边缘高光
终于这里有一个跟着光照角度变换的效果了,哈哈
一般我们会使用菲尼尔效应来实现边缘光,而unitychan里面则是采用了一张边缘光贴图

用N.L计算出来的值域在[-1,1]之间,*0.5+1后,转成[0,1]区间,然后对这张1维的rim图采样。
我们从右边打一盏平行灯,来看看采样的效果。跟光向量夹角越小的值越接近1,也就越白

但是边缘光效果要收到漫反射影响,所以他这里乘上了之前采样出来的漫反射渐变,可以看到高光被控制在了边缘
falloffU = saturate( rimlightDot * falloffU );

完整效果

总结
CharaMain.cginc中用了很多的小技巧实现了漫反射、高光、反射、边缘光。她没有传统卡通渲染赛璐璐的阴影渐变,也没有油腻的高光。她的效果都有种欲出还收的感觉。
我还是觉得效果太淡了一些
Unity酱~ 卡通渲染技术分析(一)的更多相关文章
- Unity酱~ 卡通渲染技术分析(二)
前面的话 上一篇Unity酱~ 卡通渲染技术分析(一) 写了CharaMain.cginc,服装的渲染是怎么实现的.这篇来分析一下头发跟皮肤的实现 头发 本来以为unitychan的头发会有各向异性的 ...
- 基于Unity 5的次世代卡通渲染技术 -- Unite 2017 米哈游总监贺甲分享实录
在5月12日Unite2017开发者大会上,米哈游技术总监兼美术指导贺甲进行了主题为次世代卡通渲染的演讲.一下为详细分享内容: 大家好,首先自我介绍一下,我叫贺甲,在米哈游担任技术总监和美术指导工作, ...
- Unity Shader 卡通渲染 基于退化四边形的实时描边
从csdn转移过来,顺便把写过的文章改写一下转过来. 一.边缘检测算法 3D模型描边有两种方式,一种是基于图像,即在所有3D模型渲染完成一张图片后,对这张图片进行边缘检测,最后得出描边效果.一种是基于 ...
- Unite 2018 | 《崩坏3》:在Unity中实现高品质的卡通渲染(上)
http://forum.china.unity3d.com/thread-32271-1-1.html 我们已经发布了Unite 2018 江毅冰的<发条乐师>.Hit-Point的&l ...
- Unite 2018 | 《崩坏3》:在Unity中实现高品质的卡通渲染(下)
http://forum.china.unity3d.com/thread-32273-1-1.html 今天我们继续分享米哈游技术总监贺甲在Unite Beijing 2018大会上的演讲<在 ...
- Unity Shader入门精要学习笔记 - 第16章 Unity中的渲染优化技术
转自冯乐乐的 <Unity Shader 入门精要> 移动平台的特点 为了尽可能一处那些隐藏的表面,减少overdraw(即一个像素被绘制多次),PowerVR芯片(通常用于ios设备和某 ...
- Turing渲染着色器网格技术分析
Turing渲染着色器网格技术分析 图灵体系结构通过使用 网格着色器 引入了一种新的可编程几何着色管道.新的着色器将计算编程模型引入到图形管道中,因为协同使用线程在芯片上直接生成紧凑网格( meshl ...
- Unity——卡通渲染实现
效果展示: 原模型: 一.简单分析 卡通渲染又叫非真实渲染(None-Physical Rendering-NPR),一般日漫里的卡通风格有几个特点: 1.人物有描边 2.有明显的阴影分界线,没有太平 ...
- Unity Shader NPR 卡通渲染
卡通渲染的主要原理包含两个方面: 1.轮廓线的描边效果 2.模型漫反射离散和纯色高光区域的模拟 描边: 描边的实现方法采用将模型的轮廓线顶点向法线(或顶点)的方向扩展一定的像素得到.也可通过边缘检测( ...
随机推荐
- JDK12 的下载和没有jre的解决及环境配置
一.下载直接在官网上下载并点击安装即可,步骤省.jdk12下载中途已经没有跳出窗口下载jre的过程了,需要手动生成jre. 二.没有jre的解决:1.cmd 2.切换到jdk的安装目录,执行命令:bi ...
- CMS总结
过程 初始标记 从roots(例如:thread stack引用的对象,static对象),新生代对象,标记直接引用的老年代对象. 并发标记 利用初始标记阶段标记的对象,递归标记整个老年代. 该阶段与 ...
- Scala实践8
1.1继承类 使用extends关键字,在定义中给出子类需要而超类没有的字段和方法,或者重写超类的方法. class Person { var name = "zhangsan" ...
- 初识 ST 表
推荐博客 : https://blog.csdn.net/BerryKanry/article/details/70177006 ST表通常用于RMQ问题中,询问某个区间的最值这类问题中 ST表的核心 ...
- spark和mapreduce的区别
spark和mapreduced 的区别map的时候处理的时候要落地磁盘 每一步都会落地磁盘 reduced端去拉去的话 基于磁盘的迭代spark是直接再内存中进行处理 dag 执行引擎是一个job的 ...
- Nginx作为静态web服务器——缓存原理
浏览器缓存 客户端无缓存的情况下 客户端有缓存的情况下 校验过期机制 本地客户端会检查Cache-Control(max-age)缓存是否过期,(max-age)为过期时间 Last- ...
- 【5min+】传说中的孪生兄弟? Memory and Span
系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...
- vue-cookies
vue-cookies用于登录,一般和vuex一起使用 vuex在各个组件共享值,cookie恒久保留值 一.安装 npm install vue-cookies --save 二.引用(在store ...
- 异数OS TCP协议栈测试(一)--数据传输篇
异数OS TCP协议栈测试(一)--数据传输篇 本文来自异数OS社区 github: 异数OS-织梦师(消息中间件)群: 476260389 测试目标 数据传输IO性能测试,主要是建立连接后测试收 ...
- vue需要知道哪些才能算作入门以及熟练
前两天接到一个面试官问我vue什么程度才算作可以用于开发,以前从没遇到过类似问题.只能大致说了一些,事后觉得也应该总结一下,前端vue这么火热那究竟什么才算做入门什么才算做熟练,只是我个人观点,不代表 ...