梳理 Unity Shader 的基本結構

2021-02-19 Unity3D遊戲開發精華教程乾貨

0x00 寫在前面

之前一直在閱讀 The Book of Shaders 一書,為什麼會開始寫 Unity Shader 呢?一方面,因為該書目前尚未完結,寫下此文時已閱讀到該書的最新章節;另一方面,也需要通過一些實踐來檢驗以及鞏固所學的知識。Unity 引擎提供的環境正好是一個不錯的媒介。

本文沒有完整可運行的 Shader 代碼,只是簡單梳理一下 Unity Shader 的基本結構,為之後學習做鋪墊。

0x01 基本框架

一段 Unity Shader 的基本結構如下:

Shader "Path/ShaderName"{        Properties    {
}
SubShader { [Tags] [RenderSetup] Pass { Name "PassName" [Tags] [RenderSetup] } } Fallback "OtherShaderName" }

0x02 名字

Path/ShaderName 決定該 Shader 在選擇面板上所處的位置,很像文件的全路徑。例如,Shader "Path0/Path1/CustomShader" 將位於 Path0 → Path1 → CustomShader:

0x03 屬性

Properties 括號中定義的屬性將在材質面板上展示,可以方便地進行調節。

Properties{    Name("Display Name", Type) = DefaultValue    }

定義一個屬性,就像在 C 語言中定義一個變量一樣,只是格式稍有不同。在上面的代碼中,Name 是屬性的名字,Display Name 是用於展示在材質面板上的名字,Type 是屬性的類型,DefaultValue 是屬性的默認值。ps:其中 Name 常常以下劃線開頭,例如 _PropertiesName。

下面列出一些常用的屬性:

數字
_Number0("Number 0", Range(-2.0, 2.0)) = 0.0_Number1("Number 1", Float) = 0.618_Number2("Number 2", Int) = 3

其中,Range 將在面板上展示一個滑動條,它的兩個參數依次表示可以滑動的最小值和最大值。Float 是浮點數,Int 是整數。

顏色和向量
_Color("Color", Color) = (1, 1, 1, 1)_Vector("Vector", Vector) = (1, 1, 1, 1)

顏色 Color 的四個值分別表示 RGBA,在面板上將會展示修改按鈕以及吸取按鈕。向量 Vector 為四維向量,在面板上展示為 XYZW 四個格子。

紋理
_2DTexture("2D Texture", 2D) = "defaulttexture" {}_Cube("Cube", Cube) = "defaulttexture" {}_3DTexture("3D Texture", 3D) = "defaulttexture" {}

2D 表示 2D 紋理貼圖,Cube 表示立方體貼圖,3D 表示 3D 紋理貼圖。它們都有 Tiling 和 Offset。

在 Properties 中定義的屬性可以在 SubShader 的代碼塊中使用,只需要在相應的地方定義與這些屬性 名字相同、類型匹配 的變量即可。SubShader 中的類型與 Properties 中的稍有不同,下面列出兩者對應的匹配關係:

SubShader 代碼中,有的屬性也可以不在 Properties 中定義,兩者都可以在運行時通過 C# 腳本動態地進行修改(如,使用方法 Material.SetFloat 修改浮點屬性)。兩者的區別是,定義在 Properties 中的屬性在修改後將會被保存,而不在 Properties 中的屬性則不會。

0x04 SubShader

每個 Unity Shader 中都可以包含多個 SubShader,當 Unity 展示一個 Mesh 時,將會從這些 SubShader 中找到第一個可以運行的來運行。因為不同的硬體對 Shader 的支持不同,這裡可以理解為

0x05 Tags

Tags 是 kv 結構,用來指定 Shader 怎樣以及何時渲染對象。

Tags { "TagName1" = "Value1" "TagName2" = "Value2" }

關於 Tags 的詳細說明可以查看:ShaderLab: SubShader Tags 。

0X06 RenderSetup

RenderSetup 用來設置顯卡的渲染狀態。比如,設置剔除模式。

關於渲染狀態的詳細設置可以查看:ShaderLab: Pass 。

0x07 Pass

在 SubShader 中指定的 RenderSetup 將會應用到所有 Pass 中,我們也可以在 Pass 中單獨指定。Pass 中的 Tags 與 SubShader 中的有所不同 ,主要用於控制該 Pass 中的環境光、頂點照明等,詳見:ShaderLab: Pass Tags 。

Pass{    Name "PassName"     [Tags]    [RenderSetup]        }

