如何在Unity中实现基于笔触的实时渲染

这篇文章给大家介绍如何在Unity中实现基于笔触的实时渲染,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

创新互联坚持“要么做到,要么别承诺”的工作理念,服务领域包括:网站设计、成都网站设计、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的崇仁网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

什么是基于笔触的渲染

基于笔触的渲染(stroke-based rendering,下称SBR),简单的讲就是根据图像生成笔触,然后再用笔触对图像进行重绘。这个过程实际上是模仿画家实际画画的过程,也就是观察->理解->表达的过程,画画的时候有一句话叫意在笔先也就是这个意思。具体可以看这篇关于SBR的综述:luthuli.cs.uiuc.edu/~da (luthuli.cs.uiuc.edu/~daf/courses/ComputerGraphics/01210867.pdf)。

为什么要在Unity中实现SBR

研究生的时候我是研究非真实性渲染(Non-Photorealistic Rendering,下称NPR)的,发现本质上有两种方法,一种是基于经验的研究方法,也就是没有理论根据,根据实验结果来设计渲染方法。好像有个图形学大佬说过:看起来是对的,就是对的。大概说的就是基于经验的研究方法。还有一种是基于物理模拟的研究方法,比如研究颜料的实际混色和水分的流动等等。

我发现基于经验的方法有点凭感觉,无论是设计算法还是评判结果都不好弄。基于物理模拟的研究方法又是太笨重,只是在计算机中再现了工具和颜料,而怎么画还是靠艺术家手工去画。于是我在想,怎么让计算机真的像艺术家一样去思考,去表达呢。

刚好以前接触过一点计算机视觉,于是在想有没有一种基于视觉的研究方法,让计算机去理解图像,然后像人一样去画,也就是渲染,而不是用一堆滤波器。

那时候用了opencv去做图像分割,然后计算图像的显著度(saliency),再根据显著度生成笔刷,最后用cuda并行地渲染笔刷,做了这样一个离线版本的SBR。效果还不错,但是工作之后这个研究就放下了。

最近开始学习Unity的Compute Shader,发现跟cuda很像,于是又想起了SBR,感觉用Unity可以在后处理中实现的SBR,于是做了一些尝试。

具体的实现方法

所有处理都写在post processing stack的render里面,流程大概如下:

如何在Unity中实现基于笔触的实时渲染

其中梯度张量的经过高斯平滑后,称为平滑化梯度张量,求法如下:

如何在Unity中实现基于笔触的实时渲染

IGa为高斯滤波的卷积运算,px为sobel算子计算的x方向的梯度,py为sobel算子计算的y方向的梯度。至于为什么用SVD分解求得的第二特征向量来计算旋转矩阵,那是因为第一特征向量(主特征向量)表明的是变化最大的朝向,而第二特征向量与之正交,所以可以用来表明笔触的流向。

渲染结果:

左边为原帧,右边为SBR渲染后的效果:

基于笔触的实时渲染

另外,笔触的间隔和的大小可以调节出不同的效果:

笔触的间隔和的大小可以调节

不同笔触纹理可以有不同的渲染效果:

如何在Unity中实现基于笔触的实时渲染
如何在Unity中实现基于笔触的实时渲染

代码

(github.com/alpacasking/SBR)

时间有限,现在只写了最基本的流程,其实还有很多东西值得做,比如:

  • 根据深度纹理检测前景和背景,从而生成不同密度和大小的笔触

  • 利用CV相关知识分析理解图像再生成笔触

  • 同时用不同的笔触纹理渲染

  • 让每帧之间的笔触衔接得流畅

  • 可以为油画,水彩风格等做进一步的研究

有时间的话会慢慢加上的,各位有兴趣的话也可以自行魔改。

关于如何在Unity中实现基于笔触的实时渲染就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


分享题目:如何在Unity中实现基于笔触的实时渲染
本文链接:http://myzitong.com/article/ihjggi.html