estoy codificación de un pequeño motor de renderizado con shaders GLSL:Vertex asignación de atributos shader en GLSL
cada malla (bueno, submesh) tiene un número de corrientes de vértice (posición por ejemplo, normal, textura, tangente, etc.) en un gran VBO y un MaterialID.
Cada material tiene un conjunto de texturas y propiedades (por ejemplo. Especular de color, difusa de color, el color-textura, lo normal en mapas, etc.)
entonces tengo un sombreado GLSL, con sus uniformes y atributos . Digamos:
uniform vec3 DiffuseColor;
uniform sampler2D NormalMapTexture;
attribute vec3 Position;
attribute vec2 TexCoord;
estoy un poco atascado en el intento de diseñar un camino para el sombreado GLSL para definir las asignaciones de corriente (semántica) para los atributos y uniformes, y luego se unen el vértice transmite a la adecuada atributos.
Algo en las líneas de decir a la malla: "coloque el flujo de posición en el atributo" Posición "y sus coordenadas de tex en" TexCoord ". También coloque el color difuso en" DiffuseColor "y la segunda textura de su material" NormalMapTexture "
Por el momento estoy usando nombres codificados para los atributos (es decir, vertex pos siempre es" Posición ", etc.) y comprobando cada uniforme y nombre de atributo para entender para qué lo usa el sombreador.
Supongo que estoy buscando una forma de crear una "declaración de vértices", pero también incluye uniformes y texturas.
Así que me pregunto cómo la gente hace esto en los motores de renderizado a gran escala.
Editar:
Recapitulación de los métodos sugeridos:
1. Atributo/semántica uniforme está dada por el nombre de la variable (lo que estoy haciendo ahora) El uso de nombres predefinidos para cada posible aglutinante attribute.The GLSL se consulta el nombre de cada atributo y vincular la matriz vértice basado en el nombre de la 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. Ubicaciones predefinidas para cada semántica
La carpeta GLSL siempre enlazará las matrices de vértices a las mismas ubicaciones. El sombreador tiene la opción de utilizar los nombres adecuados para que coincidan. (Esto parece muy similar al método 1, pero a menos que no he entendido bien, esto implica la unión TODOS los datos de vértices disponibles, incluso si el shader no lo consumen)
.. when linking the program...
glBindAttribLocation(prog, 0, "mg_Position");
glBindAttribLocation(prog, 1, "mg_Color");
glBindAttribLocation(prog, 2, "mg_Normal");
3. Diccionario de atributos disponibles a partir de materiales de variables globales del motor , Renderer y Mesh
Mantiene la lista de atributos disponibles publicados por el Material activo, el Motor global, el Renderer actual y el Nodo de escena actual.
por ejemplo:
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}
entonces en shader: no
uniform vec3 ambientColor,diffuseColo;
attribute vec3 Position;
Cuando la unión de los datos de vértice para el shader, el aglutinante GLSL se bucle sobre los attribs y se unen a la que se encuentra (o ?) en el diccionario:
for (int index=0;index<allAttribs;index++)
{
glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);
semantics[index] = Mesh->GetAttributeSemantics(name);
}
y lo mismo con uniformes, solo consulta material activo y también globales.
Creo que sus 3 puntos son más o menos lo mismo, según sus necesidades de configuración, desde "mantenerlo ingenuamente simple" (2) hasta "controlado por datos" (3). Hablando de los atributos de los vértices, en realidad comencé con (2) hace algunos años, pensando que iría a (1) o (3) dependiendo de mis necesidades. Nunca tuve la necesidad de cambiar todavía. No digo que las otras opciones sean malas, todo depende de tus necesidades. Como en realidad estoy en el proceso de eliminar el código sobre-diseñado en nuestro motor, quizás estoy predispuesto;) – rotoglup
Tiendo a preferir (3) atm, porque parece ser el más fácil de extender en el futuro. ** Me gustaría ** comenzar de manera simple con (2); lo que no entiendo en (2): si tienes una VBO con 4-5 secuencias de atributos, ¿cómo sabes qué secuencias enlazar dependiendo del sombreador? ? ¿simplemente los vincula a todos? – Radu094