【入门】PBR和NPR 了解不同风格渲染

PBR和NPR简述

PBR(Physically-Based Rendering)基于物理的渲染

这里有一个细节:基于物理的渲染只是基于现实物理的特性而进行的渲染,并不能完全与现实物理一致
有的人也会说PBS(Physically based shading)基于物理的着色,二者其实是包含关系,PBR中包含基于物理的着色(PBS)、基于物理的光照(PBL)以及基于物理的摄像等,一般描述物理材质的制作会说PBS但实际这也属于PBR流程的一部分,所以说PBR也是可以的。

NPR(Non-Photorealistic Rendering)非真实感渲染

与PBR不同,NPR不需要过度的在乎渲染的真实性和物理特性,主要追求最终的渲染效果与风格,像是一些卡通渲染,我们经常听到的三渲二就是非真实渲染的内容,主要追求最终的美术效果而非真实感。

PBR实现理论

渲染本质上就是计算出物体在某一种打光下的特定角度观看到的每一个点的颜色,那么PBR也就是模拟现实中光线的传播,折射,衰减等最终呈现在摄像机位置的样子
那么由此PBR光照模型的三个构成条件诞生了:

1.基于微表面模型的理论

我们都知道光照到物体表面会产生反射,越光滑的物体反射方向就越一致,得到的反光越规整,越粗糙的物体反射方向越乱,我们得到的反光就会越粗糙(但注意,这里和漫反射效果要区分开,即使是粗糙的反射光也是镜面反射,不能归为物体的漫反射。可以想象一下哑光的金属,即使表面粗糙但依然呈现出极强的镜面反射效果,这就不算是漫反射)
那么基于这种思路我们可以把模型表面抽象成细小的镜面,越粗糙的表面这些细小的镜面排列越混乱,反射方向就会越乱,从而得到粗糙的反射效果,而相反这这些微小镜面排列越规整,光线反射越规整,越能表达光滑的平面
此时我们假设一个球形材质并为他打上光,如果在某个特定角度放上相机进行观测,那么我们会发现:微表面排列越规则,镜头方向能得到反射的区域就会越小,因为所有光线的反射角度都是规则的。只有很小的区域能够恰好将光线反射到相机。如果微表面排列越混乱,我们镜头方向能得到反射的区域会因为反射角度随机而变大,同时反射区域内也会因为随机而导致有一部分光线无法反射进相机,那么最终我们会得到反射区域更大,亮度更低的反光区域。

2.基于能量守恒的光线反射理论

一束光照射到水里,会发生反射和折射。如果我们仔细观察,会发现反射光和折射光比入射光线要浅,这是由于光线被分离成了反射和折射两部分。显然这种时候仅靠微表面模型理论已经无法描述了,因为他并没有考虑光线折射进入内部的情况。
我们再仔细观察,发现光线进入水中使得水体本身也呈现出一些发光效果(不明显可以尝试矿泉水放手机闪光灯上),这是由于折射进水体的光在水内继续发散折射,有一部分进入水内的光线经过多次折射又跑了出来,使水本身好像拥有了发光的效果。这些跑出来的光经过了多次的随机折射,本身的光线朝向已经被打乱,朝向四面八方的光让水体看起来好像在发光一样。那么为了好区分,我们将跑出来的光线称为漫反射,而光线进入水面时折射的那部分则被称为镜面反射。
并不是所有材质都像水一样透明,那些不透明的材质虽然不会发生像水这么亮的漫反射,但依然会存在这种现象。并且由于不透光的性质使大量的光能量耗尽却没能再次反射出来,即使是水,也不可避免的会有光线进入水体之后多次折射能量耗尽而没能再次折射出水面,这就是光线在物体内的衰减了。那么根据材质物理特性的不同,会导致特定光谱的光线更容易穿透出来,也就让物体表面有了颜色。由此我们也可以得出另一个结论:如果材质本身不是发光体,那么由于反射和吸收,出射光永远不会超过入射光线的能量。
然而落实在实际渲染上由于计算量的问题,我们不可能全部模拟出物体内部折射光的多重反射来实现漫反射效果,所以在基于物理的渲染之中我们进行了简化,假设对平面上的每一点所有的折射光都会被完全吸收而不会散开,结合模型的贴图设定,我们会让物体表面贴图的颜色来模拟现实中的这种漫反射效果。
基于以上理论,我们只需要调整反射、漫反射与折射光强度,就可以获得不同的镜面反射和漫反射效果,也就可以更加准确的表达出不同的材质:
比如金属物理特性光线很难穿透,入射光几乎完全被吸收,所以我们可以将材质的漫反射降到很低甚至去除,只保留镜面反射。那么在此基础上我们进行微表面的排列操作即可获得光滑的金属和哑光金属材质。
或者上面说到的简化过的漫反射不计算折射光进而通过贴图来实现,假如我们牺牲计算量优化选择进行光线的折射光以及漫反射运算,就可以实现一些诸如皮肤、玉石、蜡块的次表面散射效果

3.基于物理的BRDF

