版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1010使用uniform塊來優(yōu)化對uniform變量的讀寫Uniform塊如果shader程序變得比較復(fù)雜,那么其中用到的uniform變量數(shù)量也會上升。通常會在多個(gè)shader程序中用到同一個(gè)uniform變量。而uniformbufferobject就是一種優(yōu)化uniform變量訪問,以及在不同的shader程序間共享uniform數(shù)據(jù)的方法。寫法首先了解一下uniform塊的寫法。uniformb{//‘b’對應(yīng)于外部訪問時(shí)的名稱vec4v1;//塊中的變量列表boolv2;//…};//訪問成員時(shí)使用v1、v2或者uniformb{//‘b’對應(yīng)于外部訪問時(shí)的名稱vec4v1;//塊中的變量列表boolv2;//…}name;//訪問成員時(shí)使用name.v1、name.v2注意,shader程序中的數(shù)據(jù)類型有兩種:不透明的和透明的;其中不透明的包括sampler、image和atomiccounter。一個(gè)uniform塊中只能包含透明類型的變量。另外,在同一個(gè)shader程序里的兩個(gè)uniform塊,里面的變量名都不能相同。下面我們以具體例子的編寫過程來說明在如何使用uniform塊,順便了解一下CSharpGL是如何簡化對uniform塊的使用的。回到頂部(gototop)Shader我認(rèn)為用ModernOpenGL渲染,首先要寫shader。我們先看一個(gè)簡單的vertexshader。復(fù)制代碼#version330coreuniformmat4projectionMatrix;uniformmat4viewMatrix;uniformmat4modelMatrix;invec3vPos;invec3vColor;outvec3fColor;11voidmain(void){99{12gl_Position=projectionMatrix*viewMatrix*modelMatrix*vec4(vPos,1.0);fColor=vColor;}復(fù)制代碼Uniforms”我們就把這里面的uniform變量換作塊,如下,只是把原來的uniformUniforms”復(fù)制代碼#version330coreuniformUniforms{mat4projectionMatrix;mat4viewMatrix;mat4modelMatrix;};invec3vPos;invec3vColor;outvec3fColor;voidmain(void){gl_Position=projectionMatrix*viewMatrix*modelMatrix*vec4(vPos,1.0);fColor=vColor;}復(fù)制代碼而fragmentshader則更簡單:復(fù)制代碼#version330coreinvec3fColor;outvec4out_Color;voidmain(void){out_Color=vec4(fColor,1.0f);}復(fù)制代碼回到頂部(gototop)準(zhǔn)備工作傳送一個(gè)自定義的structUniform塊,實(shí)際上對應(yīng)一個(gè)在應(yīng)用程序客戶端的struct類型。對于示例中的‘Uniforms'塊,我們可以定義如下的結(jié)構(gòu)體。為了方便對照,我們也用‘Uniforms'作為struct名,其實(shí)你可以用任意你喜歡的名字。復(fù)制代碼structUniforms:IEquatable<Uniforms>{publicmat4projection;publicmat4view;publicmat4model;publicUniforms(mat4projection,mat4view,mat4model)TOC\o"1-5"\h\z{jection=projection;this.view=view;this.model=model;}publicboolEquals(Uniformsother){jection==jection&&this.view==other.view&&this.model==other.model;}}復(fù)制代碼今后我們就將數(shù)據(jù)準(zhǔn)備好后保存到一個(gè)Uniforms對象,最終傳送到shader。uniform塊結(jié)構(gòu)這里是重點(diǎn)了。傳送float類型的uniform變量,我們有UniformFloat;傳送vec3類型的uniform變量,我們有UniformVec3。但是uniform塊傳送的是一個(gè)個(gè)可以任意自定義的不同的結(jié)構(gòu)體(例如上面的structUniforms),因此最好用一個(gè)泛型的UniformBlock<T>。復(fù)制代碼publicclassUniformBlock<T>:UniformSingleVariableBasewhereT:struct,IEquatable<T>{protectedTvalue;publicTValue{get{returnthis.value;}set10if(!value.Equals(this.value))1112this.value=value;13this.Updated=true;1415161718publicUniformBlock(stringblockName):base(blockName){}192010if(!value.Equals(this.value))1112this.value=value;13this.Updated=true;1415161718publicUniformBlock(stringblockName):base(blockName){}1920publicUniformBlock(stringblockName,Tvalue):base(blockName){this.Value=value;}2122protectedoverridevoidDoSetUniform(ShaderProgramprogram)2324//...2526復(fù)制代碼UniformBlock<T>更新uniform塊的操作比較復(fù)雜:它要?jiǎng)?chuàng)建一個(gè)uniformbufferobject,并與之綁定;以后它只需更新這個(gè)buffer里的數(shù)據(jù),就可以實(shí)現(xiàn)對uniform塊的更新。DoSetUniformSetUniform()對于普通的uniform變量,CSharpGL用Renderer.SetUniform(stringvarName,Tvalue)whereT:struct即可(無論是什么類型的uniform都可以處理)。對于Uniform塊,也可以用這個(gè)方法!回到頂部(gototop)UniformBlockRenderer有了上述準(zhǔn)備,我們就可以使用uniform塊了。創(chuàng)建渲染器按照CSharpGL的傳統(tǒng),下面來創(chuàng)建一個(gè)UniformBlockRenderer,負(fù)責(zé)加載shader、模型數(shù)據(jù)和渲染工作。復(fù)制代碼classUniformBlockRenderer:RendererpublicstaticUniformBlockRendererCreate()varmodel=newTeapot();//modelvarshaderCodes=newShaderCode[2];//shadersshaderCodes[0]=newShaderCode(File.ReadAllText(@"shaders\UniformBlock.vert"),ShaderType.VertexShader);shaderCodes[1]=newShaderCode(File.ReadAllText(@"shaders\UniformBlock.frag"),ShaderType.FragmentShader);varmap=newAttributeNameMap();//mappingrelationbetweenmodelandshadersmap.Add("vPos",Teapot.strPosition);map.Add("vColor",Teapot.strColor);varrenderer=newUniformBlockRenderer(model,shaderCodes,map);//rendererreturnrenderer;}}復(fù)制代碼設(shè)置uniform塊的值就像普通的uniform變量一樣,我們也在Renderer.DoRender()方法里更新uniform塊。復(fù)制代碼protectedoverridevoidDoRender(RenderEventArgsarg){mat4projection=arg.Camera.GetProjectionMatrix();mat4view=arg.Camera.GetViewMatrix();mat4model=this.GetModelMatrix();//設(shè)置uniform塊,只需這一行。this.SetUniform("Uniforms",newUniforms(projection,view,model));base.DoRender(arg);}復(fù)制代碼完成的效果如圖,能夠正常渲染,說明我們成功地更新了uniform塊里的數(shù)據(jù)?;氐巾敳?gototop)下載CSharpGL已在GitHub開源,歡迎對OpenGL有興趣的同學(xué)力口入(/bitzhuwei/CSharpGL)回到頂部(gototop)總結(jié)借助C#的struct與byte□的相互轉(zhuǎn)換,加上CSharpGL對ModernRendering的封裝,實(shí)際上我們不需要調(diào)用glGetUniformIndices、glGetActiveUniformsiv(用于獲取shader中uniform塊里的各個(gè)變量的偏移量)這些接口,就可以使用uniform塊了。當(dāng)shader中寫了一個(gè)uniform塊時(shí),你只需在應(yīng)用程序客戶端也寫一個(gè)對應(yīng)的struct,然后用Renderer.SetUniform(blockName,structObj);一行即可實(shí)現(xiàn)對uniform塊數(shù)據(jù)的更新。PS:測試過程中發(fā)現(xiàn)對于vec3結(jié)果正常,但是v
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 寵物馴導(dǎo)師復(fù)試測試考核試卷含答案
- 高爐原料工班組評比模擬考核試卷含答案
- 涂料調(diào)配工操作能力評優(yōu)考核試卷含答案
- 營養(yǎng)指導(dǎo)員安全知識宣貫知識考核試卷含答案
- 客戶關(guān)系管理信息庫工具
- 鼓風(fēng)爐工標(biāo)準(zhǔn)化水平考核試卷含答案
- 鉭鈮壓制成型工風(fēng)險(xiǎn)評估與管理強(qiáng)化考核試卷含答案
- 2025重慶永晟新能源科技有限公司招聘筆試參考題庫附帶答案詳解(3卷)
- 2025浙江臺州市環(huán)境科學(xué)設(shè)計(jì)研究院有限公司公開招聘2名筆試參考題庫附帶答案詳解(3卷)
- 2025年遼寧大連公交客運(yùn)集團(tuán)有限公司招聘營運(yùn)駕駛員30人筆試參考題庫附帶答案詳解(3卷)
- 基于SystemView的數(shù)字通信仿真課程設(shè)計(jì)
- 物業(yè)二次裝修管理規(guī)定
- GB 10133-2014食品安全國家標(biāo)準(zhǔn)水產(chǎn)調(diào)味品
- FZ/T 92023-2017棉紡環(huán)錠細(xì)紗錠子
- 現(xiàn)代詩的寫作課件
- 采氣工程課件
- 非洲豬瘟實(shí)驗(yàn)室診斷電子教案課件
- 工時(shí)的記錄表
- 金屬材料與熱處理全套ppt課件完整版教程
- 熱拌瀝青混合料路面施工機(jī)械配置計(jì)算(含表格)
- 水利施工CB常用表格
評論
0/150
提交評論