當用 Name 為 Pass 指定名字後,可以在其它地方復用這個 Pass。其中,Pass 名需要大寫。用法如下:

UsePass "ShaderName/PASSNAME"

一個 SubShader 中可以有多個 Pass,這些 Pass 將會被依次執行。

0x08 Fallback

如果所有 SubShader 都無法使用時,將會嘗試使用 Fallback 指定的著色器。如:

0X09 總結

本文簡單梳理了一下 Unity Shader 的基本結構,因為了解不深,部分內容只能粗略帶過。這些內容在以後有需要時會再深入研究。

最後,再回顧一下 Unity Shader 的基本結構吧:

每個 Shader 都需要定義名字,格式為:

Shader "Path/ShaderName" {}。

在 Shader 的括號中,如果有需要,我們可以在 Properties 語義塊中定義材質的屬性。

每個 Shader 都包含多個子著色器 SubShader。

使用多個 SubShader 是因為不同的硬體對 Shader 的支持有所不同。

當實例運行時,引擎會幫我們找到第一個可以運行的 SubShader 來運行。

當所有的 SubShader 都不能運行時,則使用 Fallback 指定的 Shader。

每個 SubShader 包含多個 Pass,每個 Pass 表示一個渲染流程。

因為有的效果需要幾個渲染才能表現出來,這時候就需要使用多個 Pass 了。

SubShader 和 Pass 都可以通過一些語義 (Tags 和 RenderType) 來設置渲染狀態,Pass 還可以通過:

Name "PassName" 來指定 Pass 的名字。

參考資料:

[1] Shaders Overview

[2] Unity Shader入門精要

       


聲明:發布此文是出於傳遞更多知識以供交流學習之目的。若有來源標註錯誤或侵犯了您的合法權益,請作者持權屬證明與我們聯繫,我們將及時更正、刪除,謝謝。

作者:drnkcff

原文:https://www.cnblogs.com/drnkcff/p/13777001.html

More:【微信公眾號】 u3dnotes

