OpenGL日常 著色器

2021-10-08 23:37:16 字數 3991 閱讀 6463

由屬性展開去

向量寫在後面

本文**

本篇我們通過opengl的資料流動來理解著色器,通過資料流會很清楚的看到opengl著色器的工作原理。所以今天要說的內容全部跟glsl語言有關,當然這樣的一篇不可能全部講完(可能連皮毛都沒有),理解著色器是如何傳資料的才是我們的重點。

話不多說,一圖以蔽之。

如圖中,上部cpu的部分為頂點資料,其中包含頂點、顏色資料(一般情況下);下部分橙色為頂點著色器,綠色為片元著色器;gl_position內建變數用於頂點位置設定,gl_flagcolor內建變數用於片元顏色設定。

頂點著色器shader.vs

#version 330 core

layout (location=0) in vec3 position;

layout (location=1) in vec3 color;

attribute vec2 tex_coord;

varying vec2 transform_to_frag;

out vec4 vertex_color;

void main()

片元著色器shader.frag

#version 330 core

in vec4 vertex_color;

varying vec2 transform_to_frag;

uniform sampler2d color_map;

out vec4 color;

void main()

如其英文所代表的含義,理解起來也很直觀,對於每乙個著色器而言,從外部獲取的資料為in屬性,傳出的資料為out屬性;

這裡有一點,對於頂點著色器中的out屬性變數,如在片元著色器中有同名的in屬性變數,則為同一變數,因為這樣的屬性不可以在全域性使用,所以採用這樣的方式可以傳值。(還有其他方式也可以傳值)

在上面的頂點著色器中,

layout (location=0) in vec3 position;

layout (location=1) in vec3 color;

包含有layout (location=0)屬性的in變數,在前面的幾節中,我們知道著色器通過glvertexattribpointer分配頂點資料,其中,location決定著色器從頂點快取中獲取資料的方式。

// 位置屬性

glvertexattribpointer(0, 3, gl_float, gl_false, 6 * sizeof(glfloat), (glvoid*)0);

glenablevertexattribarray(0);

// 顏色屬性

頂點和顏色資料在記憶體中的分配如圖,glenablevertexattribarray中的引數標識location的數字,表示向著色器中傳送的資料在記憶體中的起始點;每個vertex在記憶體中都是固定的大小,包含我們所需要的所有資料,在選取其中的資料時,需要提供步長來指明下一次的初始位置,如圖,每個頂點資料有6個位元組,位置與顏色資料分別佔了3個位元組。

attribute變數是只能在vertex shader中使用的變數。(它不能在fragment shader中宣告attribute變數,也不能被fragment shader中使用)

一般用attribute變數來表示一些頂點的資料,如:頂點座標,法線,紋理座標,頂點顏色等。

varying變數是vertex和fragment shader之間做資料傳遞用的。一般vertex shader修改varying變數的值,然後fragment shader使用該varying變數的值。因此varying變數在vertex和fragment shader二者之間的宣告必須是一致的。所以它是只著色器之間使用,不能被應用程式呼叫;

如果uniform變數在vertex和fragment兩者之間宣告方式完全一樣,則它可以在vertex和fragment共享使用。(相當於乙個被vertex和fragment shader共享的全域性變數)

uniform變數一般用來表示:變換矩陣,材質,光照引數和顏色等資訊。

關於這一節從網上覆制了一下,就不做具體討論了,需要注意的是「重組」的概念。

和其他程式語言一樣,glsl有資料型別可以來指定變數的種類。glsl中包含c等其它語言大部分的預設基礎資料型別:int、float、double、uint和bool。glsl也有兩種容器型別,它們會在這個教程中使用很多,分別是向量(vector)和矩陣(matrix),今天只針對向量做一些介紹。

glsl中的向量是乙個可以包含有1、2、3或者4個分量的容器,分量的型別可以是前面預設基礎型別的任意乙個。它們可以是下面的形式(n代表分量的數量):

型別含義

vecn

包含n個float分量的預設向量

bvecn

包含n個bool分量的向量

ivecn

包含n個int分量的向量

uvecn

包含n個unsigned int分量的向量

dvecn

包含n個double分量的向量

乙個向量的分量可以通過vec.x這種方式獲取,這裡x是指這個向量的第乙個分量。你可以分別使用.x、.y、.z和.w來獲取它們的第1、2、3、4個分量。glsl也允許你對顏色使用rgba,或是對紋理座標使用stpq訪問相同的分量。

vec2 somevec;

vec4 differentvec = somevec.xyxx;

vec3 anothervec = differentvec.zyw;

vec4 othervec = somevec.***x + anothervec.yxzy;

你可以使用上面4個字母任意組合來建立乙個和原來向量一樣長的(同型別)新向量,只要原來向量有那些分量即可;然而,你不允許在乙個vec2向量中去獲取.z元素。我們也可以把乙個向量作為乙個引數傳給不同的向量建構函式,以減少需求引數的數量:

vec2 vect = vec2(0.5f, 0.7f);

vec4 result = vec4(vect, 0.0f, 0.0f);

vec4 otherresult = vec4(result.xyz, 1.0f);

個人理解著色器更靠近硬體,可以直接使用硬體進行計算以提公升效率,但是外部程式並不能用高階語言來對其進行操作,所以著色器程式就建立起來乙個這樣的橋梁,由外部獲取再由著色器計算並最終渲染,glsl語言提供了外部傳入以及傳出的「介面」。

OpenGL著色器程式解析 著色器基礎

部分內容 於 現代opengl渲染管線嚴重依賴著色器來處理傳入的資料。如果不使用著色器,那麼用opengl可以做到的事情可能只有清除視窗內容了,可見著色器對於opengl的重要性。在opengl 3.0版本以前 含該版本 或者如果你用到了相容模式 compatibility prof?ile 環境,...

Opengl(四) 著色器

1.opengl確保至少有16個包含4個元素的頂點屬性可用。2.不同著色器之間的資料傳輸,在傳送方中宣告乙個輸出,在接收方中宣告乙個同名輸入。3.uniform是全域性的,uniform會一直保留他的資料,直到他被重置或更新。4.設定uniform的方式 glint x glgetuniformlo...

著色器與OpenGL

現代opengl渲染管線嚴重依賴著色器來處理傳入的資料。如果不使用著色器,那麼用opengl可以做到的事情可能只有清除視窗內容了,可見著色器對於opengl的重要性。在opengl 3.0版本以前 含該版本 或者如果你用到了相容模式 compatibility prof?ile 環境,opengl還...