Unity Shader 风格化水体渲染

您所在的位置:网站首页 toon的用法 Unity Shader 风格化水体渲染

Unity Shader 风格化水体渲染

#Unity Shader 风格化水体渲染| 来源: 网络整理| 查看: 265

风格化渲染(stylized rendering)的具体定义我没能找到,但是在一些文章中,风格化渲染就是指那些非写实的(Non Photorealistic Rendering)渲染。 其中卡通风格的渲染(Toon Shading)是一种典型的风格化渲染。提到风格化渲染,那就绕不过旷野之息。

为此,俺打开了积灰已久的switch,重新看了看这里面的水体渲染是什么样的。 和我印象中不同,旷野之息里面的水体还是比较偏写实的,并没有明显的卡通风格,如下图所示(拍屏党)。

不过还是有些风格化的地方,比如游泳的时候,产生的浮沫是完整的、厚厚的一圈。

之后,俺又去B站找了些做得挺好的风格化水体渲染的效果,例如【JTRP】风格化水体渲染_哔哩哔哩_bilibili

 我们把它和真实感水体渲染比较一下:1. 水体颜色同样基于深度差,但是深水颜色和浅水颜色变化不用很明显,整体颜色相差较小。2. 折射效果相似,但是折射也不是很明显,主要显示水体的基础颜色。3.反射同样不明显,但是在菲涅尔系数较大的时候还是有。4. 浮沫很明显,厚厚的一圈。 5. 高光区域比起真实感的高光也做了调整。

按照这个思路,我们尝试实现一下风格化水体渲染。这篇文章是在之前做的真实感水体渲染的基础上修改的,因此读者可以先看看之前的那篇文章Unity Shader 真实感水体渲染 - Kimi_Raikkonen - 博客园 (cnblogs.com)

1. 水体基础颜色

我们把真实感渲染中的渐变纹理替换成一个浅水区颜色和深水区颜色,并通过一个深度系数depthCoef进行插值。此外用一个指数_AbsorbExp模拟非线性的变化。

half depthCoef = pow(saturate(deltaDepth / _AbsorbCutOff), _AbsorbExp); fixed3 absorbColor = lerp(_ShallowColor, _DeepColor, depthCoef);

 

2. 折射和反射修改

我们希望折射和反射不要太明显,主要显示水体的基础颜色。

因此在折射和基础颜色进行插值时,更偏向基础颜色。在反射颜色和折射颜色插值时,更偏向于折射颜色(也就更偏向水体基础颜色)。为此,我换了一个菲涅尔系数的计算公式

fresnel = (1 - F0)(1 - n·v)5  

这样,通过调整F0可以使得反射为0,而之前那个公式计算出的反射系数是始终大于0的。

 

3. 浮沫

与真实感水体渲染不同,风格化渲染的浮沫是完整的一圈,有浮沫的区域纯白(或者自定义的浮沫颜色),要么就没有浮沫。

我们仍然用_FoamDistance控制浮沫产生的区域,通过下式计算出一个noiseCutOff,用于等会儿和噪声的采样值比较

half noiseCutOff = _NoiseCutOff * max(deltaDepth / _FoamDistance, 0.2);

这个式子可以多调整调整。水越深让noiseCutOff越大就可以了。这里用了一个max函数是为了让noiseCutOff计算出来不至于为0,不然整个水面都是浮沫了。

之后我们对一张噪声纹理采样(俺这里用的是一张Perlin Noise),得到采样值noise,和noiseCutOff比较,noise > noiseCutOff就产生浮沫。深水区由于noiseCutOff较大,是不会出现浮沫的。

half noise1 = tex2D(_FoamTex, i.uv_foam + _Time.y * half2(_FoamSpeedX, _FoamSpeedY)); half noise2 = tex2D(_FoamTex, i.uv_foam - _Time.y * half2(_FoamSpeedX, _FoamSpeedY)); half noise = 0.5 * (noise1 + noise2); fixed foam = (noise > noiseCutOff)? 1 : 0; finalColor += foam * _FoamColor;

 

4. 焦散

和真实感水体渲染一样,加上焦散。可以多试试不同的焦散贴图。

 

 

5. 高光修改

感觉高光也是和真实感渲染区别的重要部分。像上面这张图,高光和水面其它地方有些不在一个画风。

我感觉是,卡通风格的水体上,高光区域里高光的变化不会那么柔和。因此我把Blinn-Phong高光项里面计算出来的较小的高光值给舍弃了,然后让比较大的高光值更偏向1,也就是整个高光区域更偏向纯白色。

是的,smoothstep函数刚好能满足这个要求。

half spec = pow(saturate(dot(worldNormal, halfwayDir)), modGloss); spec = smoothstep(_SpecCutOff, 1.0, spec);

这样计算出来高光值比较大的部分都更偏向1,就能起到和风格化水面比较匹配的波光粼粼的效果。

 

 

References:

【JTRP】风格化水体渲染_哔哩哔哩_bilibili

 Unity Toon Water Shader Tutorial (roystan.net)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3