GLSL 程式設計/Unity/公告板

本教程介紹了**公告板**。
在計算機圖形學中,公告板是紋理矩形,它們被變換以始終平行於視平面。因此,它們類似於高速公路旁的公告板,它們被旋轉以獲得最佳可見度。但是,它們不同於高速公路公告板,因為它們會動態旋轉以始終提供最佳可見度。
公告板的主要用途是使用二維影像替換複雜的 3D 模型(例如草、灌木甚至樹木)。事實上,Unity 也使用公告板來渲染草。此外,公告板通常用於渲染 2D 精靈。在這兩種應用中,至關重要的是公告板始終與視平面平行,以保持 3D 形狀的錯覺,儘管只渲染了 2D 影像。
類似於“天空盒”部分,我們將使用預設的立方體物件來渲染公告板。基本思路是用標準變換 gl_ModelViewMatrix 將物件空間的原點 變換到視空間。(在齊次座標中,所有點都具有 1 作為第四個座標;參見“頂點變換”部分 的討論。)視空間只是世界空間的旋轉版本,其中 平面平行於視平面,如“頂點變換”部分 所述。因此,這是構建適當旋轉的公告板的正確空間。我們將 和 物件座標 (gl_Vertex.x 和 gl_Vertex.y) 新增到視座標中的變換原點,然後使用投影矩陣 gl_ProjectionMatrix 變換結果
gl_Position = gl_ProjectionMatrix * (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0) + vec4(gl_Vertex.x, gl_Vertex.y, 0.0, 0.0));
除此之外,我們只需要計算紋理座標,這與“螢幕疊加”部分 中的做法相同
textureCoords = vec4(gl_Vertex.x + 0.5, gl_Vertex.y + 0.5, 0.0, 0.0);
然後,片段著色器只需在插值的紋理座標處查詢顏色。
現在,標準立方體物件的完整著色器程式碼為
Shader "GLSL shader for billboards" {
Properties {
_MainTex ("Texture Image", 2D) = "white" {}
}
SubShader {
Pass {
GLSLPROGRAM
// User-specified uniforms
uniform sampler2D _MainTex;
// Varyings
varying vec4 textureCoords;
#ifdef VERTEX
void main()
{
gl_Position = gl_ProjectionMatrix
* (gl_ModelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0)
+ vec4(gl_Vertex.x, gl_Vertex.y, 0.0, 0.0));
textureCoords =
vec4(gl_Vertex.x + 0.5, gl_Vertex.y + 0.5, 0.0, 0.0);
}
#endif
#ifdef FRAGMENT
void main()
{
gl_FragColor = texture2D(_MainTex, vec2(textureCoords));
}
#endif
ENDGLSL
}
}
}
請注意,我們從未將模型矩陣應用於物件座標,因為我們不想旋轉它們。但是,這意味著我們也不能縮放它們。儘管如此,如果您在 Unity 中為立方體指定了縮放因子,您會注意到公告板實際上被縮放了。原因是 Unity 在物件座標被髮送到頂點著色器之前執行了縮放(除非所有三個縮放因子都是正數且相等,然後縮放由 1.0 / unity_Scale.w 指定)。因此,為了縮放公告板,您可以使用 Unity 的縮放功能(使用 和 的不同縮放因子),或者您可以在頂點著色器中引入額外的著色器屬性來縮放物件座標。
恭喜你完成了本教程。我們已經看到了
- 如何變換和紋理化一個立方體以渲染一個與檢視對齊的公告板。
如果您還想了解更多