Unity_Shader

简易的卡通渲染

:先说明为什么说是简易的卡通渲染,顾名思义,写的比较简单,跑去显示效果不是很好以外,甚至还会有些小小的bug没处理,不过姑且可以在一些不那么讲究的项目中用用,或者说给刚接触的小白入个门。(我摊牌了,我刚入门,我还是个小白)
最终效果:先把效果放出来,觉得还行的继续康,觉得太辣鸡的就可以跑路了(觉得看讲述费时间的也可以直接跳转文末,有完整Shader代码,基本上每句话我都打了注释,Shader基础不错的崽应该可以直接看懂)

总体简述

  • 首先是说一下这个卡通渲染实现了什么:实现了一个描边效果,一个光照效果分阶。多的没有了,所以可以看出,细节上有很多比较搓的地方
  • 关于这个描边效果还存在个问题,就是如果模型棱角比较明显,会出现描边断开的情况,具体参照下图(不过在一些过度平滑或者说比较精细的模型中,一般不会有影响),这个问题一直找不到解决方法(其他描边法除外),有大佬说可以通过切线和法线计算一个新的法线出来,但没有说具体怎么做,还是不会,如果有大佬不吝赐教那就太感谢了
  • 然后关于这个光照分阶,我没有用渐变纹理,只是很简单粗暴的手动设置了俩个颜色,作为光照颜色和阴影颜色。这也就造成了光照的过渡非常僵硬。

描边

  • 首先说说这个黑色描边的实现,之前采用的是让顶点坐标直接在模型空间下扩张开来,然后直接渲染黑色,作为描边,后来法线这种方法致命的问题,于是改了现在的方法。
  • 让顶点在模型空间下直接冲着法线的方向进行位移,就可以把模型的顶点整体向外扩出一圈,为其加上一个参数来控制其外扩的强度(不如直接叫做描边宽度?),但是还有个问题这个描边宽度是不能固定的,如果宽度固定,那么相机拉近的情况下,就可以看到很粗很粗的一条线,就没有“画”出来的那种感觉了,所以我计算了相机和当前顶点的距离,作为一个控制描边宽度的参数,去根据相机距离来动态控制这个描边宽度。
  • 整体外扩后将其全部渲染成黑色,然后再给该pass块加上一句Cull Front指令剔除前面的渲染,只渲染后面,就可以保证不会挡到模型的正常显示,就是黑色描边了。

模型渲染

  • 然后再说说这个模型的渲染问题,卡通渲染又叫非真实渲染,通常色阶比较少,过度没那么平缓,具体随便找个二次元的图一般就能康的到,所以我们要做的就是给模型渲染出来的的色阶段给分成比较明显几部分。
  • 这里我用的方法是直接对漫反射动手,使用入射光线和法线的夹角cos值作为参数,去与设定好的分阶数进行比较,然后根据结果设定当前片元的漫反射光应该是哪个颜色(预先设定好的俩个)。这也就导致了最终渲染出来效果很一般,虽然由内味儿了,但不够专业,不够强力(要真正学一手卡通渲染,还是参照大佬的详细讲解)

代码(我写了很多注释,帮助详细理解)

