You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Coin3d/OpenInventor中为SoIndexedFaceSet各面设置不同纹理的咨询

Coin3d/OpenInventor 为SoIndexedFaceSet每个面设置不同纹理的问题与解决

我用SoIndexedFaceSet创建了6个面,尝试用SoTexture3给每个面贴不同图片但失败了,求可行方案并排查代码问题。

原代码

SoSeparator* root = new SoSeparator;
root->ref();

SoTransform* pTransfrom = new SoTransform;
pTransfrom->translation.setValue(0, 0, 0);
root->addChild(pTransfrom);

SoMaterialBinding* faceBind = new SoMaterialBinding;
faceBind->value = SoMaterialBinding::PER_PART;
root->addChild(faceBind);

SoTexture3* texture = new SoTexture3;
texture->filenames.set1Value(0, SbString("D:/wrapper/TCom_Wall_Stone3_2x2_1K_albedo.tif"));
texture->filenames.set1Value(1, SbString("D:/wrapper/Com_Wall_Stone3_2x2_1K_ao.tif"));
texture->filenames.set1Value(2, SbString("D:/wrapper/TCom_Wall_Stone3_2x2_1K_height.tif"));
texture->filenames.set1Value(3, SbString("D:/wrapper/TCom_Wall_Stone3_2x2_1K_normal.tif"));
texture->filenames.set1Value(4, SbString("D:/wrapper/4.jpg"));
texture->filenames.set1Value(5, SbString("D:/wrapper/5.jpg"));
root->addChild(texture);

SoCoordinate3* coordinates = new SoCoordinate3;
//front
coordinates->point.set1Value(0, 0, 0, 0);
coordinates->point.set1Value(1, step, 0, 0);
coordinates->point.set1Value(2, step, 0, step);
coordinates->point.set1Value(3, 0, 0, step);
//back
coordinates->point.set1Value(4, step, step, 0);
coordinates->point.set1Value(5, 0, step, 0);
coordinates->point.set1Value(6, 0, step, step);
coordinates->point.set1Value(7, step, step, step);

root->addChild(coordinates);

SoIndexedFaceSet* faceSet = new SoIndexedFaceSet;
//front
faceSet->coordIndex.set1Value(0, 0);
faceSet->coordIndex.set1Value(1, 1);
faceSet->coordIndex.set1Value(2, 2);
faceSet->coordIndex.set1Value(3, 3);
faceSet->coordIndex.set1Value(4, -1);
//back
faceSet->coordIndex.set1Value(5, 4);
faceSet->coordIndex.set1Value(6, 5);
faceSet->coordIndex.set1Value(7, 6);
faceSet->coordIndex.set1Value(8, 7);
faceSet->coordIndex.set1Value(9, -1);
//left
faceSet->coordIndex.set1Value(10, 5);
faceSet->coordIndex.set1Value(11, 0);
faceSet->coordIndex.set1Value(12, 3);
faceSet->coordIndex.set1Value(13, 6);
faceSet->coordIndex.set1Value(14, -1);
//right
faceSet->coordIndex.set1Value(15, 1);
faceSet->coordIndex.set1Value(16, 4);
faceSet->coordIndex.set1Value(17, 7);
faceSet->coordIndex.set1Value(18, 2);
faceSet->coordIndex.set1Value(19, -1);
//top
faceSet->coordIndex.set1Value(20, 3);
faceSet->coordIndex.set1Value(21, 2);
faceSet->coordIndex.set1Value(22, 7);
faceSet->coordIndex.set1Value(23, 6);
faceSet->coordIndex.set1Value(24, -1);
//bottom
faceSet->coordIndex.set1Value(25, 5);
faceSet->coordIndex.set1Value(26, 4);
faceSet->coordIndex.set1Value(27, 1);
faceSet->coordIndex.set1Value(28, 0);
faceSet->coordIndex.set1Value(29, -1);
root->addChild(faceSet);

setSceneGraph(root);

代码错误分析

  • SoTexture3用错组件:SoTexture3是用于3D体纹理的,不是给多个面分配不同2D纹理的工具,应该用SoTexture2加载多张2D图片。
  • 绑定节点错误:SoMaterialBinding是给材质属性用的,纹理绑定需要用SoTextureCoordinateBinding,并设置正确的绑定模式。
  • 缺少纹理索引指定:没有通过SoTextureIndex节点告诉每个面应该使用哪一张纹理。

修正方案

  1. 替换SoTexture3为SoTexture2,保留多纹理文件名设置。
  2. 添加SoTextureCoordinateBinding节点,设置绑定模式为PER_PART(对应每个面用-1分隔的结构)。
  3. 添加SoTextureIndex节点,为每个面指定对应的纹理索引(0到5,对应加载的6张图)。
  4. 移除无关的SoMaterialBinding节点(如果不需要多材质)。

修正后的代码

SoSeparator* root = new SoSeparator;
root->ref();

SoTransform* pTransfrom = new SoTransform;
pTransfrom->translation.setValue(0, 0, 0);
root->addChild(pTransfrom);

// 纹理绑定:指定每个part(面)使用单独纹理
SoTextureCoordinateBinding* texBind = new SoTextureCoordinateBinding;
texBind->value = SoTextureCoordinateBinding::PER_PART;
root->addChild(texBind);

// 用SoTexture2加载多张2D纹理
SoTexture2* texture = new SoTexture2;
texture->filenames.set1Value(0, SbString("D:/wrapper/TCom_Wall_Stone3_2x2_1K_albedo.tif"));
texture->filenames.set1Value(1, SbString("D:/wrapper/Com_Wall_Stone3_2x2_1K_ao.tif"));
texture->filenames.set1Value(2, SbString("D:/wrapper/TCom_Wall_Stone3_2x2_1K_height.tif"));
texture->filenames.set1Value(3, SbString("D:/wrapper/TCom_Wall_Stone3_2x2_1K_normal.tif"));
texture->filenames.set1Value(4, SbString("D:/wrapper/4.jpg"));
texture->filenames.set1Value(5, SbString("D:/wrapper/5.jpg"));
// 设置纹理混合模式为MODULATE,确保正确渲染
texture->model = SoTexture2::MODULATE;
root->addChild(texture);

// 为每个面指定纹理索引:6个面对应6个索引
SoTextureIndex* texIndex = new SoTextureIndex;
texIndex->index.set1Value(0, 0); // 正面用第0张
texIndex->index.set1Value(1, 1); // 背面用第1张
texIndex->index.set1Value(2, 2); // 左面用第2张
texIndex->index.set1Value(3, 3); // 右面用第3张
texIndex->index.set1Value(4, 4); // 顶面用第4张
texIndex->index.set1Value(5, 5); // 底面用第5张
root->addChild(texIndex);

SoCoordinate3* coordinates = new SoCoordinate3;
//front
coordinates->point.set1Value(0, 0, 0, 0);
coordinates->point.set1Value(1, step, 0, 0);
coordinates->point.set1Value(2, step, 0, step);
coordinates->point.set1Value(3, 0, 0, step);
//back
coordinates->point.set1Value(4, step, step, 0);
coordinates->point.set1Value(5, 0, step, 0);
coordinates->point.set1Value(6, 0, step, step);
coordinates->point.set1Value(7, step, step, step);

root->addChild(coordinates);

SoIndexedFaceSet* faceSet = new SoIndexedFaceSet;
//front
faceSet->coordIndex.set1Value(0, 0);
faceSet->coordIndex.set1Value(1, 1);
faceSet->coordIndex.set1Value(2, 2);
faceSet->coordIndex.set1Value(3, 3);
faceSet->coordIndex.set1Value(4, -1);
//back
faceSet->coordIndex.set1Value(5, 4);
faceSet->coordIndex.set1Value(6, 5);
faceSet->coordIndex.set1Value(7, 6);
faceSet->coordIndex.set1Value(8, 7);
faceSet->coordIndex.set1Value(9, -1);
//left
faceSet->coordIndex.set1Value(10, 5);
faceSet->coordIndex.set1Value(11, 0);
faceSet->coordIndex.set1Value(12, 3);
faceSet->coordIndex.set1Value(13, 6);
faceSet->coordIndex.set1Value(14, -1);
//right
faceSet->coordIndex.set1Value(15, 1);
faceSet->coordIndex.set1Value(16, 4);
faceSet->coordIndex.set1Value(17, 7);
faceSet->coordIndex.set1Value(18, 2);
faceSet->coordIndex.set1Value(19, -1);
//top
faceSet->coordIndex.set1Value(20, 3);
faceSet->coordIndex.set1Value(21, 2);
faceSet->coordIndex.set1Value(22, 7);
faceSet->coordIndex.set1Value(23, 6);
faceSet->coordIndex.set1Value(24, -1);
//bottom
faceSet->coordIndex.set1Value(25, 5);
faceSet->coordIndex.set1Value(26, 4);
faceSet->coordIndex.set1Value(27, 1);
faceSet->coordIndex.set1Value(28, 0);
faceSet->coordIndex.set1Value(29, -1);
root->addChild(faceSet);

setSceneGraph(root);

额外说明

  • 如果纹理仍未正确显示,检查图片路径是否正确、文件是否损坏,Coin3d支持tif、jpg等常见格式。
  • 也可以选择拆分方案:将每个面做成独立的SoIndexedFaceSet,每个面单独添加SoTexture2节点,这种方式更直观,但节点数量会增加。

内容的提问来源于stack exchange,提问作者Z.Ju

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:44:57