Billboards 技術在Unity 中的幾種使用方法
關於billboard技術,原理就是計算出來一個始終朝向攝像機的面片,可以在CPU裡計算,也可以在GPU裡實現。應用的場合很多:
-
遊戲角色的頭頂文字,xue條
-
場景的樹,草
-
特效粒子片
-
3d場景裡的2d角色
思路:shader中傳入面片的中心點的世界座標,以及攝像機的right和up在world space的方向,中心點直接沿著right和up方向計算四個頂點的世界座標,定點資料中包含了每個頂點的偏移資訊。然後乘以ViewProjection矩陣,作為輸出。
這裡有個trick的地方,就是從object space 到world space是沒有旋轉的,只有偏移,所以攝像機在世界空間的right就是模型空間的right。MV的逆矩陣相當於View到Object的變換,轉置是為了去列向量好取。
CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float2 vertexOffset : TEXCOORD1; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; }; sampler2D _MainTex; v2f vert (appdata v) { v2f o; //這裡相當於取列向量 float3 right = UNITY_MATRIX_IT_MV[0].xyz; float3 up = UNITY_MATRIX_IT_MV[1].xyz; v.vertex.xyz += v.vertexOffset.x * right + v.vertexOffset.y * up; o.vertex = mul(UNITY_MATRIX_VP, float4(v.vertex.xyz, 1.0)); o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG
unity c#中生成mesh的程式碼
Vector3[] vertices = new Vector3[4] { worldPos, worldPos, worldPos, worldPos }; int[] indices = new int[6] { 0, 2, 1, 0, 3, 2 }; Vector2[] uvs = new Vector2[4] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0), }; Vector2[] uv2s = new Vector2[4] { new Vector2(-0.5f, -0.5f), new Vector2(0.5f, -0.5f), new Vector2(0.5f, 0.5f), new Vector2(-0.5f, 0.5f), }; meshFilter.mesh.vertices = vertices; meshFilter.mesh.triangles = indices; meshFilter.mesh.uv = uvs; meshFilter.mesh.uv2 = uv2s;
clip space計算
思路:還是傳入中心點的世界座標,以及4個頂點的偏移資訊。把中心點轉到
clip space,然後按照偏移資訊縮放。這個適用的場合是面片不隨距離攝像機的遠近而縮放。
CGPROGRAM #pragma vertex vert #pragma fragment frag struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float2 vertexOffset : TEXCOORD1; }; struct v2f { float2 uv : TEXCOORD0; float3 color : TEXCOORD1; float4 vertex : SV_POSITION; }; sampler2D _MainTex; v2f vert (appdata v) { v2f o; o.vertex = mul(UNITY_MATRIX_MVP, v.vertex); o.vertex.xyz /= o.vertex.w; o.vertex.xy += v.vertexOffset.xy * float2(0.2, 0.05); o.vertex.w = 1; o.uv = v.uv; return o; } fixed4 frag (v2f i) : SV_Target { // sample the texture fixed4 col = tex2D(_MainTex, i.uv); return col; } ENDCG
view space計算
上面兩種方式都是通過傳入中心點座標到shader進行計算,但是有時候並不能獲得面片的中心點座標,比如Unity中的SpriteRenderer,這時候的思路是:把中心點即(0,0,0,1)(Object space)轉到View Space,然後頂點再做偏移。
o.pos = mul(UNITY_MATRIX_P, mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0)) + float4(i.vertex.x, i.vertex.y, 0.0, 0.0));
CPU計算
思路:面片的位置發生變化,或者攝像機發生變化的時候,重新計算一下面片的旋轉,讓它始終朝向攝像機
private void CalcBillboard() { if(instance != null) { instance.transform.rotation = Camera.main.transform.rotation; } }
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70009264/viewspace-2895894/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Unity反射的幾種方式Unity反射
- PHP 技術卡片 - 字串連線的幾種方式PHP字串
- 提升編碼技能的 幾 種高階技術
- 一對一社交原始碼在直播中最佳化技術的幾種形式原始碼
- 技術分享 | MySQL 的幾種資料遷移方案MySql
- Linux系統在儲存技術中的幾項應用(轉)Linux
- Unity中的各種合批Unity
- 在JS中typeof返回的結果有哪幾種?JS
- 在Js中匿名函式的幾種寫法JS函式
- Unity Plugins的使用方法UnityPlugin
- 在 .NET 中建立物件的幾種方式的對比物件
- Laravel 表單驗證器的幾種使用方法Laravel
- [譯] 降維技術中常用的幾種降維方法
- 漫談幾種反編譯對抗技術編譯
- Unity中的三種渲染路徑Unity
- 技術人溝通中的幾個誤區
- C#中的幾個簡單技術點C#
- 在SpringMVC中獲取request物件的幾種方式SpringMVC物件
- Redis為什麼快及其高可用技術的幾種方案Redis
- 分析技術在PMP中的應用
- 原始碼防洩密幾種技術原理總結原始碼
- FCKeditor使用方法技術詳解
- AR技術在藝術展館中的使用效果
- 讓物體動起來,Unity的幾種移動方式Unity
- Spring在程式碼中獲取bean的幾種方式SpringBean
- 面試題:在JS中typeof返回的結果有哪幾種?面試題JS
- 在JavaScript中建立名稱空間的幾種寫法JavaScript
- 在專案中獲取Spring的Bean的幾種方式SpringBean
- 搞懂分散式技術16:淺談分散式鎖的幾種方案分散式
- IPv4向IPv6轉換的幾種技術分析
- Unity物件池技術(原理+實戰)Unity物件
- 技術人溝通中的幾個常見問題
- Java中的幾種註釋Java
- Stream 的幾種中間操作
- Unity 開源雙端框架 ET 中初嘗熱更新技術Unity框架
- 基於HTTP協議的幾種實時資料獲取技術HTTP協議
- 技術支援在大資料分析中的作用大資料
- Hanlp在ubuntu中的使用方法介紹HanLPUbuntu