跳轉到內容

GLSL 程式設計/Blender/RGB 立方體

來自華夏公益教科書,開放世界的開放書籍
一個 RGB 立方體:x、y、z 座標被對映到紅色、綠色和藍色顏色分量。

本教程介紹了變化變數。它建立在關於最小著色器的教程之上。

在本教程中,我們將編寫一個著色器來渲染一個類似於左側所示的 RGB 立方體。表面上每個點的顏色由其座標決定;即,位於位置 的點具有顏色 。例如,點 被對映到顏色 ,即純藍色。(這是左側圖形右下角的藍色角點。)

準備工作

[編輯 | 編輯原始碼]

由於我們要建立一個 RGB 立方體,你首先要按照關於最小著色器的教程中的描述建立立方體網格。繼續按照關於最小著色器的教程中的描述建立 Python 指令碼和遊戲邏輯。

著色器程式碼

[編輯 | 編輯原始碼]

以下是頂點著色器的原始碼,您應該將其複製並貼上到 Python 指令碼中對 VertexShader 的賦值。

        varying vec4 position; 
           // this is a varying variable in the vertex shader
         
        void main()
        {
            position = 0.5 * (gl_Vertex + vec4(1.0, 1.0, 1.0, 0.0));
               // Here the vertex shader writes output(!) to the 
               // varying variable. We add 1.0 to the x, y, and z 
               // coordinates and multiply by 0.5, because the 
               // coordinates of the cube are between -1.0 and 1.0 
               // but we need them between 0.0 and 1.0 
            gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
         }

以下是片段著色器的原始碼,應該將其分配給 FragmentShader

         varying vec4 position; 
            // this is a varying variable in the fragment shader
         
         void main()
         {
            gl_FragColor = position;
               // Here the fragment shader reads intput(!) from the 
               // varying variable. The red, gree, blue, and alpha 
               // component of the fragment color are set to the 
               // values in the varying variable. (The alpha 
               // component of the fragment doesn't matter here.) 
         }

如果您的立方體沒有正確著色,請檢查控制檯是否有錯誤訊息。

變化變數

[編輯 | 編輯原始碼]

我們著色器的主要任務是在片段著色器中將輸出片段顏色 (gl_FragColor) 設定為在頂點著色器中可用的位置 (gl_Vertex)。實際上,這並不完全正確:Blender 預設立方體的 gl_Vertex 中的座標在 -1.0 和 +1.0 之間,而我們希望顏色分量在 0.0 和 1.0 之間;因此,我們需要將 1.0 新增到 x、y 和 z 分量,並將結果乘以 0.5,這由以下表達式完成:0.5 * (gl_Vertex + vec4(1.0, 1.0, 1.0, 0.0))

然而,主要問題是:我們如何將頂點著色器中的任何值傳遞到片段著色器?事實證明,做到這一點的唯一方法是使用變化變數(或簡稱變化量)。頂點著色器的輸出可以寫入變化變數,然後片段著色器可以將其作為輸入讀取。這正是我們需要的。

要指定變化變數,它必須在頂點著色器和片段著色器中以 varying 修飾符(在型別之前)定義,位於任何函式之外;在我們的示例中:varying vec4 position;。這裡是最重要的關於變化變數的規則

這是為了避免出現 GLSL 編譯器無法確定頂點著色器的哪個變化變數應該與片段著色器的哪個變化變數匹配的模糊情況。

此著色器的變體

[編輯 | 編輯原始碼]

RGB 立方體表示可用的顏色集(即顯示器的色域)。因此,它也可以用來顯示顏色變換的效果。例如,顏色到灰度變換將計算紅色、綠色和藍色顏色分量的平均值,即,然後將此值放入片段顏色的所有三個顏色分量中,以獲得相同強度的灰度值。除了平均值,還可以使用相對亮度,即。當然,任何其他顏色變換(改變飽和度、對比度、色調等)也適用。

此著色器的另一種變體可以計算一個 CMY(青色、洋紅色、黃色)立方體:對於位置 ,您可以從純白色中減去與 成比例的紅色量,以生成青色。此外,您將減去與 分量成比例的綠色量,以生成洋紅色,以及與 成比例的藍色量,以生成黃色。

如果您真的想變得花哨,您可以計算一個 HSV(色調、飽和度、明度)圓柱體。對於 座標在 -0.5 到 +0.5 之間,您可以獲得一個角度 ,在 GLSL 中使用 180.0+degrees(atan(z, x)) 介於 0 到 360° 之間,以及一個距離 ,在 0 到 1 之間,從 軸使用 2.0 * sqrt(x * x + z * z) 計算。Blender 內建圓柱體的 座標在 -1 到 1 之間,可以使用 轉換為 0 到 1 之間的值 。關於從 HSV 座標計算 RGB 顏色的描述,請參見 維基百科上關於 HSV 的文章

插值變化變數

[編輯 | 編輯原始碼]

關於變化變數的故事還沒有結束。如果您在 **3D 檢視** 中選擇立方體物件並切換到 **編輯模式**,您將看到它只包含 8 個頂點。因此,頂點著色器可能只被呼叫 8 次,並且只有 8 個不同的輸出被寫入變化變數。但是,立方體上還有更多顏色。這是怎麼發生的?

答案隱含在 **變化** 變數的名稱中。它們之所以被稱為變化變數,是因為它們在三角形上變化。(請注意,所有多邊形在 OpenGL 中渲染之前都會分解成三角形。)事實上,頂點著色器只為每個三角形的每個頂點呼叫。如果頂點著色器對不同頂點的變化變數寫入不同的值,則這些值會在三角形上插值。然後,片段著色器被呼叫以處理被三角形覆蓋的每個畫素,並接收變化變數的插值值。這種插值的詳細資訊在 “光柵化” 中描述。

如果您想確保片段著色器從頂點著色器接收一個確切的、非插值的變數,您必須確保頂點著色器對三角形的每個頂點寫入變化變數的相同值。

本教程到此結束。恭喜!除其他事項外,您已瞭解到:

  • 什麼是 RGB 立方體。
  • 變化變數的用途以及如何定義它們。
  • 頂點著色器寫入變化變數的值如何在三角形上插值,然後由片段著色器接收。

進一步閱讀

[編輯 | 編輯原始碼]

如果您想了解更多


< GLSL 程式設計/Blender

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