GLSL中的顶点着色器属性映射 [英] Vertex shader attribute mapping in GLSL

查看:271
本文介绍了GLSL中的顶点着色器属性映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用GLSL着色器编码小型渲染引擎:

I'm coding a small rendering engine with GLSL shaders:

每个网格(孔,子网格)都有许多顶点流(例如位置,法线,纹理,切线等)成一个大的VBO和一个MaterialID.

Each Mesh (well, submesh) has a number of vertex streams (eg. position,normal,texture,tangent,etc) into one big VBO and a MaterialID.

每种材料都有一组纹理和属性(例如镜面颜色,漫反射颜色,颜色纹理,法线贴图等)

Each Material has a set of textures and properties (eg. specular-color, diffuse-color, color-texture, normal-map,etc)

然后我有一个GLSL着色器,它具有制服和属性.假设:

Then I have a GLSL shader, with it's uniforms and attributes. Let's say:

uniform vec3 DiffuseColor;
uniform sampler2D NormalMapTexture;
attribute vec3 Position;
attribute vec2 TexCoord;

我有点想尝试为GLSL着色器设计一种方法来定义属性和统一体的流映射(语义),然后将顶点流绑定到适当的属性.

I'm a little bit stuck in trying to design a way for the GLSL shader to define the stream mappings (semantics) for the attributes and uniforms, and then bind the vertex streams to the appropriate attributes.

对网格的描述如下:将位置流放置在属性"Position"中,将tex坐标放置在"TexCoord"中.还将材质的漫反射颜色放置在"DiffuseColor"中,将材质的第二个纹理放置在"NormalMapTexture"中"

Something in the lines of saying to the mesh :"put your position stream in attribute "Position" and your tex coordinates in "TexCoord". Also put your material's diffuse color in "DiffuseColor" and your material's second texture in "NormalMapTexture"

此刻,我正在使用属性的硬编码名称(即,顶点pos始终是"Position"等),并检查每个统一名称和属性名称,以了解着色器将其用于什么目的.

At the moment I am using hard-coded names for the attributes (ie. vertex pos is always "Position" ,etc) and checking each uniform and attribute name to understand what the shader is using it for.

我想我正在寻找一种创建顶点声明"的方法,但也要包括制服和纹理.

I guess I'm looking for some way of creating a "vertex declaration", but including uniforms and textures too.

所以我只是想知道人们在大型渲染引擎中如何做到这一点.

So I'm just wondering how people do this in large-scale rendering engines.

建议方法概述:

1.属性/统一语义由变量名称给出 (我现在在做什么) 为每个可能的属性使用预定义的名称.GLSL绑定器将查询每个属性的名称,并根据变量的名称链接顶点数组:

1. Attribute/Uniform semantic is given by the name of the variable (what I'm doing now) Using pre-defined names for each possible attribute.The GLSL binder will query the name for each attribute and link the vertex array based on the name of the variable:

//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极为相似,但是除非我误解了,否则这意味着绑定所有可用的顶点数据,即使着色器不使用它也是如此)

GLSL binder will always bind the vertex arrays to the same locations.It is up to the shader to use the the appropriate names to match. (This seems awfully similar to method 1, but unless I misunderstood, this implies binding ALL available vertex data, even if the shader does not consume it)

.. when linking the program...
glBindAttribLocation(prog, 0, "mg_Position");
glBindAttribLocation(prog, 1, "mg_Color");
glBindAttribLocation(prog, 2, "mg_Normal");

3.材质,引擎全局变量,渲染器和网格的可用属性字典

维护由活动材质,引擎全局变量,当前渲染器和当前场景节点发布的可用属性的列表.

Maintain list of availlable attributes published by the active Material, the Engine globals, the current Renderer and the current Scene Node.

例如:

 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绑定器将遍历attribs并绑定到字典中找到的那个(或不是?):

When binding the vertex data to the shader, the GLSL binder will loop over the attribs and bind to the one found (or not? ) in the dictionary:

 for (int index=0;index<allAttribs;index++)
    {
       glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);      
      semantics[index] = Mesh->GetAttributeSemantics(name);
}

和制服一样,也只查询活动的Material和Globals.

and the same with uniforms, only query active Material and globals aswell.

推荐答案

属性:

您的网格具有许多数据流.对于每个流,您都可以保留以下信息:(名称,类型,数据).

Your mesh has a number of data streams. For each stream you can keep the following info: (name, type, data).

通过链接,您可以查询GLSL程序以获取活动属性,并为该程序形成属性字典.这里的每个元素就是( name,type ).

Upon linking, you can query the GLSL program for active attributes and form an attribute dictionary for this program. Each element here is just (name, type).

当使用指定的GLSL程序绘制网格时,将浏览程序属性字典并绑定相应的网格流(或在不一致的情况下报告错误).

When you draw a mesh with a specified GLSL program, you go through programs attribute dictionary and bind the corresponding mesh streams (or reporting an error in case of inconsistency).

制服:

让着色器参数字典成为(名称,类型,数据链接)的集合.通常,您可以使用以下词典:

Let the shader parameter dictionary be the set of (name, type, data link). Typically, you can have the following dictionaries:

  • 材料(漫射,镜面反射,光泽等)-取材
  • 引擎(相机,模型,灯光,计时器等)-取自引擎单例(全局)
  • 渲染(与着色器创建者相关的自定义参数:SSAO半径,模糊量等)-专门由着色器创建者类(渲染)提供

链接后,将为GLSL程序提供一组参数字典,以便使用以下元素格式填充其自身的字典:(<位置>,类型,数据链接).通过查询活动制服列表并将匹配的( name,type )对与字典中的一对配对来完成此填充.

After linking, the GLSL program is given a set of parameter dictionaries in order to populate it's own dictionary with the following element format: (location, type, data link). This population is done by querying the list of active uniforms and matching (name, type) pair with the one in dictionaries.

结论: 此方法允许传递任何自定义顶点属性和着色器制服,而无需在引擎中使用硬编码的名称/语义.基本上,只有加载器和渲染器知道特定的语义:

Conclusion: This method allows for any custom vertex attributes and shader uniforms to be passed, without hard-coded names/semantics in the engine. Basically only the loader and render know about particular semantics:

  • 加载程序会填充网格数据流声明和材料字典.
  • 渲染器使用知道名称的着色器,提供其他参数,并选择适当的网格物体来绘制.

这篇关于GLSL中的顶点着色器属性映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