#水墨风格渲染
这次学校的比赛打算做一个中国古代背景的游戏,所以尝试做了水墨风格的渲染。
主要按以下四步来实现的效果:

  1. 根据色调和饱和度调整饱和度。
  2. 对图像进行模糊
  3. 水墨风格的物体边缘
  4. 物体内画笔笔触的模拟

接下来我分别就这四步依次展开说明:
##调整饱和度
这里我使用Post-Processing Stack 的Color Grading 来调节饱和度,通过使用Grading Curves来具体调节。根据色调和饱和度调整饱和度。强化部分国画中常用颜料的颜色部分的饱和度,少见颜料的颜色降低饱和度;饱和度高的强化,低的降低。这里我调节了Sat VS Sat和Hue VS Sat两种曲线,保留了部分色调在红色和绿色附近(也就是所谓的丹青)的饱和度,使其它颜色整体变灰;并使饱和的较高的部分区域的饱和度更高,其余部分有所降低,效果对比如下:

##图像模糊
这里使用高斯模糊来实现,由于与之后的描边效果不冲突可以写在一个Pass里。我这里直接用Post-Processing Stack里的DOF(景深)效果,然后把焦距调到最小,让全屏都模糊。实际上的效果是几乎一样的。

##水墨描边
由于上一步我们模糊了图像,所有这里不能直接用原图来进行边缘检测,我们通过_CameraDepthNormalsTexture,来获得法线图然后用法线图来进行边缘检测,这样我们不仅得到了模糊前图的边缘而且,不会讲阴影等几何上在一个平面上的颜色不连续的部分也识别为边缘。
采用Roberts边缘算子来检测,Roberts算子计算对角上的像素之间的差,模板比较简单,而且可以通过调整中心像素到角上的距离来控制描边的粗细。

具体代码如下:


float rgb2gray(fixed3 col){float gray = 0.2125 * col.r + 0.7154 * col.g + 0.0721 * col.b; return gray;
}
fixed4 frag (v2f i) : SV_Target
{//......float2 texel = _MainTex_TexelSize.xy;//判断是否是边缘fixed3 col0 = tex2D(_CameraDepthNormalsTexture,i.uv+_EdgeWidth*texel*float2(1,1)).xyz;fixed3 col1 = tex2D(_CameraDepthNormalsTexture,i.uv+_EdgeWidth*texel*float2(1,-1)).xyz;fixed3 col2 = tex2D(_CameraDepthNormalsTexture,i.uv+_EdgeWidth*texel*float2(-1,1)).xyz;fixed3 col3 = tex2D(_CameraDepthNormalsTexture,i.uv+_EdgeWidth*texel*float2(-1,-1)).xyz;float edge = rgb2gray(pow(col0-col3,2)+pow(col1-col2,2));//.......
}

其中_EdgeWidth用来控制边缘粗细
理论上我们这样计算出来的edge是一个大于0小于1的很小的数,为了更好的视觉效果我们通过pow()函数来增大edge的值,相当于进行一个对数变换,在变换后部分非边缘的区域edge也会有个较大的值,我们可以再设定一个阈值来舍弃edge不够大的部分区域。

edge = pow(edge,0.2);
if(edge<_Sensitive)edge=0;
return fixed4(edge,edge,edge,1.0);

以下为_EdgeWidth为3时,不进行任何变换、进行对数变换、设置阈值为0.35时的到的边缘图

然后用edge的值来控制边缘与原图混合,可以设置具体的边缘颜色。
可以通过噪声图或噪声函数来给边缘制造水墨感。关于噪声的内容我就不具体说明了,我这里用了三维值噪声的分形叠加,为了是摄像机移动后同一个噪声纹理与模型相匹配,我通过深度值来获得像素世界坐标,再用世界坐标来生成噪声,这样噪声的样式就贴到模型上了,而不会像用屏幕坐标来采样时那样,移动屏幕会显得不自然。

