白纸一张

三十而立,四十而不惑

0%

练习项目(十):非真实感渲染的几个小知识点

概述

本篇内容比较简单,主要介绍非真实感渲染中的几种轮廓线实现方法,再介绍一下卡通着色和素描风格的渲染技术。

一、表面角度轮廓线

实现思路:利用视线方向和顶点法线的点积,得到轮廓线的信息。点积越接近0,说明距离轮廓线越近。

这种方式的优点是,只需要一个Pass就可以得到结果,简单、快速。

但缺点也很明显,只适用于某些类型的模型,对于像Cube这样的模型就会有问题。由于这种方法渲染得到的轮廓线宽度不均,实际应用不多。

效果如下:

代码如下

二、程序几何轮廓线

实现思路:使用两个Pass渲染,第一个Pass正常渲染,渲染前面;第二个Pass渲染轮廓线,渲染背面。使用某些技术让背面可见。

下面介绍几种渲染背面的方法。

1、Vertex Normal法

思路:在顶点着色器中把顶点法线变换到观察空间,统一设置变换后法线的Z值,然后,把观察空间的顶点沿着法线方向移动一段距离。最后,变换到裁剪空间中。如下图所示:

代码如下

2、Z Bias法

思路:在顶点着色器中,把顶点变换到观察空间,然后控制顶点的Z值移动一段距离,最后,变换到裁剪空间中。如下图所示:

代码如下

三、卡通着色

思路:使用两个Pass渲染。第一个Pass正常渲染;第二个Pass可以直接使用上面的Vertex Normal法中的轮廓线Pass,用来渲染轮廓线。

主要的内容在正常渲染的Pass。

这里,需要分别计算环境光照、漫反射和高光。

环境光照没什么需要多说的。

1
half3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo.rgb;

漫反射部分的话,有些不同。这里不是直接根据法线和光线的点积来计算漫反射颜色。而是使用法线和光线的点积来采样一张渐变纹理,这样,漫反射的明暗变化会更加可控。

1
2
float diff = Convert01(dot(normalWS, lightDirWS));
half3 diffuse = mainLight.color * albedo.rgb * SAMPLE_TEXTURE2D(_Ramp, sampler_Ramp, float2(diff, diff)).rgb;

高光部分,也有些不同。根据法线和半向量的点积,与高光阈值比较,控制高光的范围。

1
2
3
half spec = dot(normalWS, halfDir);
half w = fwidth(spec) * 2.0;
half3 specular = _SpecularColor.rgb * albedo.rgb * smoothstep(-w, w, spec - _SpecularThreshold);

最后,把三者相加得到最终的颜色。

代码如下

四、素描风格渲染

思路:使用多张纹理,代表不同光照角度下的素描风格。在顶点着色器中,计算顶点法线和光照方向的点积,根据得到的结果,判断应该采样哪几张纹理。最后,在片元着色器中对各张纹理根据权重进行混合,得到最终的效果。

代码如下

五、总结

本篇文章谈的内容比较浅显、杂乱。先对相应的内容有个大概的印象,后面需要的话再详细地对相关知识点进行学习。

参考

-------------本文结束感谢您的阅读-------------