如何告诉 frag-shader 在外部生成的 3D 文件的每个顶点使用哪个纹理(许多先前加载的纹理)?
我正在尝试找出将纹理 3D 模型加载到 webGL 应用程序中的最佳方法,但遇到了一些问题。我的 3D 模型有超过 1 个纹理,我不知道如何告诉着色器每个顶点使用哪个纹理,因为此信息似乎没有包含在我迄今为止查看的 3D 文件中。 我举个例子:我在 Blender 中建模了一把带有皮革座椅/垫子的木椅。我应该导出哪种格式的椅子才能轻松高效地提取: - 顶点位置; - 定义哪个顶点属于每个面的面/索引信息。 - 紫外线坐标; - 法线 - 纹理文件名称/位置。 - 每个顶点使用哪个纹理。
我假设一旦我的 JS 中有了 vertex-textureID 对,我就可以将它作为属性(基于每个顶点)传递给着色器,让它知道该特定顶点使用哪个纹理(使用 drawElements 一次性绘制它) )但我不知道如何开始获取该信息。
到目前为止,我在网上找到的所有文章、指南和教程都仅加载具有 1 个纹理的模型。我还注意到 Three.js 似乎已经解决了这个问题,但我有点想让它直接在 webGL 上工作,然后再进入这些库之一(例如 Three.js、glge、scene.sj、spiderGL 等) 。
任何帮助、链接或建议将不胜感激。
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.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(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.