if(edge<_Sensitive)edge=0;
else{edge=noise;
}
fixed3 finalColor = (edge)*_EdgeColor.xyz+(1-edge)*col*(0.95+0.1*noise);
//非边缘部分也可以加上较小的噪声来模拟水墨在纸上扩散的质感
//因为noise在0~1的范围内所有使系数和的均值为1左右来保证画面不会更亮或更暗
return fixed4(finalColor,1.0);


##模拟笔触
虽然通过模糊颜色上有一定的水墨扩散的感觉,通过描边可以区分模型的边缘,但图片还是有许多不自然的地方。比如颜色扩散太均匀不想“画”出来的,许多细小的边缘由于太小而形成了“噪点”。而且由于我使用的噪声是通过世界坐标得到的,部分很远的地方由于透视而显得噪声很乱。所以我们再进行一次滤波来消除这些问题,并模拟画笔的笔触。这里用了一种保留边缘的滤波,算法具体的名字我忘了,之前不记得哪里看到过。具体思路是用中心像素作为模板的四个角,然后分别计算中心在四个角时的整个区域的均值和方差,然后取方差最小的区域的均值输出。求知道这个滤波名字的大佬告知一下,我好查一查相关资料,浅墨的这篇文章里实现的油画效果也是用简化后,只取两个角来计算的。我这里就直接用两个角的来算了

for (int j = -4; j <= 0; ++j)
{  for (int k = -4; k <= 0; ++k)  {  c = tex2D(_MainTex, i.uv +texel*float2(k, j)).xyz;m0 += c;   s0 += c * c;  }
}
for (int j = 0; j <= 4; ++j)
{  for (int k = 0; k <= 4; ++k)  {  c = tex2D(_MainTex, i.uv +texel*float2(k, j)).xyz;m1 += c;   s1 += c * c;  }
}
//取方差小的区域的颜色作为最终输出颜色
float4 finalFragColor = 0.;
float min_sigma2 = 1e+2;
m0 /= 25;
s0 = abs(s0 / 25 - m0 * m0);
float sigma2 = s0.r + s0.g + s0.b;
if (sigma2 < min_sigma2)
{  min_sigma2 = sigma2;  finalFragColor = float4(m0, 1.0);
}
m1 /= 25  ;
s1 = abs(s1 / 25 - m1 * m1);
sigma2 = s1.r + s1.g + s1.b;
if (sigma2 < min_sigma2)
{  min_sigma2 = sigma2;  finalFragColor = float4(m1, 1.0);
}
return finalFragColor;

注意这里是对描边后的图像进行的操作,最终效果如下
可以调节最开始的滤波范围和描边粗细,边缘颜色等参数来调整效果



对比后处理前原效果

嗯,感觉更丑了。

