為何要在GLSL中使用UBO

2021-06-16 10:14:04 字數 1548 閱讀 9546

關於ubo的介紹和使用詳情,請看

除了opengl手冊,應該沒有比這個更詳細的了。

最近在乙個glsl專案中,需要迴圈繪製多塊buffer,而每次迴圈都要給buffer傳入大量的uniform,導致shader的渲染效率極低。

比如之前的**是類似這個樣子:

m_pprogramblock->senduniform3fv(a);

m_pprogramblock->senduniform3fv(b);

m_pprogramblock->senduniform3fv(c);

m_pprogramblock->senduniform3fv(d);

gldrawelements(...);

相應的,在shader中uniform有如下定義:

#version 330

uniform vec3 a;

uniform vec3 b;

uniform vec3 c;

uniform vec3 d;

結果在效能測試中發現,每執行一次senduniform的操作耗費的時間居然大於執行一次gldrawelements的時間!

glsl提供了ubo技術能很好的解決這個問題。通過把uniform繫結到顯示卡的緩衝區,可以極大提公升修改uniform資料的速度。此外他的最大優勢在於能在shader之間共享uniform。ubo的詳細說明請參閱

修改後的opengl**是類似這個樣子:

glbindbuffer(gl_uniform_buffer, m_ubohandle);

glbuffersubdata(gl_uniform_buffer, 0, 16, (char*)(&a);

glbuffersubdata(gl_uniform_buffer, 16, 16, (char*)(&b);

glbuffersubdata(gl_uniform_buffer, 32, 16, (char*)(&b);

glbuffersubdata(gl_uniform_buffer, 48, 16, (char*)(&b);

gldrawelements(...);

相應的,在shader中uniform有如下定義:

#version 330

layout(std140) uniform blobsettingsblob;

那麼到底效能差異有多大呢?使用vs2012的效能測試,可以得到如下資料:

senduniform占用了9.4%的渲染時間,而一條glbuffersubdata只占用了0.1%!

使用glbuffersubdata的效率比使用senduniform高將近2個數量級!

然而使用ubo也要付出代價。因為每個顯示卡不同,ubo裡每個uniform所占用位元組數都未必相同,即使你指定了layout(std140)。

不要在v for中使用v if

一 前言 以下 寫法,相信80 的初學者寫過,即使沒寫過,也應該見過!v for product in products key product.id v if product.price 50 li ul 使用 v if 來過濾 v for 迴圈的資料是乙個超級大錯誤!儘管這看起來很直觀,但它會導...

OpenGL中使用GLSL著色器

opengl中使用glsl著色器步驟 glsl既適用於頂點著色器,也適用於片段著色器。使用著色器物件的步驟 1 建立著色器物件 gluint glcreateshader glenum type 建立乙個著色器物件,type值必須是gl vertex shader或gl fragment shade...

不要在標頭檔案中使用using namespace

在這裡,我毫不迴避地說了這句話 引用我再也不想在任何標頭檔案中看到 using namespace 了 作為乙個開發者 團隊領導者,我經常會去招聘新的專案成員,有時候也幫助其他組的人來面試應聘者。作為應聘流程之一,我經常要求應聘者寫一些 因此我檢查過相當多的 在最近提交的c 中,我注意到乙個趨勢,在...