问题
I'm trying to figure out the best way to load a textured 3D model into my webGL application but I'm having some trouble with it. My 3D models have more than 1 texture and I don't know how to tell the shader which texture to use per vertex as this info doesn't seem to be included into the 3D files I looked into so far. I'll give an example: I have modeled a wooden chair with a leather seat/cushion in Blender. Which format should I export the chair to make it easy and efficient to extract: - the vertice positions; - the faces/index info defining which vertex belongs to each face. - the UV coords; - the normals - the texture files name/location. - which texture to use per vertex.
I assume that once I have the vertex-textureID pair in my JS, I could pass it to the shader as attribute (per-vertex based) letting it know which texture to use for that specific vertex (using drawElements to draw it all at once) but I don't know how to get my hands on that info to begin with.
All the articles, howtos and tutorials I found on the web so far load models with 1 texture only. I also noticed that three.js seems to have solved this problem already but I kind of wanted to get it working directly on webGL before moving into one of these libraries (such as three.js, glge, scene.sj, spiderGL, etc).
Any help, links or suggestions will be most appreciated.
回答1:
Sounds like you've got two problems here, one of which we can help with and one which requires more information.
For one, most of the time you won't have texture information listed per-vertex, as it's more natural to list it per-face. You'll still have to pass it to a shader per-vertex, so there's likely to be a little bit of pre-processing on your part, but it shouldn't be too bad. How you get that information out of your file entirely depends on the format you are using for it, however, which you haven't specified.
As for rendering multiple textures with a file, there's a couple of ways of going about it. You can bind all the textures you need to a sampler array in the shader and then index it with a vertex attribute, which you were hinting at earlier. That's a good way to cut down on the number of draw calls, but it's a bit of an extreme optimization and I doubt that you'll benefit much from it.
A more common practice is to do a single draw call for each material (material == texture in your case). So if you have a chair with a wooden frame and a leather seat cushion as you described you would bind the wood texture, render the entire frame, then bind the seat cushion texture and render the cushion separately. This give you the opportunity further down the line to use different shaders for each material type as well, so you could crank up the specularity on the leather parts while leaving the wood nice and matte. It may sound expensive to do several draw calls per-object, but in most cases it's not a big problem unless you are dealing with some really complex scenes.
来源:https://stackoverflow.com/questions/9257056/how-do-i-tell-frag-shader-which-texture-of-many-previously-loaded-textures-to