我正在编写一个带有GLSL着色器的小型渲染引擎:
每个网格(或子网格)都有多个顶点流(例如位置、法线、纹理、切线等),它们被合并到一个大的VBO中,并带有一个MaterialID。
每种材质都有一组纹理和属性(例如高光颜色、漫反射颜色、颜色纹理、法线贴图等)
然后我有一个GLSL着色器,其中包含它的uniform变量和attribute变量。假设如下:
uniform vec3 DiffuseColor;
uniform sampler2D NormalMapTexture;
attribute vec3 Position;
attribute vec2 TexCoord;
我在尝试设计GLSL着色器定义属性和Uniform的流映射(语义),并将顶点流绑定到相应的属性。比如说对于网格,可以让其把位置流放在"Position"属性中,把纹理坐标放在"TexCoord"属性中,把材质漫反射颜色放在"DiffuseColor"属性中,把材质的第二个纹理放在"NormalMapTexture"属性中。
目前我正在使用硬编码属性名称(例如顶点位置总是"Position"),并检查每个Uniform和属性名称来了解着色器是如何使用它的。
我想找一种创建"顶点声明"的方法,其中包括Uniform和纹理。
因此,我想知道大型渲染引擎中人们是如何解决这个问题的。
编辑:
建议的方法概述:
1. 通过变量的名称确定属性/Uniform的语义 (我的当前做法) 为每个可能的属性使用预定义的名称。GLSL绑定程序将查询每个属性的名称,并根据变量名称链接顶点数组:
//global static variable
semantics (name,normalize,offset) = {"Position",false,0} {"Normal",true,1},{"TextureUV,false,2}
...when linking
for (int index=0;index<allAttribs;index++)
{
glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);
semantics[index]= GetSemanticsFromGlobalHardCodedList(name);
}
... when binding vertex arrays for render
for (int index=0;index<allAttribs;index++)
{
glVertexAttribPointer(index,size[index],type[index],semantics[index]->normalized,bufferStride,semantics[index]->offset);
}
2. 每个语义预定义的位置
GLSL绑定器将始终将顶点数组绑定到相同的位置。由着色器使用适当的名称进行匹配。(这似乎与方法1非常相似,但除非我误解了,否则这意味着绑定所有可用的顶点数据,即使着色器不使用它)。
.. when linking the program...
glBindAttribLocation(prog, 0, "mg_Position");
glBindAttribLocation(prog, 1, "mg_Color");
glBindAttribLocation(prog, 2, "mg_Normal");
3. Material、Engine全局变量、渲染器和网格可用属性的字典
维护当前材质、引擎全局变量、当前渲染器和场景节点发布的可用属性列表。
例如:
Material has (uniformName,value) = {"ambientColor", (1.0,1.0,1.0)}, {"diffuseColor",(0.2,0.2,0.2)}
Mesh has (attributeName,offset) = {"Position",0,},{"Normals",1},{"BumpBlendUV",2}
然后在着色器中:
uniform vec3 ambientColor,diffuseColo;
attribute vec3 Position;
将顶点数据绑定到着色器时,GLSL绑定器将循环遍历属性并绑定到在字典中找到的一个(或没有找到?):
for (int index=0;index<allAttribs;index++)
{
glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);
semantics[index] = Mesh->GetAttributeSemantics(name);
}
同样适用于uniform变量,只查询活动材质和全局变量。