




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1010使用uniform块来优化对uniform变量的读写Uniform块如果shader程序变得比较复杂,那么其中用到的uniform变量数量也会上升。通常会在多个shader程序中用到同一个uniform变量。而uniformbufferobject就是一种优化uniform变量访问,以及在不同的shader程序间共享uniform数据的方法。写法首先了解一下uniform块的写法。uniformb{//‘b’对应于外部访问时的名称vec4v1;//块中的变量列表boolv2;//…};//访问成员时使用v1、v2或者uniformb{//‘b’对应于外部访问时的名称vec4v1;//块中的变量列表boolv2;//…}name;//访问成员时使用name.v1、name.v2注意,shader程序中的数据类型有两种:不透明的和透明的;其中不透明的包括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;}}复制代码今后我们就将数据准备好后保存到一个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块的操作比较复杂:它要创建一个uniformbufferobject,并与之绑定;以后它只需更新这个buffer里的数据,就可以实现对uniform块的更新。DoSetUniformSetUniform()对于普通的uniform变量,CSharpGL用Renderer.SetUniform(stringvarName,Tvalue)whereT:struct即可(无论是什么类型的uniform都可以处理)。对于Uniform块,也可以用这个方法!回到顶部(gototop)UniformBlockRenderer有了上述准备,我们就可以使用uniform块了。创建渲染器按照CSharpGL的传统,下面来创建一个UniformBlockRenderer,负责加载shader、模型数据和渲染工作。复制代码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块里的数据。回到顶部(gototop)下载CSharpGL已在GitHub开源,欢迎对OpenGL有兴趣的同学力口入(/bitzhuwei/CSharpGL)回到顶部(gototop)总结借助C#的struct与byte□的相互转换,加上CSharpGL对ModernRendering的封装,实际上我们不需要调用glGetUniformIndices、glGetActiveUniformsiv(用于获取shader中uniform块里的各个变量的偏移量)这些接口,就可以使用uniform块了。当shader中写了一个uniform块时,你只需在应用程序客户端也写一个对应的struct,然后用Renderer.SetUniform(blockName,structObj);一行即可实现对uniform块数据的更新。PS:测试过程中发现对于vec3结果正常,但是v
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 制药生产设备管理制度
- 小学餐饮浪费管理制度
- DB3410T 51-2025 工程建设项目全流程一码管地技术规范
- 别墅转让方案(3篇)
- 消防窗户整改方案(3篇)
- 消防孙峰课件
- 厂区立柱保护方案(3篇)
- 村庄彩绘方案(3篇)
- 小学课程规划方案(3篇)
- 采石场承包合同矿产资源保护与综合利用协议
- 物业管理规范试题及答案
- 美国地理考试题及答案
- 2025-2030中国食品市场调研及重点企业投资评估规划分析研究报告
- 家庭电梯保养合同协议
- 2025年上半年度苏州城际铁路限公司管理岗位公开招聘易考易错模拟试题(共500题)试卷后附参考答案
- 2025年高中化学学业水平考试知识点归纳总结(复习必背)
- 2025中国经济破浪前⾏ 稳中求进-安永
- 2025年贵州西南能矿建设工程有限公司招聘笔试参考题库含答案解析
- 超声引导介入术-深度研究
- 2025年金融科技发展趋势洞见报告-北京金融信息化研究所
- 2024江苏苏州高新现代服务业招商中心有限公司招聘10人笔试参考题库附带答案详解
评论
0/150
提交评论