跳到内容

GLSL 编程/Unity/公告板

来自维基教科书,开放世界中的开放书籍
高速公路旁的公告板。注意公告板的朝向,以获得最佳可见度。

本教程介绍了**公告板**。

它基于“纹理球体”部分“顶点变换”部分 的讨论。

公告板

[编辑 | 编辑源代码]

在计算机图形学中,公告板是纹理矩形,它们被变换以始终平行于视平面。因此,它们类似于高速公路旁的公告板,它们被旋转以获得最佳可见度。但是,它们不同于高速公路公告板,因为它们会动态旋转以始终提供最佳可见度。

公告板的主要用途是使用二维图像替换复杂的 3D 模型(例如草、灌木甚至树木)。事实上,Unity 也使用公告板来渲染草。此外,公告板通常用于渲染 2D 精灵。在这两种应用中,至关重要的是公告板始终与视平面平行,以保持 3D 形状的错觉,尽管只渲染了 2D 图像。

公告板的顶点变换

[编辑 | 编辑源代码]

类似于“天空盒”部分,我们将使用默认的立方体对象来渲染公告板。基本思路是用标准变换 gl_ModelViewMatrix 将对象空间的原点 变换到视空间。(在齐次坐标中,所有点都具有 1 作为第四个坐标;参见“顶点变换”部分 的讨论。)视空间只是世界空间的旋转版本,其中 平面平行于视平面,如“顶点变换”部分 所述。因此,这是构建适当旋转的公告板的正确空间。我们将 对象坐标 (gl_Vertex.xgl_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 的缩放功能(使用 的不同缩放因子),或者您可以在顶点着色器中引入额外的着色器属性来缩放对象坐标。

恭喜你完成了本教程。我们已经看到了

  • 如何变换和纹理化一个立方体以渲染一个与视图对齐的公告板。

进一步阅读

[编辑 | 编辑源代码]

如果您还想了解更多


< GLSL 编程/Unity

除非另有说明,否则本页上的所有示例源代码均归属公有领域。
华夏公益教科书