跳轉到內容

Cg 程式設計/Unity/廣告牌

來自 Wikibooks,開放世界開放書籍
高速公路上的廣告牌。請注意廣告牌的朝向以獲得最佳可見度。

本教程介紹了廣告牌

它基於“紋理球體”部分以及“頂點變換”部分中的討論。

廣告牌

[編輯 | 編輯原始碼]

在計算機圖形學中,廣告牌是經過變換的紋理矩形,它們始終平行於視平面顯示。因此,它們類似於高速公路上的廣告牌,它們被旋轉以獲得最佳可見度。但是,它們不同於高速公路上的廣告牌,因為它們會動態旋轉以始終提供最佳可見度。

廣告牌的主要用途是用二維影像替換複雜的 3D 模型(例如草、灌木甚至樹)。事實上,Unity 也使用廣告牌來渲染草。此外,廣告牌通常用於渲染 2D 精靈。在這兩種應用中,至關重要的是廣告牌始終與視平面對齊,以便保持 3D 形狀的錯覺,儘管只渲染了 2D 影像。

廣告牌的頂點變換

[編輯 | 編輯原始碼]

“天空盒”部分類似,我們可以使用預設立方體物件來渲染廣告牌。(為了使其與預設四邊形一起工作,您應該將程式碼中的減號更改為加號。對於預設平面,您必須使用z座標而不是y座標。)基本思想是隻將物件空間的原點 使用標準模型檢視變換UNITY_MATRIX_MV 轉換為檢視空間。(在齊次座標中,所有點的第四個座標為 1;請參見“頂點變換”部分中的討論。)檢視空間只是世界空間的旋轉版本,其中平面平行於視平面,如“頂點變換”部分中所述。因此,這是構造適當旋轉的廣告牌的正確空間。我們從檢視座標中變換後的原點中減去物件座標(vertex.xvertex.y),然後使用投影矩陣UNITY_MATRIX_P變換結果

            output.pos = mul(UNITY_MATRIX_P, 
              mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
              + float4(input.vertex.x, input.vertex.y, 0.0, 0.0));

為了擁有不同大小的廣告牌,我們添加了著色器屬性_ScaleX_ScaleY 來縮放物件座標;因此,程式碼變為

            output.pos = mul(UNITY_MATRIX_P, 
              mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
              + float4(input.vertex.x, input.vertex.y, 0.0, 0.0)
              * float4(_ScaleX, _ScaleY, 1.0, 1.0));

除此之外,我們只需要設定紋理座標

            output.tex = input.tex;

然後片段著色器只在插值的紋理座標處查詢顏色。

完整著色器程式碼

[編輯 | 編輯原始碼]

現在,標準立方體物件的完整著色器程式碼是

Shader "Cg  shader for billboards" {
   Properties {
      _MainTex ("Texture Image", 2D) = "white" {}
      _ScaleX ("Scale X", Float) = 1.0
      _ScaleY ("Scale Y", Float) = 1.0
   }
   SubShader {
      Pass {   
         CGPROGRAM
 
         #pragma vertex vert  
         #pragma fragment frag

         // User-specified uniforms            
         uniform sampler2D _MainTex;        
         uniform float _ScaleX;
         uniform float _ScaleY;

         struct vertexInput {
            float4 vertex : POSITION;
            float4 tex : TEXCOORD0;
         };
         struct vertexOutput {
            float4 pos : SV_POSITION;
            float4 tex : TEXCOORD0;
         };
 
         vertexOutput vert(vertexInput input) 
         {
            vertexOutput output;

            output.pos = mul(UNITY_MATRIX_P, 
              mul(UNITY_MATRIX_MV, float4(0.0, 0.0, 0.0, 1.0))
              + float4(input.vertex.x, input.vertex.y, 0.0, 0.0)
              * float4(_ScaleX, _ScaleY, 1.0, 1.0));
 
            output.tex = input.tex;

            return output;
         }
 
         float4 frag(vertexOutput input) : COLOR
         {
            return tex2D(_MainTex, float2(input.tex.xy));   
         }
 
         ENDCG
      }
   }
}

恭喜你,你完成了本教程。我們已經看到了

  • 如何變換和紋理化立方體以渲染與檢視對齊的廣告牌。

進一步閱讀

[編輯 | 編輯原始碼]

如果你想了解更多

讀者評論

[編輯 | 編輯原始碼]

為了避免渲染多個廣告牌時出現“閃爍”,我必須在 Subshader 中新增以下標籤

Tags { "DisableBatching" = "True" }

< Cg 程式設計/Unity

除非另有說明,否則本頁上的所有示例原始碼均歸屬公共領域。
華夏公益教科書