在第四篇的简单光照模型中,做了一个简单的卡通着色器。对的,讲的思路是冯氏着色的方法,但是最后做出来的实际上是卡通着色。

原因很简单,是因为像素着色器里 这一行的效果。


(资料图)

什么是lerp?什么是saturate?为什么要 LightNormal*16+0.5?

为了方便观察,在这里放置一个球。球可以在PE里快速建出,记得随便贴上个纯色的贴图,还有toon。放上简单光照的fx效果,如图。光照部分和阴影部分有较为明显的二分。所以是非真实感渲染 (Non-Photorealistic Rendering) ,NPR。

实际上把后面的*16+0.5删掉就可以得到 真实感渲染(Photorealistic rendering)。

为了看得更明显,所以这里调整了一下强度和颜色。可以看到这种层层的渐变效果。真实渲染 旨在渲染真实感的画面,而NPR则追求更加有艺术感的画面效果。

回到最开始的问题,什么是lerp?

lerp函数,是经常用的插值函数。其意义是 lerp(a,b,w),计算 a + w*(b-a),在a和b之间插值,w表示权值,范围0~1。

为了看得更明显,我们可以把前边的MaterialToon改成float3(0,0,0),这样就是黑色,与白色,进行插值。

saturate函数,很好理解,saturate(x)将x的数值,截取在0-1之间。

接下来我们更改一下LightNormal*16,从左到右依次是*32,*64。可以看到,边缘的强烈分割。

还有一个插值函数,smoothstep,作用和用法跟lerp一致,但两者之间有一定的区别,这里不多赘述,因为用不到。可以借鉴学习https://blog.csdn.net/qq_41835314/article/details/128618789

最后一个问题,为什么要 LightNormal*16+0.5?

通过修改数值能够有所体会,若想究其原理,需要拿出纸笔,动手算算或者思考一下。

1.在球的光照亮面取一个点,边缘上取一个点,暗面取一个点。

2.用float LightNormal = dot(Normal,-LightDirection)

分别算出LightNormal的正负,大小的排序。

3.saturate(LightNormal*16+0.5),取得三者权重,然后分别插值。

关于HLSL中的函数,这里就不搬运了,参考微软官方文档,或者参考https://blog.csdn.net/eloudy/article/details/71258367

推荐内容