BRDF即双向反射分布函数
上面说到通过贴图来模拟漫反射从而减少运算量,但这样会有一个问题,贴图只是一张固定图片,它本身没有阴影信息。也就是说漫反射的强度还是需要计算。并且上述微表面和能量守恒都是理论,无法在程序层面灵活进行运用,那么落实到程序实现,我们可以通过BRDF函数来计算出模型在各种情况下贴图与环境进行交互后的结果。用比较官方的说法就是:解决了从某个方向发射过来的某些能量会被反射到什么方向以及会分别分布多少能量的问题。
这个方程会被运用在很多其他的方程推导和实现中,BRDF有好几种模拟表面光照的算法,每种侧重点和效果有所不同。因为本文为入门笔记,加之篇幅原因不会过多深入,理解是什么即可,感兴趣可以自行深入理解。

NPR实现理论

NPR最核心的处理在于使用色块表现体积感,因为要追求手绘感因此光影之间的过度不会非常圆滑,一般还会加上描边线增强效果
要实现基本的卡通效果一般要实现四部分:

1.简化阴影

由于引擎默认的光照是写实光照,要做到卡通效果首先要对阴影的过度进行简化,这里会分为美式卡通风格和日式卡通风格,美式卡通风格一般会有较多色阶过度,色彩上会有比较多的渐变色,阴影的处理也会比较大胆和夸张,而日式卡通一般使用纯色色块进行着色,整体会更偏向现实一点,不会有过于夸张的表现,阴影通常表现为赛璐璐样式的二分阴影,带有很明显的分界线
通常情况下,使用基于兰伯特光照模型得到的 NDotL(法线方向点乘光入射方向)可以计算出一个物体的顶点光照结果。此时的结果为物理光照效果,我们只需要在此基础上使用step函数对计算结果进行二值化,就可以得到一个基础的二分阴影效果
除此之外还有第二种实现方式,使用 Ramp 贴图来定义光照情况下的颜色,从而控制阴影的外观:在顶点着色器中,计算NdotL(法线与光照方向的点乘),并将结果作为采样 Ramp 贴图的 U 轴坐标。这样,Ramp 贴图的纹理坐标根据光照角度进行采样,将采样到的Ramp图的颜色与模型基础贴图颜色进行混合,得到最终的颜色。这种方式的好处在于阴影颜色可以更加灵活的定义,尤其是对于一些皮肤或者丝袜材质可以实现很漂亮的阴影过渡色带(有点像次表面?)

2.法线修正

使用上述方法简化阴影后会发现有的地方会有明显的阴影异常,尤其是角色模型的面部,由于默认的光照模型计算,面部的模型较为复杂,简单对阴影进行二值化会出现很奇怪的阴影块。尤其是在面部,对于NRP来讲非常影响观感。那么我们就可以通过对面部的法线进行统一方向的操作来平滑面部的阴影。
目前有三种方式来实现:
第一种就是借助法线修正工具来对面部的法线进行调整,使其统一朝向,但这样会有很大的弊端,法线的变化会影响很多其他的效果,并且法线的调整就算有工具也比较麻烦。
第二种方式可以通过将另一个球形的法线信息转移到角色面部。这通常是通过在角色模型上创建一个球形投影,然后将球形的法线信息传递给角色模型的表面,使角色的面部使用球形的阴影效果实现平滑阴影
第三种方式可以使用SDF贴图,在着色器中根据贴图中的距离信息来调整阴影计算。这样可以在面部产生更加可定义的平滑阴影,避免了法线对阴影的影响。

3.添加描边线

为了使3D模型更具有动画感,描边线是必不可少的,目前基本上有四种实现方式:
1.本村线:本质就是为一些内描边画贴图线。优点是线条真实(毕竟是真手绘)。缺点也很明显:不能实现外描边,只能做衣服或肌肉骨骼的内描边线条
2.多通道渲染:本质就是将模型复制一份再放大,将大于原模型的位置调整为描边线。具体实现:创建一个新的 Shader,包含两个 Pass,一个用于正常渲染模型,另一个用于描边效果。在描边效果的 Pass 中,通过在顶点着色器中沿着法线方向进行位移来实现对模型进行一定程度的外扩,之后剔除模型正面。之后在描边效果的 Pass 中,对颜色进行一定的处理就完成简单的实现了。
3.基于屏幕后处理使用法线和深度信息进行边缘检测,最终实现描边线效果。但这种方式不好调整线条,并不推荐。
4.将菲涅尔效果调节为非常小的值,使其成为边缘轮廓的形状,然后在做颜色处理。优点是实现简单,缺点是形成的轮廓并不是很可控,并且粗细不均因有些不像线条,另外颜色处理也很麻烦。

4.高光边缘光处理

高光处理主要体现在头发上,日式赛璐璐经典的天使环状高光是肯定需要单独实现的,可以使用Kajiya-Kay或者Marschner实现,也有用各向异性来实现或者直接在画在贴图上的
边缘光较为简单的方法是使用菲涅尔效果获取到模型边缘的Mask,然后进行边缘光调色即可实现简单的效果。

  • 29
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值