相關焦點

  • 隨風擺動的草叢 — Unity Shader Graph 2D 初探
    微信有壓縮,請在「閱讀原文」中打開圖片查看細節基本思路實現細節1. Split 節點與 Combine 節點的使用個人感想Add,Multiply,Subtract,Divide 以及 One Minus 這些基本節點用處非常廣泛,在學習時須熟練掌握其性質若要僅更改某 N 維矢量的某一維度,先使用 Split 節點將其分離,再使用 Combine 節點組合在一起Gradient Noise 節點可生成均勻自然的隨機噪聲,在模擬風,水波等自然效果時應用廣泛這個著色器瞎胡調參數能調出來好多神奇的效果
  • Unity3D 實用技巧 - Unity Shader 匯總式學習·初探篇
    以.shader作為後綴的一種文件。在Unity shader裡面,我們可以做的事情遠多於一個傳統意義上的Shader。在傳統的shader中,我們僅可以編寫特定類型的Shader,例如頂點著色器,片元著色器等。在Unity Shader中,我們可以在同一個文件裡面同時包含需要的頂點著色器和片元著色器代碼。
  • 在Unity Shader中自定義材質面板
    很多時候,我們為了使寫出來的shader更加直觀易用,需要對材質面板的顯示樣式做一些簡單的修改。
  • Unity PBR Standard Shader 實現詳解 (三)
    上一篇《Shader框架和數據準備》中,我們寫了一個完整的shader,但這個shader的主要內容並不是PBR計算,而是計算前的數據準備
  • Unity 3d可視化節點材質Shader Forge實用教程 初級篇
    大家好,我們前段時發布了免費的shader forge教程,現在更完整,更強大的Shader Forge實用教程來了!
  • Unity Standard Shader 技術分析
    Metallic和unity_ColorSpaceDielectricSpec.a被用來構造reflectivity,之後reflectivity和Albedo共同構造diffColor.而Metallic,Albedo,unity_ColorSpaceDielectricSpec被共同用來構造
  • Unity Shader 基礎教程
    例如:你可能想要寫為PC/Desktop寫一個高質量的Subshader,為移動端寫一個低質量,但速度更快的Subshader.我們將添加一個數據結構a2v(此處和原文不一致),並修改頂點函數,將a2v作為參數傳遞給頂點函數。
  • Unity 重Built-in到URP函數對應整理
    Unlit templatehttps://gist.github.com/phi-lira/10159a824e4e522060c47e21762941bbBoat attack demo projecthttps://github.com/Verasl/BoatAttackPhil Lira’s shader examples
  • 《卡通湖水渲染思路》與《Unity Shader ScreenPos》詳解
    至於給波浪更換顏色,我們容易發現上面功能實現後,儘管我們可以給shader添加一個_FoamColor屬性來控制,但顏色值會和水面顏色混合,並不能得到我們想要的效果。我們可以在Unity內置shader中找到這個函數的內部定義:
  • 一種Shader變體收集和打包編譯優化的思路
    在帶有多個變體的Shader代碼片段中,最顯著的特徵就是擁有這些預編譯開關,如:  #pragma multi_compile_fwdbase // unity 內置前向管線編譯設置集合,控制光照,陰影等很多相關功能#pragma shader_feature _USE_FEATURE_A // 自定義功能開關#pragma multi_compile _USE_FUNCTION_A
  • Unity Shader 使用滑鼠繪製自由多邊形
    3、核心代碼實現3.1 Polygon.cs腳本中實現的是滑鼠點擊和向shader傳遞信息的功能(1)為了實現滑鼠點選場景中的3D位置,需要使用射線Camera.main.ScreenPointToRay(Input.mousePosition);   RaycastHit hit;    if (Physics.Raycast(ray, out hit, 100))    {    Debug.DrawLine(ray.origin, hit.point);                         }(2)向shader
  • Unity3D Shader 新手教程—更好的卡通Shader
    在shader中學習更多不同參考坐標系(空間space)以及其作用。深入學習一個實用的fragment shader。學習矩陣相乘和Unity內建矩陣的使用。準備工作為了實現一個描邊的toon shader,我們需要做的是:描邊有很多方法進行描邊,現在我們採用使用一個Pass改善已有的描邊效果。
  • 【厚積薄發】Packages目錄下Shader打包疑問
    UWA 問答社區:answer.uwa4d.comUWA QQ群2:793972859(原群已滿員)本期目錄:Q:Unity引入了Package Manager來進行管理插件管理,例如URP引入Packages之後會有目錄Packages/com.unity.render-pipelines.universal
  • Unity PBR Standard Shader 實現詳解(一)
    最近在學習Unity的PBR shader,有一點自己的結論,特來這裡分享一下。我自己是一個美術工作者,不是程式設計師,所以更多的是講實現效果。以及一些必須知道的原則。站在美術的角度的一些新的思考。數學原理上只提出,但不會深入分析。但這篇文章也不是純美術向的,我不會涉及美術的製作部分:比如高低模,烘焙,貼圖繪製這類的。著重於的是TA的應用方面:Shader。
  • 零基礎入門Unity Shader(九)
    SetReplacementShader("shaderA","RenderType"),由於這裡Tag為"RenderType",所以先查看場景中的shader中是否有RenderType參數,如果有,再看RenderType中的值是否與shaderA中的RenderType值相等,相等則使用shaderA渲染,否則就不渲染(Game視圖什麼也沒有)。
  • Unity shader五種繪製等寬sin曲線
    一共嘗試了5種方法:萬能lerp大法多點檢測法導數解析法超越函數牛頓迭代法超越函數切比雪夫迭代法解法1:萬能lerp大法首先明確 直接偏移函數曲線是不等寬的 ,頂部的區域更寬些.如下圖但是可以先用shader簡單實現下,shader編程與cpu打點編程不同 他是一個個xy然後判斷是否在某範圍內
  • Unity中使用URP的RenderFeature快樂滴RTXON!
    要想使用RenderFeature,目前直接下載最新的unity使用URP即可。故第一步則先需要先創建一個RenderFeature如下。(需要把創建的RenderFeature 拖入 forwardRender)
  • Shader Forge插件入門
    涉及的知識點有漫反射,高光,自發光,菲涅爾,頂點偏移,UV偏移、扭曲等,並去製作一些易上手但效果不錯的shader。有興趣的同學們可以加入學習。該課程基於Unity2017.2進行開發,shader forge版本1.38。
  • 【遊戲流體力學基礎及Unity代碼(二)】用平流方程模擬染料流動
    在此之前,我們要從最基本的水系魔法開始學起。【誤】首先認識三個名詞,平流,對流以及擴散,英文:Advection,Convection and Diffusion。如果我們將一滴染料滴在清水中,那麼染料會在水中擴散,也就是隨機朝四面八方移動。