unity shader 剔除

當(dāng)一個(gè)mesh組件的信息被傳遞后选酗,我們可以通過代碼決定哪些部分渲染(render)出來阵难,而哪些部分不要,這個(gè)過程就像把那些不要的部分剔除了星掰,我們看不到他多望,雖然他的mesh信息還在,但是我們的GPU不會(huì)去處理它氢烘,肯定比剔除前GPU的性能消耗要低怀偷。這個(gè)過程就好比我們的mesh組件是一個(gè)透明的膜,我們假設(shè)這個(gè)膠紙我們根本看不到播玖,而片段著色器在著色的時(shí)候像毛筆選擇性地上色椎工,最后的效果是我們可能看到膜的一部分是可見的,但是不見的地方蜀踏,膜還是存在的维蒙,只是我們沒有給他上色,我們既看不看他們果覆,也不需要再他們上面畫寶貴的墨水(GPU并行處理能力)
所以我們可以來改造一下上一個(gè)例子中的經(jīng)度綠色假彩色球體颅痊,將其經(jīng)度>0.5的部分擦掉,那么代碼應(yīng)該相應(yīng)修改為:

Pass{
Cull front // 外部剪裁,那么這個(gè)通道可以理解為是給籃球的內(nèi)表面上色
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vertexOutput {
float4 pos : SV_POSITION;
//由頂點(diǎn)著色器輸出mesh信息中的紋理坐標(biāo)局待,這個(gè)坐標(biāo)是以對(duì)象為坐標(biāo)系的
float4 posInObjectCoords : TEXCOORD0;
};
vertexOutput vert(appdata_full input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
//直接把texcoord傳遞給片段著色器
output.posInObjectCoords = input.texcoord;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
//當(dāng)坐標(biāo)的y值大于0.5的時(shí)候擦除片段
if (input.posInObjectCoords.y > 0.5)
{
discard;
}

//其余部分仍然按y值大小生成經(jīng)度綠色球
return float4(0.0, input.posInObjectCoords.y , 0.0, 1.0);
}
ENDCG
}

Pass{
Cull back //內(nèi)部剪裁斑响,那么這個(gè)通道可以理解為是給籃球的外表面上色
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct vertexOutput {
float4 pos : SV_POSITION;
//由頂點(diǎn)著色器輸出mesh信息中的紋理坐標(biāo)菱属,這個(gè)坐標(biāo)是以對(duì)象為坐標(biāo)系的
float4 posInObjectCoords : TEXCOORD0;
};
vertexOutput vert(appdata_full input)
{
vertexOutput output;
output.pos = mul(UNITY_MATRIX_MVP, input.vertex);
//直接把texcoord傳遞給片段著色器
output.posInObjectCoords = input.texcoord;
return output;
}
float4 frag(vertexOutput input) : COLOR
{
//當(dāng)坐標(biāo)的y值大于0.5的時(shí)候擦除片段
if (input.posInObjectCoords.y > 0.5)
{
discard;
}

//其余部分仍然按y值大小生成經(jīng)度紅色球
return float4(input.posInObjectCoords.y, 0.0 , 0.0, 1.0);
}
ENDCG
}

//其余部分仍然按y值大小生成經(jīng)度綠色球return float4(0.0, input.posInObjectCoords.y , 0.0, 1.0);}ENDCG}
那么把這個(gè)shader給material,然后給一個(gè)球體可以看到我們上次見到的綠色假彩色球只剩下南半球了:

從正面看起來像是實(shí)心的

稍微傾斜一下從上面看過去可以看到球體內(nèi)部是空心的舰罚,所以我用膜和毛筆來比喻這個(gè)render過程纽门。
我們來把球體換成立方體,看看是什么樣子:

