概述
本篇内容比較簡單,主要介紹非真實感渲染中的幾種輪廓線實作方法,再介紹一下卡通着色和素描風格的渲染技術。
一、表面角度輪廓線
實作思路:利用視線方向和頂點法線的點積,得到輪廓線的資訊。點積越接近0,說明距離輪廓線越近。
這種方式的優點是,隻需要一個Pass就可以得到結果,簡單、快速。
但缺點也很明顯,隻适用于某些類型的模型,對于像Cube這樣的模型就會有問題。由于這種方法渲染得到的輪廓線寬度不均,實際應用不多。
效果如下:
代碼如下
二、程式幾何輪廓線
實作思路:使用兩個Pass渲染,第一個Pass正常渲染,渲染前面;第二個Pass渲染輪廓線,渲染背面。使用某些技術讓背面可見。
下面介紹幾種渲染背面的方法。
1、Vertex Normal法
思路:在頂點着色器中把頂點法線變換到觀察空間,統一設定變換後法線的Z值,然後,把觀察空間的頂點沿着法線方向移動一段距離。最後,變換到裁剪空間中。如下圖所示:
代碼如下
2、Z Bias法
思路:在頂點着色器中,把頂點變換到觀察空間,然後控制頂點的Z值移動一段距離,最後,變換到裁剪空間中。如下圖所示:
代碼如下
三、卡通着色
思路:使用兩個Pass渲染。第一個Pass正常渲染;第二個Pass可以直接使用上面的Vertex Normal法中的輪廓線Pass,用來渲染輪廓線。
主要的内容在正常渲染的Pass。
這裡,需要分别計算環境光照、漫反射和高光。
環境光照沒什麼需要多說的。
half3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo.rgb;
漫反射部分的話,有些不同。這裡不是直接根據法線和光線的點積來計算漫反射顔色。而是使用法線和光線的點積來采樣一張漸變紋理,這樣,漫反射的明暗變化會更加可控。
float diff = Convert01(dot(normalWS, lightDirWS));
half3 diffuse = mainLight.color * albedo.rgb * SAMPLE_TEXTURE2D(_Ramp, sampler_Ramp, float2(diff, diff)).rgb;
高光部分,也有些不同。根據法線和半向量的點積,與高光門檻值比較,控制高光的範圍。
half spec = dot(normalWS, halfDir);
half w = fwidth(spec) * 2.0;
half3 specular = _SpecularColor.rgb * albedo.rgb * smoothstep(-w, w, spec - _SpecularThreshold);
最後,把三者相加得到最終的顔色。
代碼如下
四、素描風格渲染
思路:使用多張紋理,代表不同光照角度下的素描風格。在頂點着色器中,計算頂點法線和光照方向的點積,根據得到的結果,判斷應該采樣哪幾張紋理。最後,在片元着色器中對各張紋理根據權重進行混合,得到最終的效果。
代碼如下
五、總結
本篇文章談的内容比較淺顯、雜亂。先對相應的内容有個大概的印象,後面需要的話再詳細地對相關知識點進行學習。
參考
- [1] 《Real-Time Rendering 4th Edition》15.2.2節
- [2] 《Unity Shader入門精要》第14章
- [3] 【NPR】漫談輪廓線的渲染