前言:
前言當然是先介紹一下工具囉~
Particle Event
打開粒子的Send Collison Messages選項。
MonoBehavior的 "OnParticleCollision"會在被particle碰撞時呼叫,我們這時用List<ParticleCollisionEvent>去承接碰撞的結果。
文件:
GPU Instance
在之前的
文章中探討過 GPU instance 與 Compute Shader的種類與使用方式,並分別製作了固定位置的草原以及動態的流體效果。 對GPU Instance還不熟悉的建議先複習一下。
這次透過Unity提供的particle 碰撞事件去新增GPUInstancer數量。
結構
定義buffer架構,這次想讓噴灑的顏色有變化,所以多了一個color參數。
接著就跟之前一樣設定Buffer資訊。
除了buffer資訊外,我們再多設置一個變數transform_center以記錄該物件的世界座標。
CG Shader
承接資料的buffer:
在vert函數以碰撞中心點展開vertex。
frag渲染簡單幾行。
![](https://i2.bahamut.com.tw/editor/emotion/5.gif)
成果: 在陰影處的噴漆比較暗。
HLSL
因為無聊,所以挑戰用HLSL再寫一遍。
High-Level Shader Language (HLSL) 是一種類似於 C 語言的高級著色器語言,用於 DirectX 中的可編程著色器。 Unity原本使用Cg語言,但目前已改使用HLSL,而CGProgram內部其實也是跑HLSL,差別在於當使用CGProgram時Unity會自動幫我們include許多方便的函數。
延伸閱讀:
HLSL基本
雖然vert,frag概念跟CGProgram一樣,在處理上變化不少。
例如採樣貼圖就分成texture與sampler。
Vert
ShaderVariablesFunctions.hlsl提供許多計算位置、法線等等方法。例如GetVertexPositionInputs內部如下,輸出的input就幫我們算好世界座標、view座標、clip座標、NDC座標,你不要一個也不行。
GetVertexNormalInputs倒是大大節省了以前處理法線的麻煩。
Frag
以下範圍為製作基本的BlingPhong材質。
首先,Input.hlsl定義了InputData與surfaceData結構,我們接著填上幾個必要的參數如世界座標、法線、view方向、陰影座標等。接著一同餵入UniversalFragmentBlinnPhong方法得到最終渲染顏色。
InputeData
內容如下:
SurfaceData
UniversalFragmentBlinnPhong
內碼跟我們之前自己做shader的內容差不多。
由於BlinnPhong顏色介於[0,1],渲染出來的陰暗面就會非常黑,HLSL好像也沒提供half-lambert方法。
因此我最終顏色就不使用Unity提供的BlinnPhong方法,而是直接對陰影採樣的結果做half-lambert操作再乘上採樣顏色。
結果:
後記:
- 謝謝七七贊助了10本書
![](https://bmc-dev.s3.us-east-2.amazonaws.com/assets/icons/bmc_icon_black.png)
![](https://bmc-dev.s3.us-east-2.amazonaws.com/assets/icons/bmc_icon_black.png)
(′▽`???)(′▽`???)(′▽`???)
- 雖然HLSLProgram把分工拆得很細,常常不知道要引入甚麼,但能趁著這個機會學習將Shader模組化的概念。
![](https://i2.bahamut.com.tw/editor/emotion/16.gif)
- Github裡面的程式碼沒有清過,註解可能有點多。XD