可以發(fā)現(xiàn)這是一個(gè)詭異的立方體营罢,立方體的六個(gè)面分別只繪制了一半赏陵,且都是下面的一半。為啥立方體和球體上的效果差別這么大呢饲漾?因?yàn)榱⒎襟w是直角坐標(biāo)系蝙搔,球體是極坐標(biāo)系啊…………扇耳光~~~還給老師了嗎 嗎嗎嗎嗎嗎
同理我們將>0.5改為<0.5,就可以得到球體的北半球能颁。
這是最簡單的表面剔除(cuteaway)
更好一點(diǎn)的表面剔除是將片段的位置從對(duì)象坐標(biāo)系轉(zhuǎn)換到世界坐標(biāo)系杂瘸,然后根據(jù)基礎(chǔ)矩陣進(jìn)行變換可以計(jì)算出哪些片段位于其他球體的內(nèi)部(原始半徑是0.5),然后再將位于其他球體內(nèi)部的表面剔除伙菊,這樣的話假如兩個(gè)球互相重疊一部分败玉,那么即使兩個(gè)球互相繞著自己的球心怎么旋轉(zhuǎn),沒有重疊的部分都會(huì)被繪制运翼,而重疊的部分不會(huì)被繪制兴枯,反正我們看不到,這樣省性能悠夯。因?yàn)榧词骨蝮w旋轉(zhuǎn)躺坟,物體的坐標(biāo)經(jīng)過unity的內(nèi)建矩陣變換為世界坐標(biāo)后,重疊部分的世界坐標(biāo)是固定的夕膀,所以不會(huì)出現(xiàn)兩個(gè)球體重疊部分表面被裁剪后美侦,旋轉(zhuǎn)一個(gè)球之后慢慢看到被裁剪的那個(gè)洞了菠剩。(因?yàn)榍懊娴姆椒ㄊ前磳?duì)象坐標(biāo)系裁剪的)
前面與后面剪裁剛剛的代碼中我們看到了Cull Off,這行代碼位于CGPROGRAM標(biāo)記之前具壮,所以他不屬于CG的范疇擦囊。它是我們Unity中的ShaderLab的指令违霞,所以他不需要分號(hào)來結(jié)尾嘴办。Cull Off 即為關(guān)掉三角形剪裁(為何突然冒出來了三角形瞬场,腦補(bǔ)一下,我們的立體圖像在計(jì)算機(jī)中是以三角形拼湊的涧郊,正因?yàn)槿绱宋覀兊娜S圖形才會(huì)產(chǎn)生鋸齒贯被,那都是三角形的功勞啊)Cull Front 為前面(外部)剪裁Cull Back 為后面(內(nèi)部)剪裁,而這是我們所有Shader的默認(rèn)模式妆艘,也就是說如果Shader不是你自己寫的彤灶,很可能轉(zhuǎn)動(dòng)我們的半球的時(shí)候,你只看的到前方的曲面而不是半球曲面,不信你可以拖個(gè)模型看看
至于為何默認(rèn)是后面剪裁呢批旺,因?yàn)榇蟛糠智闆r下我們的渲染都是對(duì)整個(gè)三維體的表面進(jìn)行的,那么既然表面全部被渲染汽煮,你就看不到正背對(duì)著你的部分,所以默認(rèn)后面剪裁會(huì)節(jié)省很多物理性能靶睦!不過既然我們將表面進(jìn)行了擦除鞋囊,那么我們可以透過被擦除的部分看到背面的內(nèi)表面,那么我們應(yīng)該修改這個(gè)剪裁模式了溜腐,就像一個(gè)房子有房頂译株,我們從正上方看不到房子里面的地板,所以地板應(yīng)該屬于剪裁的范疇挺益。但是如果我們把房頂擦除了(推開房頂),還看不到地板那就有點(diǎn)恐怖了歉糜,這種事情就要切換剪裁模式
為了更直觀的明白這兩種模式,我們修改上面的代碼為內(nèi)部/外部剪裁的雙通道(Pass)矩肩,并且每個(gè)Pass中的最后著色不同(紅和綠)
要明白一點(diǎn)现恼,Unity中的Shader只會(huì)執(zhí)行一個(gè)SubShader,但是會(huì)執(zhí)行所有的Pass
修改后的代碼:
Pass{Cull front // 外部剪裁黍檩,那么這個(gè)通道可以理解為是給籃球的內(nèi)表面上色CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct vertexOutput {float4 pos : SV_POSITION;//由頂點(diǎn)著色器輸出mesh信息中的紋理坐標(biāo)叉袍,這個(gè)坐標(biāo)是以對(duì)象為坐標(biāo)系的float4 posInObjectCoords : TEXCOORD0;};vertexOutput vert(appdata_full input){vertexOutput output;output.pos = mul(UNITY_MATRIX_MVP, input.vertex);//直接把texcoord傳遞給片段著色器output.posInObjectCoords = input.texcoord;return output;}float4 frag(vertexOutput input) : COLOR{//當(dāng)坐標(biāo)的y值大于0.5的時(shí)候擦除片段if (input.posInObjectCoords.y > 0.5){discard;}
//其余部分仍然按y值大小生成經(jīng)度綠色球return float4(0.0, input.posInObjectCoords.y , 0.0, 1.0);}ENDCG}
Pass{Cull back //內(nèi)部剪裁,那么這個(gè)通道可以理解為是給籃球的外表面上色CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"struct vertexOutput {float4 pos : SV_POSITION;//由頂點(diǎn)著色器輸出mesh信息中的紋理坐標(biāo)喳逛,這個(gè)坐標(biāo)是以對(duì)象為坐標(biāo)系的float4 posInObjectCoords : TEXCOORD0;};vertexOutput vert(appdata_full input){vertexOutput output;output.pos = mul(UNITY_MATRIX_MVP, input.vertex);//直接把texcoord傳遞給片段著色器output.posInObjectCoords = input.texcoord;return output;}float4 frag(vertexOutput input) : COLOR{//當(dāng)坐標(biāo)的y值大于0.5的時(shí)候擦除片段if (input.posInObjectCoords.y > 0.5){discard;}
//其余部分仍然按y值大小生成經(jīng)度紅色球return float4(input.posInObjectCoords.y, 0.0 , 0.0, 1.0);}ENDCG}
我們完成了一個(gè)擁有兩個(gè)Pass的Shader,現(xiàn)在看看球體是什么樣子:

從頂部往下看,由于完全垂直看下去我們不知道這個(gè)球體的凹進(jìn)去的還是凸出來的,仿佛還是我們上個(gè)例子中的綠色經(jīng)度球笑陈,我們再從底部網(wǎng)上看:

我們還是不知道這個(gè)紅黑部分是凹的還是凸的坡锡,畢竟這是個(gè)半球拳缠,垂直半球去看沒啥發(fā)現(xiàn)我們再從正面偏上看過去:

可見綠黑部分是凹進(jìn)去的內(nèi)表面哲鸳,紅黑部分是凸起的外表面~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末婿奔,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖踊沸,帶你破解...
    沈念sama閱讀 216,843評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件歇终,死亡現(xiàn)場離奇詭異,居然都是意外死亡逼龟,警方通過查閱死者的電腦和手機(jī)评凝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來审轮,“玉大人肥哎,你說我怎么就攤上這事〖苍” “怎么了饥伊?”我有些...
    開封第一講書人閱讀 163,187評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵竟终,是天一觀的道長。 經(jīng)常有香客問我夏漱,道長朱浴,這世上最難降的妖魔是什么吊圾? 我笑而不...
    開封第一講書人閱讀 58,264評(píng)論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮翰蠢,結(jié)果婚禮上项乒,老公的妹妹穿的比我還像新娘。我一直安慰自己梁沧,他們只是感情好檀何,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評(píng)論 6 390
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著廷支,像睡著了一般频鉴。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上恋拍,一...
    開封第一講書人閱讀 51,231評(píng)論 1 299
  • 那天垛孔,我揣著相機(jī)與錄音,去河邊找鬼施敢。 笑死周荐,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的僵娃。 我是一名探鬼主播概作,決...
    沈念sama閱讀 40,116評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼悯许!你這毒婦竟也來了仆嗦?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,945評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤先壕,失蹤者是張志新(化名)和其女友劉穎瘩扼,沒想到半個(gè)月后谆甜,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,367評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡集绰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評(píng)論 2 333
  • 正文 我和宋清朗相戀三年规辱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片栽燕。...
    茶點(diǎn)故事閱讀 39,754評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡罕袋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出碍岔,到底是詐尸還是另有隱情浴讯,我是刑警寧澤,帶...
    沈念sama閱讀 35,458評(píng)論 5 344
  • 正文 年R本政府宣布蔼啦,位于F島的核電站榆纽,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏捏肢。R本人自食惡果不足惜奈籽,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評(píng)論 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鸵赫。 院中可真熱鬧衣屏,春花似錦、人聲如沸辩棒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽盗温。三九已至藕赞,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間卖局,已是汗流浹背斧蜕。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留砚偶,地道東北人批销。 一個(gè)月前我還...
    沈念sama閱讀 47,797評(píng)論 2 369
  • 正文 我出身青樓,卻偏偏與公主長得像染坯,于是被迫代替她去往敵國和親均芽。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • 參考風(fēng)宇沖Unity3D教程學(xué)院 Shader第十一講 剔除及深度測試...
    洪福齊天999閱讀 2,073評(píng)論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理单鹿,服務(wù)發(fā)現(xiàn)掀宋,斷路器,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • Unity shader 官網(wǎng)文檔全方位學(xué)習(xí)(一)What?? Shader,看起來好高級(jí)的樣子劲妙,是的湃鹊,這是Uni...
    狼之獨(dú)步閱讀 6,025評(píng)論 0 12
  • 草原行第一天。 第一天的大多時(shí)間都是在路上镣奋,過了冀蒙界就是赤峰币呵,慢慢出現(xiàn)了內(nèi)蒙地貌,但是前面的草原還是裸露地面的較...
    青言青語閱讀 135評(píng)論 0 0
  • 我都忘記來大華多久了,一周哈垢,還是兩周妻柒?每天過得很忙碌,以至于都不像新到一個(gè)地方温赔,感覺開始很久了蛤奢。 ...
    方小姐的漫山遍野閱讀 511評(píng)論 4 3