版權說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權,請進行舉報或認領
文檔簡介
1010使用uniform塊來優(yōu)化對uniform變量的讀寫Uniform塊如果shader程序變得比較復雜,那么其中用到的uniform變量數(shù)量也會上升。通常會在多個shader程序中用到同一個uniform變量。而uniformbufferobject就是一種優(yōu)化uniform變量訪問,以及在不同的shader程序間共享uniform數(shù)據(jù)的方法。寫法首先了解一下uniform塊的寫法。uniformb{//‘b’對應于外部訪問時的名稱vec4v1;//塊中的變量列表boolv2;//…};//訪問成員時使用v1、v2或者uniformb{//‘b’對應于外部訪問時的名稱vec4v1;//塊中的變量列表boolv2;//…}name;//訪問成員時使用name.v1、name.v2注意,shader程序中的數(shù)據(jù)類型有兩種:不透明的和透明的;其中不透明的包括sampler、image和atomiccounter。一個uniform塊中只能包含透明類型的變量。另外,在同一個shader程序里的兩個uniform塊,里面的變量名都不能相同。下面我們以具體例子的編寫過程來說明在如何使用uniform塊,順便了解一下CSharpGL是如何簡化對uniform塊的使用的?;氐巾敳?gototop)Shader我認為用ModernOpenGL渲染,首先要寫shader。我們先看一個簡單的vertexshader。復制代碼#version330coreuniformmat4projectionMatrix;uniformmat4viewMatrix;uniformmat4modelMatrix;invec3vPos;invec3vColor;outvec3fColor;11voidmain(void){99{12gl_Position=projectionMatrix*viewMatrix*modelMatrix*vec4(vPos,1.0);fColor=vColor;}復制代碼Uniforms”我們就把這里面的uniform變量換作塊,如下,只是把原來的uniformUniforms”復制代碼#version330coreuniformUniforms{mat4projectionMatrix;mat4viewMatrix;mat4modelMatrix;};invec3vPos;invec3vColor;outvec3fColor;voidmain(void){gl_Position=projectionMatrix*viewMatrix*modelMatrix*vec4(vPos,1.0);fColor=vColor;}復制代碼而fragmentshader則更簡單:復制代碼#version330coreinvec3fColor;outvec4out_Color;voidmain(void){out_Color=vec4(fColor,1.0f);}復制代碼回到頂部(gototop)準備工作傳送一個自定義的structUniform塊,實際上對應一個在應用程序客戶端的struct類型。對于示例中的‘Uniforms'塊,我們可以定義如下的結構體。為了方便對照,我們也用‘Uniforms'作為struct名,其實你可以用任意你喜歡的名字。復制代碼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;}}復制代碼今后我們就將數(shù)據(jù)準備好后保存到一個Uniforms對象,最終傳送到shader。uniform塊結構這里是重點了。傳送float類型的uniform變量,我們有UniformFloat;傳送vec3類型的uniform變量,我們有UniformVec3。但是uniform塊傳送的是一個個可以任意自定義的不同的結構體(例如上面的structUniforms),因此最好用一個泛型的UniformBlock<T>。復制代碼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復制代碼UniformBlock<T>更新uniform塊的操作比較復雜:它要創(chuàng)建一個uniformbufferobject,并與之綁定;以后它只需更新這個buffer里的數(shù)據(jù),就可以實現(xiàn)對uniform塊的更新。DoSetUniformSetUniform()對于普通的uniform變量,CSharpGL用Renderer.SetUniform(stringvarName,Tvalue)whereT:struct即可(無論是什么類型的uniform都可以處理)。對于Uniform塊,也可以用這個方法!回到頂部(gototop)UniformBlockRenderer有了上述準備,我們就可以使用uniform塊了。創(chuàng)建渲染器按照CSharpGL的傳統(tǒng),下面來創(chuàng)建一個UniformBlockRenderer,負責加載shader、模型數(shù)據(jù)和渲染工作。復制代碼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;}}復制代碼設置uniform塊的值就像普通的uniform變量一樣,我們也在Renderer.DoRender()方法里更新uniform塊。復制代碼protectedoverridevoidDoRender(RenderEventArgsarg){mat4projection=arg.Camera.GetProjectionMatrix();mat4view=arg.Camera.GetViewMatrix();mat4model=this.GetModelMatrix();//設置uniform塊,只需這一行。this.SetUniform("Uniforms",newUniforms(projection,view,model));base.DoRender(arg);}復制代碼完成的效果如圖,能夠正常渲染,說明我們成功地更新了uniform塊里的數(shù)據(jù)。回到頂部(gototop)下載CSharpGL已在GitHub開源,歡迎對OpenGL有興趣的同學力口入(/bitzhuwei/CSharpGL)回到頂部(gototop)總結借助C#的struct與byte□的相互轉換,加上CSharpGL對ModernRendering的封裝,實際上我們不需要調(diào)用glGetUniformIndices、glGetActiveUniformsiv(用于獲取shader中uniform塊里的各個變量的偏移量)這些接口,就可以使用uniform塊了。當shader中寫了一個uniform塊時,你只需在應用程序客戶端也寫一個對應的struct,然后用Renderer.SetUniform(blockName,structObj);一行即可實現(xiàn)對uniform塊數(shù)據(jù)的更新。PS:測試過程中發(fā)現(xiàn)對于vec3結果正常,但是v
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度國際物流貨運出口服務合同
- 2024建設項目合同:單價包干合同版B版
- 衡陽幼兒師范高等??茖W?!兜乩韺W思想史》2023-2024學年第一學期期末試卷
- 2025年統(tǒng)編版2024必修1物理下冊月考試卷
- 提升客戶體驗客戶服務流程全面優(yōu)化策略培訓匯報
- 技術創(chuàng)新驅動的產(chǎn)業(yè)發(fā)展新模式
- 工業(yè)互聯(lián)網(wǎng)平臺的政策支持與產(chǎn)業(yè)發(fā)展
- 小學綜合實踐活動中的團隊協(xié)作與勞動教育
- 二零二五年度高級智能化辦公樓委托管理合同3篇
- 2025年度通信工程環(huán)境保護及生態(tài)補償協(xié)議3篇
- 2023年基礎會計學課后習題及參考答案
- 2024年時事新聞及點評【六篇】
- (部編版)統(tǒng)編版小學語文教材目錄(一至六年級上冊下冊齊全)
- 2024年中國防偽行業(yè)發(fā)展概況、市場全景分析及投資策略研究報告
- 高中英語-名詞性從句教學設計學情分析教材分析課后反思
- 2024-2030年中國Micro LED行業(yè)發(fā)展現(xiàn)狀調(diào)研及市場前景趨勢報告
- 2024年全國職業(yè)院校技能大賽“新型電力系統(tǒng)與維護”賽項考試題庫-中(多選題)
- 除濕機濕度調(diào)節(jié)能力考核試卷
- 朗誦社團活動教案
- 宜賓市翠屏區(qū)2022-2023學年七年級上學期期末地理試題
- 汽車智能座艙交互體驗測試評價規(guī)程
評論
0/150
提交評論