《Manifold Garden》中的模型描邊是怎麼實現的?
我發現《Manifold Garden》這個遊戲還是非常漂亮的。就是想知道它的描邊是是怎麼實現的,是寫Shader做的么?我覺得應該不可能是貼圖畫出來的吧......
感覺在一些渲染軟體裡面,像這樣渲染出線框都是非常簡單的,但為什麼我在Unity里卻總也做不出那種效果?感覺這種風格很漂亮,想學習一下,望大神賜教,謝謝。就是下面圖中那樣的
顯然不是用視角方向點乘頂點法線的方法,遊戲里大量使用了正方體這樣的模型,這是這種判斷角度來描邊的方法的死穴!同樣,沿法線擴張也肯定不行啊,artifacts分分鐘出現(【NPR】漫談輪廓線的渲染)!
這個遊戲我關注很久了,大概是2014年的時候吧,忘記怎麼發現作者的網站(http://willychyr.com/blog/)了,總之被這種美術風格強烈地吸引了,作者是個對藝術和技術都有追求的人,令人敬佩的獨立遊戲人。
回到正題,這種描邊效果是靠屏幕空間里的邊緣檢測實現的,其實就是一種屏幕特效,靠一些邊緣檢測運算元檢測屏幕空間法線的變化率,超過某個閾值則認為需要描邊。所以如果兩個正方體離得很近就不會有描邊了:
作者曾寫了一篇關於改進邊緣檢測的文章(http://williamchyr.com/2015/03/edge-detection-shader-artifacts-fixed/)。
當然了,這麼檢測鋸齒還是挺嚴重的,這遊戲畫面看起來這麼夢幻肯定使用了各種AA、Bloom、Vignette等等畫面特效,人家是主機遊戲,這種特效加起來還不是毫不猶豫的么
哦補充一句,這遊戲就是拿Unity做的unity里的line renderer令人髮指的難用,有時候還會出現扭轉的情況(我的經驗是不要出現&<=90°的轉角...)
有個插件叫Fast Line Renderer for Unity,還不錯實在不行GL.Lines繪製也行。。。具體這個遊戲怎麼做的,得等遊戲出來GPA或者NSight一發即可(嘿嘿嘿確實是可以用 Shader 實現的,關鍵詞:卡通渲染(Cartoon Render)。
一言以蔽之,卡通渲染可以簡單地理解為「減少模型的顏色層級,並增加描邊」。
《Manifold Garden》中並沒有採用前半段(本身模型顏色單一),而主要是添加粗細均勻的描線。Shader "Custom/ToonShader" {
Properties {
_Color("Main Color",color)=(1,1,1,1)//物體的顏色
_Outline("Thick of Outline",range(0,0.1))=0.02//擠出描邊的粗細
_Factor("Factor",range(0,1))=0.5//擠出多遠
_ToonEffect("Toon Effect",range(0,1))=0.5//卡通化程度(二次元與三次元的交界線)
_Steps("Steps of toon",range(0,9))=3//色階層數
}
SubShader {
pass{//處理光照前的pass渲染
Tags{"LightMode"="Always"}
Cull Front
ZWrite On
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float _Outline;
float _Factor;
struct v2f {
float4 pos:SV_POSITION;
};
v2f vert (appdata_full v) {
v2f o;
float3 dir=normalize(v.vertex.xyz);
float3 dir2=v.normal;
float D=dot(dir,dir2);
dir=dir*sign(D);
dir=dir*_Factor+dir2*(1-_Factor);
v.vertex.xyz+=dir*_Outline;
o.pos=mul(UNITY_MATRIX_MVP,v.vertex);
return o;
}
float4 frag(v2f i):COLOR
{
float4 c=0;
return c;
}
ENDCG
}//end of pass
// ... 下略,關係到描線的就是這一部分。完整版可以下載工程查看。
}
}
3. 新建一個材質,在材質中選擇 Custom-&> ToonShader;
4. 將材質賦給需要用卡通方式渲染的對象。這樣一來就可以給模型加上邊緣的描線了。
(我只是個搬運工,Shader 方面還在入門學習中)
參考資料:
用 3D 渲染來創作漫畫,可行性高嗎? - 遊戲卡通渲染的業界現狀? - 3D特別聲明:本段 Shader 代碼非本人所寫出自原網頁:Unity3d shader之卡通著色Toon Shading
另外,題目中提到「渲染出線框」……這個其實是兩個方向。
這一邊的關鍵詞是 線框渲染(Wireframe Render)。最簡單的,使用前人的勞動成果,直接去 Unity Store 購買相關的 Shader:商店鏈接:Asset Store加州大學洛杉磯分校出的線框 Shader,免費使用。但是僅限 Windows 平台,而且需要 DirectX 11 支持。我下載過來沒法用,所以祝你好運。商店鏈接:Asset Store
這個 25 美刀,但是效果看上去非常棒。線框都是實時渲染出來的,不局限於模型本身的線框。例如這個液體混合的模型,線框也會實時改變。預覽視頻(需翻牆):https://www.youtube.com/watch?v=dCL_SdBMVq8
另外也有自己手工加 Shader 的方式,分兩層渲染,一層純渲染線框,一層按原樣渲染,疊加即可。
同樣是兩種辦法,直接加線框渲染的 Shader。
Shader 內容如下……太長了不放了,感興趣直接下載範例工程查看吧。卡通渲染及線框渲染的演示工程(百度網盤):http://pan.baidu.com/s/1boU1agR
或者也可以直接給攝像機加一個腳本:// from http://docs.unity3d.com/ScriptReference/GL-wireframe.html
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
void OnPreRender() {
GL.wireframe = true;
}
void OnPostRender() {
GL.wireframe = false;
}
}
如此一來該攝像機渲染出來的對象就都是線框模式,使用兩個攝像機疊加顯示即可。
(這種不用每個模型單獨設置,更方便)對了順便一提,還有個逆(ma)天(fan)的方法你應該也能想到。
展開 UV,保留邊線,然後直接作為貼圖。這個就……嗯,不咋有實用性,隨口帶過啦。參考資料:
基礎工程來源:Wireframe shader for Unity腳本方式實現:unity - Display and render only a specific object in wireframe in Unity3D攝像機腳本:unityscript - Display and render only a specific object in wireframe in Unity3D藉助 Blender 的另一種實現方式:Creating 3D Holograms for Unity
描邊有3類。
3d空間,增大模型,沿著法線,或者其它增大方法,反面繪製一次,接著正面正常繪製, 反面繪製時候不寫z。問題,頂點法線方向不一致,導致模型拆散,某些面看不見而沒有建模,導致缺失。3d空間,rimlight, 用邊緣光偽裝描邊。邊緣法線不好控制。
問題 邊緣太粗。屏幕空間,將場景正常渲染,接著用場景深度執行邊緣檢測,繪製描邊。
上面繪製的是outline,外輪廓,但是遊戲中不是, 待續看起來就是普通的卡通渲染。分以下兩步:1.描邊:簡單的做法是取相機方向和像素法線的點積,小於閥值即為邊。(一般有兩種實現方式,第一種是兩個三角形組成一條帶寬度的線,動態軟計算並構建邊網格,單獨渲染;另一種是直接在shader里kill掉非邊像素)。2.顏色分層,即把顏色通道歸納幾種顏色,比如把r通道分為兩個區間層,淺紅(0.0,0.4)和深紅(0.4,0.6),當顏色值為0.5的時候直接替換為深紅。實現方式直接在shader里做判斷或把顏色通道區間層傳入shader查表都可以。這樣就實現了卡通風格有邊且色塊明顯的效果。
asset store上的 Wireframe Shader Artist,
我也被這個問題
困擾了很久,然後用這個插件做出了你想要的效果的,這個可以調節三角面超過一個彎折角度後才畫線,希望能夠幫到你
如果是opengl3.3或dx10以後的卡,可以利用geometry shader來做這件事。
之前在3Dmax里找到過這種渲染,好像要用very,然後在內窗口裡調成卡通模式。
原理應該是兩個相交的面角度大於45度,加上黑線,不會寫代碼
推薦閱讀:
※如何進一步學習 shader (CG) 的知識?
※在頂級遊戲開發的過程中需要怎樣的編程實力?
※unity和ue4以後那個發展好?
※Unity 3D引擎有多強大?
※如何評價「仙劍奇俠傳六」使用Unity 3D引擎?