1、OpenGL 與 著色器
在OpenGL 3.0之前领铐,OpenGL 包含一個(gè)固定功能的管線勘纯,它可以在不使用著色器的情況下處理幾何與像素?cái)?shù)據(jù)。在3.1版本開始磷仰,固定管線從核心模式去掉。因此現(xiàn)在需要使用著色器來完成工作境蔼。
2灶平、OpenGL 基礎(chǔ)圖形管線
OpenGL 中的土元不過是頂點(diǎn)的集合以預(yù)定義的方式結(jié)合在一起伺通。例如:一個(gè)單獨(dú)的點(diǎn)就是一個(gè)圖元,它只需要一個(gè)頂點(diǎn)逢享。
2.1 渲染管線簡化版本
客戶機(jī)罐监、服務(wù)器
管線分為上下2部分,上部分是客戶端瞒爬,而下半部分則是服務(wù)端弓柱。
客戶端是存儲在CPU存儲器中的,并且在應(yīng)用程序中執(zhí)行侧但,或者在主系統(tǒng)內(nèi)存的驅(qū)動程序中執(zhí)行矢空。驅(qū)動程序會將渲染命令和數(shù)組組合起來,發(fā)送給服務(wù)器執(zhí)行 !(在一臺典型的個(gè)人計(jì)算機(jī)上禀横,服務(wù)器實(shí)際上就是圖形加速卡上的硬件和內(nèi)存)
服務(wù)器和客戶機(jī)在功能上也是異步的屁药。 它們是各自獨(dú)立的軟件塊或硬件塊。我們是希望它們2個(gè)端都盡量在不停的工作柏锄∧鸺客戶端不斷的把數(shù)據(jù)塊和命令塊組合在一起輸送到緩沖區(qū),然后緩沖區(qū)就會發(fā)送到服務(wù)器執(zhí)行绢彤。
如果服務(wù)器停止工作等待客戶機(jī)七问,或者客戶機(jī)停止工作來等待服務(wù)器做好接受 多的命令和準(zhǔn)備,我們把這種情況成為管線停滯茫舶。
著色器
上圖的Vertex Shader(頂點(diǎn)著色器) 和 Fragment Shader(片元著色器)械巡。
著色器是勇士GLSL編寫的程序,看起來與C語言非常類似饶氏。著色器必須從源碼中編譯和鏈接在一起讥耗。最終準(zhǔn)備就緒的著色器程序。
頂點(diǎn)著色器:處理從客戶機(jī)出入的數(shù)據(jù)疹启、應(yīng)用轉(zhuǎn)換古程、進(jìn)行其他的類型的數(shù)學(xué)運(yùn)算來計(jì)算光照效果、位移喊崖、顏色值等等挣磨。
渲染一個(gè)有3個(gè)頂點(diǎn)的三角形,頂點(diǎn)著色器將執(zhí)行3次荤懂,每個(gè)頂點(diǎn)執(zhí)行一次渲染茁裙。(在目前的硬件上有多個(gè)執(zhí)行單元同時(shí)運(yùn)行,就意味著3個(gè)頂點(diǎn)可以同時(shí)進(jìn)行處理=诜隆)
如上圖所示晤锥,頂點(diǎn)著色器完成工作之后,到了 primitive Assembly(圖元裝配) 階段,說明三個(gè)頂點(diǎn)已經(jīng)組合在一起矾瘾,而三角形已經(jīng)逐個(gè)片段的進(jìn)行了光柵化女轿。每個(gè)片段通過執(zhí)行片元著色器進(jìn)行填充。片元著色器 會輸出我們在屏幕上看到的最終顏色值壕翩。
光柵化(Rasterization):光柵化階段把圖元轉(zhuǎn)換成片段集合蛉迹,之后會提交給片段著色器處理,這些片段集合表示可以被繪制到屏幕的像素戈泼。
輸出的時(shí)每個(gè)片段對應(yīng)的屏幕坐標(biāo)婿禽,和屬性(顏色赏僧,紋理坐標(biāo))
注意
我們必須在這之前為著色器提供數(shù)據(jù)大猛,否則什么都無法實(shí)現(xiàn)。
有3中想OpenGL 著色器傳遞渲染數(shù)據(jù)的方法:
- 屬性
- uniform值
- 紋理
3淀零、屬性挽绩、uniform值、紋理
3.1 屬性
屬性:就是對于每一個(gè)頂點(diǎn)都要作改變的數(shù)據(jù)元素驾中。實(shí)際上唉堪,頂點(diǎn)位置本身就是一個(gè)屬性。屬性值可以是浮點(diǎn)數(shù)肩民、整數(shù)唠亚、布爾數(shù)據(jù)。
屬性總是以四維向量的形式進(jìn)行內(nèi)部存儲的持痰,即使我們不會使用所有的4個(gè)分 量灶搜。一個(gè)頂點(diǎn)位置可能存儲(x,y,z),將占有4個(gè)分量中的3個(gè)工窍。
實(shí)際上如果是在平面情況下:只要在xy平面上就能繪制割卖,那么Z分量就會自動設(shè)置為0。
屬性還可以是:紋理坐標(biāo)患雏、顏色值鹏溯、光照計(jì)算表面法線。
在頂點(diǎn)程序(shader渲染)可以代表你想要的任何意義淹仑。因?yàn)槎际悄阍O(shè)定的丙挽。
屬性會從本地客戶機(jī)內(nèi)存中復(fù)制存儲在圖形硬件中的一個(gè)緩沖區(qū)上。這些屬性只提供給頂點(diǎn)著色器使用匀借,對于片元著色器沒有太大意義颜阐。
聲明:這些屬性對每個(gè)頂點(diǎn)都要做改變,但并不意味著它們的值不能重復(fù)怀吻。通常情況下瞬浓,它們都是不一樣的,但有可能整個(gè)數(shù)組都是同一值的情況蓬坡。
3.1 Uniform值
屬性是一種對整個(gè)批次屬性都取統(tǒng)一值的單一值猿棉。它是不變的磅叛。通過設(shè)置 uniform變量就緊接著發(fā)送一個(gè)圖元批次命令,Uniform變量實(shí)際上可以無數(shù)次限制地使用萨赁,設(shè)置一個(gè)應(yīng)用于整個(gè)表面的單個(gè)顏色值弊琴,還可以設(shè)置一個(gè)時(shí)間值。在每次渲染某種類型的頂點(diǎn)動畫時(shí)修改它杖爽。
uniform變量最常見的應(yīng)用是在頂點(diǎn)渲染中設(shè)置變換矩陣敲董。
與屬性相同點(diǎn):可以是浮點(diǎn)值、整數(shù)慰安、布爾值 腋寨。
與屬性不同點(diǎn):頂點(diǎn)著色器和片元著色器都可以使用 uniform 變量。
uniform 變量還可以是標(biāo)量類型化焕、矢量類型萄窜、uniform矩陣。
注意
uniform 變量每個(gè)批次改變一次撒桨,而不是每個(gè)頂點(diǎn)改變一次查刻。
3.3紋理
在頂點(diǎn)著色器、片元著色器中都可以對紋理數(shù)據(jù)進(jìn)行采樣和篩選凤类。
典型的應(yīng)用場景: 片元著色器對一個(gè)紋理值進(jìn)行采樣穗泵,然后在一個(gè)三角形表面應(yīng)用渲染紋理數(shù)據(jù)。
紋理數(shù)據(jù)谜疤, 僅僅表現(xiàn)在圖形佃延,很多圖形文件格式都是以無符號字節(jié) (每個(gè)顏色通道8位)形式對顏色分量進(jìn)行存儲的。
附上本篇的demo:demo下載地址