Note that there are some explanatory texts on larger screens.

plurals
  1. POVertex shader attribute mapping in GLSL
    text
    copied!<p>I'm coding a small rendering engine with GLSL shaders:</p> <p>Each Mesh (well, submesh) has a number of vertex streams (eg. position,normal,texture,tangent,etc) into one big VBO and a MaterialID.</p> <p>Each Material has a set of textures and properties (eg. specular-color, diffuse-color, color-texture, normal-map,etc)</p> <p>Then I have a GLSL shader, with it's uniforms and attributes. Let's say:</p> <pre><code>uniform vec3 DiffuseColor; uniform sampler2D NormalMapTexture; attribute vec3 Position; attribute vec2 TexCoord; </code></pre> <p>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.</p> <p>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"</p> <p>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.</p> <p>I guess I'm looking for some way of creating a "vertex declaration", but including uniforms and textures too. </p> <p>So I'm just wondering how people do this in large-scale rendering engines.</p> <p>Edit:</p> <p>Recap of suggested methods:</p> <p><strong>1. Attribute/Uniform semantic is given by the name of the variable</strong> (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:</p> <pre><code>//global static variable semantics (name,normalize,offset) = {"Position",false,0} {"Normal",true,1},{"TextureUV,false,2} ...when linking for (int index=0;index&lt;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&lt;allAttribs;index++) { glVertexAttribPointer(index,size[index],type[index],semantics[index]-&gt;normalized,bufferStride,semantics[index]-&gt;offset); } </code></pre> <p><strong>2. Predefined locations for each semantic</strong></p> <p>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)</p> <pre><code>.. when linking the program... glBindAttribLocation(prog, 0, "mg_Position"); glBindAttribLocation(prog, 1, "mg_Color"); glBindAttribLocation(prog, 2, "mg_Normal"); </code></pre> <p><strong>3. Dictionary of available attributes from Material, Engine globals, Renderer and Mesh</strong></p> <p>Maintain list of availlable attributes published by the active Material, the Engine globals, the current Renderer and the current Scene Node. </p> <p>eg:</p> <pre><code> 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} </code></pre> <p>then in shader:</p> <pre><code> uniform vec3 ambientColor,diffuseColo; attribute vec3 Position; </code></pre> <p>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:</p> <pre><code> for (int index=0;index&lt;allAttribs;index++) { glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name); semantics[index] = Mesh-&gt;GetAttributeSemantics(name); } </code></pre> <p>and the same with uniforms, only query active Material and globals aswell.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload