通常,需要渲染的像素比頂點(diǎn)數(shù)多,而頂點(diǎn)數(shù)又比物體數(shù)多很多。所以如果可以,盡量將運(yùn)算從 FS 移到 VS,或直接通過(guò) script 來(lái)設(shè)置某些固定值;
在使用Surface Shader時(shí),可以通過(guò)一些指令讓shader優(yōu)化很多。
通常情況下,Surface shader的很多默認(rèn)選項(xiàng)都是開(kāi)啟的,以適應(yīng)大多數(shù)情況,但是很多時(shí)候,你可以關(guān)閉其中的一些選項(xiàng),從而讓你的shader運(yùn)行的更快: (1) apPRoxview 對(duì)于使用了 view direction 的shader,該選項(xiàng)會(huì)讓 view dir 的 normalize 操作 per-vertex 進(jìn)行,而不是 per-pixel。這個(gè)優(yōu)化通常效果明顯。 (2) halfasview 可以讓Specular shader變得快一些,使用一個(gè)介于光照方向和觀察方向之間的 half vector 來(lái)代替真正的觀察方向 viewDir 來(lái)計(jì)算光照函數(shù)。 (3) noforwardadd Forward Rende r時(shí),完全只支持一盞方向光的 per-pixel 渲染,其余的光照全部按照 per-vertex 或 SH 渲染。這樣可以確保shader在一個(gè)pass里渲染完成。 (4) noambient 禁掉 ambient lighting 和 SH lighting,可以讓 shader 快一點(diǎn)兒。在移動(dòng)設(shè)備上,Color Mask 也是非常昂貴的,所以盡量別使用它,除非真的是需要。
x = tex.Load();if(x == 5){ // Thread 1 & 2 使用這個(gè)路徑 out.Color = float4(1, 1, 1, 1); }else{ // Thread 3 & 4 使用這個(gè)路徑 out.Color = float4(0, 0, 0, 0);}比如在上例中,兩個(gè)分支的語(yǔ)句Shader Unit都會(huì)執(zhí)行,只是不同的是如果在執(zhí)行if分支,那么計(jì)算結(jié)果將不會(huì)寫(xiě)入到thread 3 和 4的存儲(chǔ)中(無(wú)副作用)。這樣做就相當(dāng)于運(yùn)算量增加了不少,這是動(dòng)態(tài)分支的主要成本。但是如果所有的線程,都走的是同一分支,那么另外一個(gè)分支就不用走了。這個(gè)時(shí)候Shader Unit也不會(huì)去傻逼一樣的執(zhí)行另外一個(gè)根本不需要執(zhí)行的分支。此時(shí)性能的損失也不多。并且,在實(shí)際的Shader中,除非特殊情況,大部分Warp內(nèi)的線程,即便在動(dòng)態(tài)分支的情況下,也多半走的是同一分支。4. 動(dòng)態(tài)分支和代碼優(yōu)化難度有相關(guān)性
這一點(diǎn)經(jīng)常被忽視,就是有動(dòng)態(tài)分支的代碼,因?yàn)闆](méi)準(zhǔn)你要讀寫(xiě)點(diǎn)什么,前后還可能有依賴,往往也難以被優(yōu)化。比如說(shuō)你非要鬧這樣的語(yǔ)句出來(lái):if(x == 1){ color = tex1.Load(coord);}else if(x == 2){ color = tex2.Load(coord);}...你說(shuō)編譯器怎么給你優(yōu)化。說(shuō)句題外話,為啥要有TextureArray呢?也是為了這個(gè)場(chǎng)合。TextureArray除了紋理不一樣,無(wú)論格式、大小、坐標(biāo)、LoD、偏移,都可以是相同的。這樣甚至可以預(yù)見(jiàn)不同Texture Surface上取數(shù)據(jù)的內(nèi)存延遲也是非常接近的。這樣有很多的操作都可以合并成SIMD,就比多個(gè)Texture分別來(lái)取快得多了。這就是一個(gè)通過(guò)增加了約束(紋理格式、大小、尋址坐標(biāo))把SISD優(yōu)化成SIMD的例子。定位渲染通道瓶頸的方法
轉(zhuǎn)自:http://blog.csdn.net/rabbit729/article/details/6398343 一般來(lái)說(shuō), 定位渲染通道瓶頸的方法就是改變渲染通道每個(gè)步驟的工作量, 如果吞吐量也改變了, 那個(gè)步驟就是瓶頸.。找到了瓶頸就要想辦法消除瓶頸, 可以減少該步驟的工作量, 增加其他步驟的工作量。 一般在光柵化之前的瓶頸稱作”transform bound”, 三角形設(shè)置處理后的瓶頸稱作”fill bound”
定位瓶頸的辦法: 1. 改變幀緩沖或者渲染目標(biāo)(Render Target)的顏色深度(16 到 32 位), 如果幀速改變了, 那么瓶頸應(yīng)該在幀緩沖(RenderTarget)的填充率上。2. 否則試試改變貼圖大小和貼圖過(guò)濾設(shè)置, 如果幀速變了,那么瓶頸應(yīng)該是在貼圖這里。3. 否則改變分辨率.如果幀速改變了, 那么改變一下pixel shader的指令數(shù)量, 如果幀速變了, 那么瓶頸應(yīng)該就是pixel shader. 否則瓶頸就在光柵化過(guò)程中。4. 否則, 改變頂點(diǎn)格式的大小, 如果幀速改變了, 那么瓶頸應(yīng)該在顯卡帶寬上。5. 如果以上都不是, 那么瓶頸就在CPU這一邊。
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注