unity shader 后处理实现水墨风格渲染「Low Poly 」变「水墨画 」相关推荐

  1. 着色器编程_unity中的基础纹理,使用Unity Shader实现基础纹理的渲染效果

    学习通过使用Unity Shader实现基础纹理的渲染效果 目录 学习通过使用Unity Shader实现基础纹理的渲染效果 问1:详细描述一下漫反射纹理.高度纹理.法线纹理.渐变纹理和遮罩纹理? 问 ...

  2. 脑洞大开!Adobe等新研究把「自拍」变「他拍」,魔幻修图效果感人

    选自arXiv 作者:Liqian Ma.Zhe Lin等 机器之心编译 编辑:蛋酱.张倩.杜伟 自拍也能变为他拍,魔幻修图界又出新招式,但效果实在感人. 智能手机的出现,让摄影变成了一项大众艺术,也 ...

  3. java修图sdk_脑洞大开!Adobe等新研究把「自拍」变「他拍」,魔幻修图效果感人...

    自拍也能变为他拍,魔幻修图界又出新招式,但效果实在感人. 智能手机的出现,让摄影变成了一项大众艺术,也让越来越多的人爱上「自拍」.但自拍照常常存在构图问题,比如不自然的肩膀姿势.占据一小半镜头的手臂, ...

  4. (十六)unity shader之——————高级纹理之渲染纹理(镜子、玻璃效果)

    在之前的学习中,一个摄像机的渲染结果会输出到颜色缓冲中,并显示到我们的屏幕上.现在的GPU允许我们把整个三维场景渲染到一个中间缓冲中,即渲染目标纹理(Render Target Texture,RTT ...

  5. (十九)unity shader之——————基于物理的渲染技术(PBS):中篇(Unity 5中的Standard Shader的实现和使用)

    一.unity 5中的standard shader 在unity5中新创建一个模型或是新创建一个材质时,默认使用的着色器都是一个名为standard 的着色器.这个standard shader使用 ...

  6. 「网络创业家」变「网络发明家」的3个新网站实例

    「发明家」是那位名垂千古的伟大爱迪生,而「创业家」只是隔壁那个中辍找不到工作只好开点的阿狗,我们只敢认自己为「创业家」,不敢「升级」为「发明家」 .但,网络其实还蛮适合「发明」的. 周末看到一个我认为 ...

  7. Unity Shader 实现简单的宝石渲染

    入职实习的第一周过去了,感觉还是相当不错的,找到工作了也就不用再顶着高压去学习了,快乐. 闲话少说,先上效果图啦. 效果还是很棒的,但这不是我写的,哈哈,这个代码可以完全说就是抄Unity的案例.As ...

  8. (二十)unity shader之——————基于物理的渲染技术(PBS):下篇(PBS技术拓展:全局光照、伽马校正、HDR)

    前面两篇文章我们介绍了PBS实现的数学和理论基础,和standard shader的原理和实现,还有一些其他的渲染相关的unity技术.其中有些概念和技术没有讲的很详细,现在对这些重要的概念进行更深入 ...

  9. 【Unity Shader实战】卡通风格的Shader(一)

    写在前面 本系列其他文章: 卡通风格的Shader(二) 呜,其实很早就看到了这类Shader,实现方法很多,效果也有些许不一样.从这篇开始,陆续学习一下接触到的卡通类型Shader的编写. 本篇的最 ...

最新文章

  1. 【HDU2582 关于 gcd( C[n][1],C[n][2],C[n][3],........C[n][n-1) 】
  2. CentOS7安装Nginx,全网最快安装教程
  3. HDU 2072 单词数
  4. ESP32串口API
  5. 设计模式学习笔记(九)——Composite组合模式
  6. 经典排序算法(八)--选择排序Selection Sort
  7. php回滚实例_thinkphp 的事务回滚处理 和 原始PHP的事务回滚实例
  8. 加密--HashPasswordForStoringInConfigFile过时问题
  9. Rhadoop的安装
  10. windows下调用外部exe程序 SHELLEXECUTEINFO
  11. [COGS 2479] [HZOI 2016] 偏序
  12. 短视频矩阵系统,抖音矩阵系统,抖音获客系统源码。look
  13. java对打字速度,java课程设计-- 打字速度测试程序
  14. 解决:windows电脑连接iphone手机热点,iphone锁屏后热点会自动断开
  15. 在Windows下配置Ubuntu启动引导项
  16. 大学计算机基础教程第10章数据通信技术基础
  17. SSAO与HBAO学习笔记(持续改进)
  18. Spark 第三讲 Scala数组与函数基础
  19. 美国名校的网上竞争雷人语录
  20. 肢体语言心理学+FBI阅人术(行为心理学) 用最短的时间了解一个人

热门文章

  1. 仿百度地图抽屉拖拽效果
  2. 计算机毕业设计asp.net党员信息管理系统(源码+系统+mysql数据库+Lw文档)
  3. 打印机 HP LaserJet 1018安装教程
  4. WM6 Rapi 开发(一) 准备工作
  5. ORACLE DG专题3--手把手部署DG 物理备库
  6. 三国志战略版:Daniel_张姬分析
  7. 转—正弦波逆变器入门到精通----逆变器设计原理
  8. ctfshow 七夕杯(复现)
  9. C4D云渲染平台哪家好?
  10. 怎么关闭win7计算机一键还原系统,电脑一键还原,小编教你win7电脑如何一键还原...