Unity Shader 學習之旅之SurfaceShader

Unity Shader 學習之旅之SurfaceShader

若是大地的每一個角落都充滿了光明 誰還須要星星,誰還會 在夜裏凝望 尋找遙遠的安慰——江河html

官方文檔函數

1、工做原理

sureface表面着色器至關於unity在頂點片元着色器的基礎上進一步的封裝。當咱們定義一個「surface function」後,能夠經過unity已經封裝好的的結構體「SurfaceOutput」等直接獲取須要的數據,如紋理,法線,光滑度等學習

2、結構體

2.1標準output結構體

  1. struct SurfaceOutput 

  2. fixed3 Albedo; // 漫反射顏色 
  3. fixed3 Normal; // 切線空間法線 
  4. fixed3 Emission; 
  5. half Specular; // 高光係數 
  6. fixed Gloss; // 高光強度 
  7. fixed Alpha; // alpha 通道 
  8. }; 

2.2Unity5 output結構體

unity5中表面着色器使用基於物理的光照模型。內建Standard和StantardSpecular光照模型使用以下兩種結構體:ui

  1. struct SurfaceOutputStandard 

  2. fixed3 Albedo; // base (diffuse or specular) color 
  3. fixed3 Normal; // tangent space normal, if written 
  4. half3 Emission; 
  5. half Metallic; // 0=non-metal, 1=metal 
  6. half Smoothness; // 0=rough, 1=smooth 
  7. half Occlusion; // occlusion (default 1) 
  8. fixed Alpha; // alpha for transparencies 
  9. }; 
  10. struct SurfaceOutputStandardSpecular 

  11. fixed3 Albedo; // diffuse color 
  12. fixed3 Specular; // specular color 
  13. fixed3 Normal; // tangent space normal, if written 
  14. half3 Emission; 
  15. half Smoothness; // 0=rough, 1=smooth 
  16. half Occlusion; // occlusion (default 1) 
  17. fixed Alpha; // alpha for transparencies 
  18. }; 

3、SurfaceShader編譯指令

SurfaceShader被放置在 CGPROGRAM---ENDCG語塊之間,須要注意如下兩點:spa

  • 必須放置在SubShader語塊中,不能在Pass語塊中,SurfaceShader會自主編譯成多個Pass
  • 經過使用 #pragma surface ... 來代表這是一個SurfaceShader
  1. #pragma surface surfaceFunction lightModel [optionalparams] 

3.1必要參數

  • surfaceFuncton:這就是咱們在編譯指令中指定的表面着色器Cg函數。能夠經過 void surf (Input IN, inout SurfaceOutput o) 這種形式定義。其中input是咱們定義的結構體,包含該函數須要的數據信息。
  • lightMode:光照模型能夠使用內建的基於物理的 Standard 和StandardSpecular。也能夠使用非物理的Lambert BlinnPhong。這幾種類型能夠直接經過在編譯指令中指定,無需在本身實現。
    • Standard 光照模型使用SurfaceOutputStandard output結構體
    • StandardSpecular 光照模型使用SurfaceOutputStandardSpecular output結構體
    • Lambert和BlinnPhong 光照模型使用 SurfaceOutput output結構體

3.2可選參數

經過指定可選參數[optionalparams],能夠讓surfaceshader表現出更豐富的效果,如霧效,半透明,陰影等。可選參數具體類型可參考文首給出的 官方文檔 查閱。3d

3.3示例

示例1:使用內置Lambert光照模型的表面着色器code

  1. Shader "Example/Rim" { 
  2. Properties { 
  3. _MainTex ("Texture", 2D) = "white" {} 
  4. _BumpMap ("Bumpmap", 2D) = "bump" {} 
  5. _RimColor ("Rim Color", Color) = (0.26,0.19,0.16,0.0
  6. _RimPower ("Rim Power", Range(0.5,8.0)) = 3.0 

  7. SubShader { 
  8. Tags { "RenderType" = "Opaque" } 
  9. CGPROGRAM 
  10. #pragma surface surf Lambert 
  11. struct Input { 
  12. float2 uv_MainTex; 
  13. float2 uv_BumpMap; 
  14. float3 viewDir; 
  15. }; 
  16. sampler2D _MainTex; 
  17. sampler2D _BumpMap; 
  18. float4 _RimColor; 
  19. float _RimPower; 
  20. void surf (Input IN, inout SurfaceOutput o) { 
  21. o.Albedo = tex2D (_MainTex, IN.uv_MainTex).rgb; 
  22. o.Normal = UnpackNormal (tex2D (_BumpMap, IN.uv_BumpMap)); 
  23. half rim = 1.0 - saturate(dot (normalize(IN.viewDir), o.Normal)); 
  24. o.Emission = _RimColor.rgb * pow (rim, _RimPower); 

  25. ENDCG 
  26. }  
  27. Fallback "Diffuse" 

示例2:使用可選參數的表面着色器,經過指定decal:blend,該shader會表現出半透明貼畫的效果。orm

  1. Shader "Example/Decal" { 
  2. Properties { 
  3. _MainTex ("Base (RGB)", 2D) = "white" {} 

  4. SubShader { 
  5. Tags { "RenderType"="Opaque" "Queue"="Geometry+1" "ForceNoShadowCasting"="True" } 
  6. LOD 200 
  7. Offset -1, -1 
  8.  
  9. CGPROGRAM 
  10. #pragma surface surf Lambert decal:blend 
  11.  
  12. sampler2D _MainTex; 
  13.  
  14. struct Input { 
  15. float2 uv_MainTex; 
  16. }; 
  17.  
  18. void surf (Input IN, inout SurfaceOutput o) { 
  19. half4 c = tex2D (_MainTex, IN.uv_MainTex); 
  20. o.Albedo = c.rgb; 
  21. o.Alpha = c.a; 

  22. ENDCG 

相關文章
相關標籤/搜索