Shader "Custom/Myshader/CartoonRandering3"
{Properties{_MainTex("Main Texture",2D) = "while"{}                   //定义一个2D的纹理输入_Color1("MyColor1",Color) = (1.0,1.0,1.0,1.0)            //色阶1       _Color2("MyColor2",Color) = (1.0,1.0,1.0,1.0)            //色阶2_Line_thickness("Line_thickness",Range(0,2)) = 1.1       //线条粗细_Density("Density",Range(0,1)) = 0.5                     //控制色阶比例}SubShader{pass{//黑色描边pass//剔除前方,仅渲染后方Cull Front  Tags{"LightMode" = "ForWardBase"}CGPROGRAM#pragma vertex _Vert#pragma fragment Pixel//定义顶点函数输入struct vertexInput{float4 Pos:POSITION;float3 Normal:NORMAL;};//定义顶点函数输出struct vertexOutput{float4 Pos:SV_POSITION;};//声明线宽参数float _Line_thickness;//开写顶点函数vertexOutput _Vert(vertexInput v){//声明返回值vertexOutput r;//计算相机与顶点的距离,准备作为顶点移位的参数float4 dis = distance(_WorldSpaceCameraPos,mul(unity_ObjectToWorld, v.Pos));//法线标准化v.Normal = normalize(v.Normal);//对顶点坐标按照法线方向移位//移位距离是由外部参数_Line_thickness和相机与顶点距离dis决定的v.Pos.xyz += v.Normal*dis*_Line_thickness;//将移位后的顶点坐标转换到屏幕空间下r.Pos = UnityObjectToClipPos(v.Pos);return r;}fixed4 Pixel(vertexOutput v) :SV_TARGET{//简单粗暴的返回黑色就行return fixed4(0,0,0,0);}ENDCG}pass{//模型渲染passCull BackTags{"LightMode" = "ForWardBase"}CGPROGRAM#pragma vertex _Vert#pragma fragment Pixel#include "Lighting.cginc"#include "UnityCG.cginc"struct vertexInput{float4 Pos:POSITION;         float3 Normal:NORMAL;float4 texcoord : TEXCOORD0;};struct vertexOutput{float4 Pos:SV_POSITION;float3 WorldNormal : TEXCOORD0;float2 uv : TEXCOORD1;};//声明我们需要的变量sampler2D _MainTex;float4 _MainTex_ST;float4 _Color1;float4 _Color2;float _Density;vertexOutput _Vert(vertexInput v){vertexOutput r;//将法线转换到世界坐标下,存入返回值备用r.WorldNormal = UnityObjectToWorldNormal(v.Normal);//将顶点的坐标信息转换到剪裁空间r.Pos = UnityObjectToClipPos(v.Pos);//对应纹理取得uv坐标存入返回值中备用,不过在对模型的卡通渲染中一般用不到纹理的缩放偏移//所以这句代码也可以是:r.uv = v.texcoord.xy;r.uv = TRANSFORM_TEX(v.texcoord,_MainTex);return r;}fixed4 Pixel(vertexOutput v) :SV_TARGET{//对MainTex进行采样,直接作为底色float3 albedo = tex2D(_MainTex, v.uv).xyz;//将世界坐标下的法线方向标准化fixed3 WorldNormal = normalize(v.WorldNormal);//将世界空间的光照方向标准化fixed3 WorldLightDir = normalize(_WorldSpaceLightPos0.xyz);//得到环境光fixed4 ambient = fixed4(UNITY_LIGHTMODEL_AMBIENT.xyz,0);//定义漫反射光fixed4 diffuse;//计算入射光和法线夹角的cos值,并将其作为确定光照颜色的参数与_Density参数作为比较//最终确定这个点的漫反射光照颜色是哪个if(saturate(dot(WorldNormal, WorldLightDir))>_Density){diffuse = _Color1;}else{diffuse = _Color2;}//漫反射光和环境光叠加,得到总光照信息fixed4 Dif = saturate(diffuse+ambient);//将总的光照信息和底色进行叠底,得到最终显色返回fixed4 r = fixed4(albedo, 1.0)*Dif;return r;}ENDCG}}FallBack "Diffuse"
}

Unity_Shader(简易的卡通渲染)相关推荐

  1. Unity Shader 卡通渲染 (一):仿塞尔达荒野之息 Shader(简易版)

    温馨提示: 本系列文章面向那些 Shader 刚刚入门,想寻求进一步提升的群体,如果对 Shader 一无所知的话,建议自行搜索其他 Shader入门教程观看学习,再食用本系列文章. 前言: 说起卡通 ...

  2. 腾讯游戏主美:二次元卡通渲染有哪些黑科技?

    今年,<原神>的出现让行业注意到了三渲二这种独特的画风.但在二次元游戏中,<原神>其实并非第一个吃螃蟹的人.作为腾讯游戏魔方工作室群<王牌战士>项目组的主美,谢海天 ...

  3. unity 3d物体描边效果_从零开始的卡通渲染描边篇

    序言: 一直对卡通渲染非常感兴趣,前后翻找了不少的文档,做了一些工作.前段时间<从零开始>的手游上线了,试着渲染了一下的其中模型,觉得效果很不错.打算写一个专栏记录其中的渲染技术.在后面的 ...

  4. 寄存器分配图着色_【02】从零开始的卡通渲染-着色篇1

    专栏目录 2173:[01]从零开始的卡通渲染-描边篇​zhuanlan.zhihu.com 2173:[02]从零开始的卡通渲染-着色篇1​zhuanlan.zhihu.com 2173:[03]从 ...

  5. ue4 如何获取端口号_尝试在UE4.22中实现罪恶装备Xrd的卡通渲染

    零.前言 最近尝试尝试给UE4添加一个用于三渲二的新的光照模型,主要参考了知乎文章和这篇博客教程,以及GDC2015罪恶装备Xrd制作团队的演讲及其PPT内容. 一.获取美术资源 由于是完全照抄罪恶装 ...

  6. Unity Shader 卡通渲染 (三):仿塞尔达荒野之息 Shader(顶点色控制细节)

    上一篇传送门: https://blog.csdn.net/qq_27534999/article/details/100925621 顶点色在卡通渲染中有挺多应用,本篇会在上一篇的基础上,运用模型顶 ...

  7. 【Unity天空盒】卡通渲染中如何实现云的消散效果

    写在前面 完成大气渲染之后,接下来就是考虑云渲染了.因为我想做的天空盒本身是想跟着这位大佬Unity 卡通渲染 程序化天空盒 - 知乎里叙述的进程来的,里面云实现的是原神里的云,原神又是在崩3的基础上 ...

  8. 崩三类卡通渲染解析及制作规范

    一.本篇文章分为三部分 1,卡通材质解析. 2,优化方向. 3,制作规范. 二.正文部分 1,卡通材质解析 卡通渲染属于非真实感计算机图形学(NPR)的范畴,然而崩三的卡通渲染又在国内被称为行业的标杆 ...

  9. Hair卡通渲染的效果(各向异性)

    Hair卡通渲染的效果-各向异性 丽塔头发 各向异性渲染(截图) 视频演示链接https://www.bilibili.com/video/av71067897 效果截图: 最终渲染源码: 丽塔头发 ...

最新文章

  1. 2021信号与系统一流课程申请-说课视频规划
  2. very_confusing
  3. 字符串(strcmp)
  4. centos7安装mongodb3.6
  5. OpenCV FLANN在数据集中搜索查询图片的实例(附完整代码)
  6. SAP Spartacus 服务器端渲染的依赖注入之 ProductPageEventBuilder
  7. 【H264码流分析】 SPS/PPS/Slice Header
  8. Windows 7 HomeGroup的隐私保护
  9. 直播笔记 | Unity中路径的疑难杂症剖析
  10. 【转载】石油天然气常用单位换算
  11. react 对象渲染_不要过度使用React.useCallback()
  12. python not in range1002无标题_新手常见Python运行时错误
  13. python爬虫之模拟登陆(CSDN篇)
  14. java过滤敏感词汇
  15. Saber电路仿真软件
  16. Date时间里的GMT是什么意思
  17. html2canvas给图片添加水印,小程序用Canvas给图片加水印,拼接图片,制作名片
  18. c#实现爬虫获取小说(.NET)
  19. 设置vs工程中的宏参数
  20. 关于IOS设备window onscroll滚动条滚动事件不触发的问题

热门文章

  1. 低功耗稳压芯片HT73XX系列
  2. reactos终于被成功编译通过
  3. 成都链安重磅出品 | 基于VS Code插件的智能合约自动形式化验证工具Beosin—VaaS『离线免费版』...
  4. 随笔 | 武汉大学管理课笔记 第一课
  5. 使用Camstudio和KeyCastOW来录屏制作软件Demo视频
  6. 广电收视率项目之项目需求分析
  7. 大坝安全监测设备(数据采集仪MCU)-守护水库安全防线
  8. PHP接口开发加密技术实例原理与例子
  9. 【Kettle】 Javascript脚本组件
  10. 伽马发布、泊松分布以及指数分布的关系