編寫Shader時的一些性能考慮


編寫shader時的一些建議:
1、只計算需要計算的東西;
2、通常,需要渲染的像素比頂點數多,而頂點數又比物體數多很多。所以如果可以,盡量將運算從PS移到VS,或直接通過script來設置某些固定值;
3、在使用Surface Shader時,可以通過一些指令讓shader優化很多。
  通常情況下,Surface shader的很多默認選項都是開啟的,以適應大多數情況,但是很多時候,你可以關閉其中的一些選項,從而讓你的shader運行的更快:
  (1) approxview 對於使用了view direction的shader,該選項會讓view dir的normalize操作per-vertex進行,而不是per-pixel。這個優化通常效果明顯。
  (2) halfasview 可以讓Specular shader變得快一些,使用一個介於光照方向和觀察方向之間的half vector來代替真正的觀察方向viewDir來計算光照函數。
  (3) noforwardadd Forward Render時,完全只支持一盞方向光的per-pixel渲染,其余的光照全部按照per-vertex或SH渲染。這樣可以確保shader在一個pass里渲染完成。
  (4) noambient 禁掉ambient lighting和SH lighting,可以讓shader快一點兒。
4、浮點數精度相關:
  float:最高精度,通常32位
  half:中等精度,通常16位,-60000到60000,
  fixed:最低精度,通常11位,-2.0到2.0,1/256的精度。
  盡量使用低精度。對於color和unit length vectors,使用fixed,其他情況,根據取值范圍盡量使用half,實在不夠則使用float。
  在移動平台,關鍵是在fragment shader中盡可能多的使用低精度數據。另外,對於多數移動GPU,在低精度和高精度之間轉換是非常耗的,在fixed上做swizzle操作也是很費事的。
5、Alpha Test
  Alpha test和clip()函數,在不同平台有不同的性能開銷。
  通常使用它來cull那些完全透明的像素。
  但是,在ios和一些android上使用的PowerVR GPUs上面,alpha test非常的昂貴。
 6、Color Mask
  在移動設備上,Color Mask也是非常昂貴的,所以盡量別使用它,除非真的是需要。

 

shader多版本編譯:
shader variants(shader 變種)使用方式:
(1)#pragma multi_compile FANCY_STUFF_OFF FANCY_STUFF_ON
(2)#pragma shader_feature FANCY_STUFF_OFF FANCY_STUFF_ON
  #pragma shader_feature FANCY_STUFF是#pragma shader_feature _ FANCY_STUFF的快捷方式,同樣會生成兩個變種

shader_feature和multi_compile的區別:
  shader_feature:未使用的變種不會build進游戲;
  multi_compile:會編譯生成所有變種。
  用法:shader_feature更適用於材質的關鍵字,而multi_compile更適用於代碼設置的全局關鍵字。

關鍵字個數限制:
  unity最多支持256個關鍵字,並且unity內部已經使用了60個左右。另外,可以在unity的工程設置中定義一些全局有效的關鍵字,這樣也會消耗一些數量,所以在編寫shader時要注意數量不要超過上限。

內置的multi_compile快捷組合:
  #pragma multi_compile_fwdbase 編譯ForwardBase需要的所有關鍵字變種,包括不同的lightmap類型,主要的方向光是否開啟陰影等。
  #pragma multi_compile_fwdadd 編譯ForwardAdd Pass包含的關鍵字變種。
  #pragma multi_compile_fwdadd_fullshadows 和上一個類似,另外還包含了光照實施陰影的能力。
  #pragma ulti_compile_fog 霧效。
  上面內置的快捷方式包含了很多的變種,但可以通過skip_variants來屏蔽某些關鍵字:
  #pragma skip_variants POINT POINT_COOKIE

硬件級別shader變種:
  提供針對不同硬件(比如gles和gles 3.0)的shader變種。(針對硬件能力級別的優化)
  #pragma hardware_tier_variants renderer
    d3d11 - Direct3D 11/12
    glcore - OpenGL 3.x/4.x
    gles - OpenGL ES 2.0
    gles3 - OpenGL ES 3.x
    metal - iOS
    /Mac Metal
    vulkan - Vulkan
    d3d11_9x - Direct3D 11 9.x feature level, as commonly used on WSA platforms
    xboxone - Xbox One
    ps4
    - PlayStation 4
    psp2 - PlayStation Vita
    n3ds - Nintendo 3DS
    wiiu - Nintendo Wii U
  添加了上述#pragma的shader會自動生成三個關鍵字變種:
    UNITY_HARDWARE_TIER1
    UNITY_HARDWARE_TIER2
    UNITY_HARDWARE_TIER3
  編輯器模式下,可以在Graphics Emulation中來手動設置使用哪個變體。
  上述三中變體,同時只會加載其中一種,
  指定方式:
    (1)自動檢測:在加載時,Unity檢測GPU並進行設置;如果檢測不到,默認選擇最高級。
    (2)手動設置來制定使用哪一個tier,代碼如下:(一定是在shader加載之前制定,在某個shader加載之后再指定是不會影響該shader的)
    Graphics.activeTier = UnityEngine.Rendering.GraphicsTier.Tier1;

  平台shader設置:
    可以通過代碼手動設置[平台, tier, 設置]
    UnityEditor.Rendering.EditorGraphicsSettings.SetTierSettings(BuildTargetGroup target, GraphicsTier tier, TierSettings settings);
    

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM