深度揭秘(opengl編程實(shí)例)opengl編程精粹,OpenGL 可編程混合模式優(yōu)化,建站公司網(wǎng)站源碼,
目錄:
1.opengl編程基礎(chǔ)
2.opengl編程語(yǔ)言
3.簡(jiǎn)述opengl的編程步驟
4.opengl編程指南和超級(jí)寶典
5.opengl編程
6.opengl簡(jiǎn)單程序
7.《opengl游戲編程》
8.opengl圖形編程項(xiàng)目實(shí)戰(zhàn)
9.opengl是怎么編寫(xiě)的
10.opengl圖形編程
1.opengl編程基礎(chǔ)
快手Y-tech最新技術(shù)干貨分享摘要很多渲染效果只需要讀取當(dāng)前位置的一個(gè)像素進(jìn)行處理,但是為了讀取這一個(gè)像素不得不把整個(gè)輸入圖像作為紋理傳給片元著色器本文討論了 OpenGL 中針對(duì)此類(lèi)需求能帶來(lái)性能提升的措施。
2.opengl編程語(yǔ)言
背景OpenGL 提供了有限的混合模式設(shè)置方法,可以通過(guò) glB劍來(lái)人物簡(jiǎn)介和身份lend 和 glBlendFunc 來(lái)設(shè)置片元著色器輸出的像素如何與當(dāng)前幀緩存上已有的像素混合除了常用的把 alpha 通道當(dāng)作不透明度來(lái)混合,還可以實(shí)現(xiàn)乘法混合等方式。
3.簡(jiǎn)述opengl的編程步驟
固有功能可以實(shí)現(xiàn)的混合模式是有限的,一些混合方式必須通過(guò)在片元著色器中編程完成,此時(shí)需要要混合的目標(biāo)紋理綁定到管線(xiàn)上作為輸入紋理,并采樣對(duì)應(yīng)位置的像素例如“疊加”的混合模式是,當(dāng)基色小于等于 0.5 時(shí),結(jié)果色=基色×混合色。
4.opengl編程指南和超級(jí)寶典
當(dāng)基色大于 0.5 時(shí),結(jié)果色 = 1 - (1 - 基色) × (1 - 混合色) × 2,用 GLSL 表示:vec3 blend(v劍來(lái)人物簡(jiǎn)介和身份ec3 src, vec3 dst){return mix(src * dst,
5.opengl編程
1 - (1.0 - src) * (1.0 - dst) * 2.0, step(src, vec3(0.5)));}如果要多次執(zhí)行這種渲染,通常會(huì)使用兩個(gè)大小相同的幀緩存綁定兩個(gè)紋理,每次繪制后交換采樣源和繪制目標(biāo),這次從 A 采樣繪制到 B,下次就從 B 采樣繪制到 A,如此互相繪制,所使用的片元著色器:
6.opengl簡(jiǎn)單程序
#version 100uniform sampler2D texSrc;uniform sampler2D texDst;vec3 blend(vec3 src,劍來(lái)人物簡(jiǎn)介和身份 vec3 dst){return mix(src * dst,
7.《opengl游戲編程》
1 - (1.0 - src) * (1.0 - dst) * 2.0, step(src, vec3(0.5)));}void main() {vec3 src = texture2D(texSrc).rgb;
8.opengl圖形編程項(xiàng)目實(shí)戰(zhàn)
vec3 dst = texture2D(texDst).rgb;gl_FragColor = vec4(blend(src, dst), 1.0);}可以預(yù)見(jiàn),兩個(gè)幀緩存互相繪制要不斷切換目標(biāo)幀緩存,繪制過(guò)程中要進(jìn)行大量紋理采樣,效率肯定不如固有混合功能。
9.o劍來(lái)人物簡(jiǎn)介和身份pengl是怎么編寫(xiě)的
實(shí)際上我們只需要在片元著色器中讀取幀緩存下當(dāng)前對(duì)應(yīng)位置的像素顏色值正文一、OpenGL:Texture Barrier 擴(kuò)展一個(gè)自然的想法是,把當(dāng)前幀緩存上的紋理綁定到當(dāng)前管線(xiàn)上,然后在片元著色器里讀當(dāng)前位置的像素顏色值就行。
10.opengl圖形編程
但是在所有 OpenGL ES 版本和 OpenGL 4.5 之前的版本里(見(jiàn) OpenGL 4.4 specification, 9.3.1),讀寫(xiě)同一紋理是未定義行為,除非讀寫(xiě)同一紋理的不同 Mipmap 層次,而這實(shí)際上也相當(dāng)于不同紋理。
這個(gè)條件相當(dāng)保守,不論讀寫(xiě)區(qū)域是否重疊,讀寫(xiě)是否按條件發(fā)生,都會(huì)引發(fā)未定義行為NV劍來(lái)人物簡(jiǎn)介和身份IDIA 基于這一思路開(kāi)發(fā)了擴(kuò)展 GL_NV_texture_barrier,這個(gè)擴(kuò)展有兩個(gè)效果:(1)允許在片元著色器讀寫(xiě)同一紋理,但有限制條件,必須為以下兩種情況之一:
讀的區(qū)域與寫(xiě)的區(qū)域不相交;在整個(gè)渲染片元階段每個(gè)像素只能被讀寫(xiě)一次,且同一次執(zhí)行修改的必須是同一像素(2)提供 glTextureBarrierNV 函數(shù)用于同步當(dāng)前幀緩存的結(jié)果,使之前寫(xiě)入的結(jié)果能夠被讀取。
這里解釋一下,之前不需要 glTextureBarrierNV 接口,因?yàn)榍袚Q幀緩存對(duì)象和切換幀緩存對(duì)象綁定的紋理這兩個(gè)行為本身就會(huì)同步幀緩存上的像素,而之前不允許讀寫(xiě)同一紋理,將紋理從 FBO 上解綁后再綁定到管線(xiàn)紋理劍來(lái)人物簡(jiǎn)介和身份單元上本身就會(huì)使之前的寫(xiě)入操作得到同步。
GL_NV_texture_barrier 之后略加修改(glTextureBarrierNV 函數(shù)名去掉了后綴變成 glTextureBarrier)成為了 ARB 擴(kuò)展 GL_ARB_texture_barrier,并于 OpenGL 4.5 成為核心擴(kuò)展。
這個(gè)擴(kuò)展在桌面端顯卡上被廣泛實(shí)現(xiàn),MacBook Pro 2019 只支持到 OpenGL 4.1,但也支持 GL_NV_texture_barrier 擴(kuò)展使用 Texture Barrier 擴(kuò)展,上述著色器不用修改,只需要把當(dāng)前幀緩存的紋理綁定到 texDst 對(duì)應(yīng)的紋理單元即可。
二、Ope劍來(lái)人物簡(jiǎn)介和身份nGL ES:Framebuffer Fetch 擴(kuò)展移動(dòng)端普遍使用統(tǒng)一內(nèi)存架構(gòu)和 Tile Based 架構(gòu),此時(shí) GPU 的 cache 較小,制約性能的因素是數(shù)據(jù)帶寬,上述 GL_NV_texture_barrier 擴(kuò)展實(shí)現(xiàn)起來(lái)需要在多個(gè) render pass 間將數(shù)據(jù)寫(xiě)回紋理進(jìn)行同步,較為耗費(fèi)帶寬,因此在移動(dòng)平臺(tái)上實(shí)現(xiàn)極少。
移動(dòng)平臺(tái)上主要使用擴(kuò)展 GL_ARM_shader_framebuffer_fetch,GL_EXT_shader_framebuffer_fetch 或 GL_NV_shader_framebuffer_fetch。
這些擴(kuò)展的“侵入性”比上節(jié)的 GL_NV_t劍來(lái)人物簡(jiǎn)介和身份exture_barrier 更強(qiáng),它們?nèi)匀徊辉试S直接讀寫(xiě)同一紋理,而是需要在著色器中開(kāi)啟擴(kuò)展并使用擴(kuò)展寫(xiě)法讀取幀緩存像素,具體的寫(xiě)法有細(xì)節(jié)上的差別,但都是以某種方式讓片元著色器能夠讀取幀緩存當(dāng)前位置像素的值:
GL_NV_shader_framebuffer_fetch:增加內(nèi)置變量 gl_LastFragData(vec4 數(shù)組)與 gl_LastFragColor(vec4 變量,與 gl_LastFragData[0] 等價(jià))可在片元著色器中直接得到當(dāng)前幀緩存中各附著紋理當(dāng)前位置像素的值。
此擴(kuò)展實(shí)現(xiàn)極少GL_ARM_shader_framebuffer_fetch:增加內(nèi)置變量 gl_L劍來(lái)人物簡(jiǎn)介和身份astFragColorARM(vec4 變量),可在片元著色器中直接得到當(dāng)前幀緩存中 0 號(hào)附著紋理當(dāng)前位置像素的值。
GL_EXT_shader_framebuffer_fetch:GL ES 2.0 中該擴(kuò)展會(huì)增加內(nèi)置數(shù)組變量 gl_LastFragData(vec4 數(shù)組),可在片元著色器中直接得到當(dāng)前幀緩存中各附著紋理當(dāng)前位置像素的值;
GL ES 3.0+ 中該擴(kuò)展則允許把片元著色器的輸出變量聲明為 inout 進(jìn)行讀取,讀取到的值就是當(dāng)前幀緩存中各附著紋理當(dāng)前位置像素的值以GL_NV_shader_framebuffer_fetch的擴(kuò)展。
為例,要使用這個(gè)擴(kuò)展,之前的 shader 劍來(lái)人物簡(jiǎn)介和身份要改成這樣:#version 100#extension GL_EXT_shader_framebuffer_fetch : requireuniform sampler2D texSrc;
vec3 blend(vec3 src, vec3 dst){return mix(src * dst, 1 - (1.0 - src) * (1.0 - dst) * 2.0, step(src, vec3(
0.5)));}void main() {vec3 src = texture2D(texSrc).rgb;vec3 dst = gl_lastFragData[0].rgb;gl_FragColor劍來(lái)人物簡(jiǎn)介和身份 = vec4(blend(src, dst),
1.0);}語(yǔ)義上混合所用基色改為來(lái)自 gl_lastFragData[0] 而非從紋理中讀取具體實(shí)現(xiàn)上,著色器在執(zhí)行時(shí)會(huì)直接讀取 GPU 當(dāng)前緩存 Tile 中的值,而不用進(jìn)行內(nèi)存存取和紋理采樣操作,節(jié)省了帶寬和 GPU 運(yùn)算資源。
三、Metal 和 Vulkan 中的相關(guān)概念Metal 允許在片元著色器參數(shù)中指定屬性 [[color(N)]] 來(lái)獲取 N 號(hào)幀緩存顏色附著的當(dāng)前值,這類(lèi)似于上述 Framebuffer Fetch 擴(kuò)展;在 MacOS 上 Metal 也支持類(lèi)似類(lèi)似上述 Texture Barrier 的接口。
Vulkan 則劍來(lái)人物簡(jiǎn)介和身份是通過(guò) subpass 的概念實(shí)現(xiàn)優(yōu)化,一個(gè) render pass 中的 subpass 可以直接讀取輸出附著當(dāng)前位置的像素值,使用的著色器語(yǔ)法是使用 subpassInput 變量,類(lèi)似上述 Framebuffer Fetch 擴(kuò)展。
參考文獻(xiàn)[1]https://www.khronos.org/opengl/wiki/Memory_Model[2]https://developer.apple.com/library/archive/documentation/3DDrawing/Conceptual/OpenGLES_ProgrammingGuide/BestPracticesforSh劍來(lái)人物簡(jiǎn)介和身份aders/BestPracticesforShaders.html#//apple_ref/doc/uid/TP40008793-CH7-SW23
你可能還想看
基于單目3D人體姿態(tài)估計(jì)的虛擬穿衣周杰倫MV同款水體特效的背后技術(shù)風(fēng)格化變老—遇見(jiàn)變老的你
等你來(lái) Y-tech快手Y-tech部門(mén)致力于通過(guò)計(jì)算機(jī)視覺(jué)、計(jì)算機(jī)圖形學(xué)、深度學(xué)習(xí)、AR/VR/HCI等多領(lǐng)域的交叉,幫助每個(gè)人更好地表達(dá)、創(chuàng)作以及互動(dòng)Y-tech在北京、深圳、Palo Alto均有研發(fā)團(tuán)隊(duì)。
如果你對(duì)我們做的事情感興趣,歡迎聯(lián)系并加入我們!Y-tech長(zhǎng)期招聘(全職或?qū)嵙?xí)生):計(jì)算機(jī)視覺(jué)、計(jì)算機(jī)圖形學(xué)、UE/Unity開(kāi)發(fā)、技術(shù)劍來(lái)人物簡(jiǎn)介和身份美術(shù)、AI推理引擎、AI工程架構(gòu)、美顏/特效技術(shù)、平臺(tái)/工具開(kāi)發(fā)、技術(shù)產(chǎn)品經(jīng)理等方向的優(yōu)秀人才。
聯(lián)系方式:ytechservice@kuaishou.comY-tech///