JavaFX 纹理导入的 3D 对象

Posted

技术标签:

【中文标题】JavaFX 纹理导入的 3D 对象【英文标题】:JavaFX texturing an imported 3D object 【发布时间】:2015-06-17 05:22:48 【问题描述】:

所以我尝试使用 InteractiveMesh 的 ColModelImporterJFX 将 collada .dae 文件导入 Javafx 场景。

我已经从 jar 工作中导入模型并将其渲染到场景中,但是没有任何关于将 PhongMaterials 添加到返回的 MeshViews 的有用文档。

ColModelImporter station = new ColModelImporter();
station.setResourceBaseUrl(ClassLoader.getSystemResource("models/Station"));
station.read(ClassLoader.getSystemResource("models/station.dae"));

返回的节点数组中唯一的节点似乎是一个包含所有节点的组。

Group model = (Group)(station.getImport()[0]);
root.getChildren().addAll(model);

我所知道的是,getNamedMaterials() 方法会返回一个材质图,但不知道如何实际应用它们。

Map<String, PhongMaterial> tex = station.getNamedMaterials();

虽然我确实找到了一种将材质分别应用到每个 MeshView 的方法(组模型包含另一个包含所有 MeshView 节点的组),但它对我一点帮助都没有,因为我无法知道哪种材质使用哪个 MeshView。

for (int i = 0; i < ((Group) model.getChildren().get(0)).getChildren().size(); i++) 
        ((MeshView) ((Group) model.getChildren().get(0)).getChildren().get(i)).setMaterial(somematerial);

我确实使用 ModelBrowserJFX 试用了我的 3D 模型,它可以正常工作。

我们将不胜感激。

【问题讨论】:

你试过不应用材料吗?不同的网格视图应该已经应用了它们的材料。这就是为什么您使用模型浏览器可以很好地看到它们的原因。 是的,全是白色的:/ 也许是因为光线。你有应用一些灯吗?我刚刚在 InteractiveMesh 上尝试过 collada 示例,我不必添加材质。 这确实让我想到纹理的位置可能不正确......我怀疑 getResourceBaseUrl 做了很多。 是的,我有灯光,还有很多在场景中具有纹理(基元)的对象,这样肯定可以工作 【参考方案1】:

PhongMaterials 已应用,但它们的 URL 不正确(至少我的情况是这样)。如果您使用 windowsTIFF 文件,可能会发生这样的纹理您将无法通过 JavaFX Image 上传。

这段代码会告诉你问题出在哪里。

URL url = getClass().getResource("/models/hst.3ds");
ModelImporter modelImporter = new TdsModelImporter();
modelImporter.read(url);
Node[] nodes = (Node[]) modelImporter.getImport();
Map<String, PhongMaterial> mapTexs = modelImporter.getNamedMaterials();
Iterator<String> it = mapTexs.keySet().iterator();
while (it.hasNext()) 
    PhongMaterial material = mapTexs.get(it.next());
    if(Objects.nonNull(material.getBumpMap())) 
       printErrors(material.getBumpMap());
    
    if(Objects.nonNull(material.getDiffuseMap())) 
       printErrors(material.getDiffuseMap());
    
    if(Objects.nonNull(material.getSpecularMap())) 
       printErrors(material.getSpecularMap());
    


private void printErrors(Image image) 
    System.out.println(image.getException().getMessage());

方法一

您需要使用正确的 URL 更改图像,然后设置单独的 PhongMaterial。如您所见,我在名为纹理的 src 中创建了文件夹,并在那里添加了所有纹理。这种方法有一个很大的缺点。变量 key 的值必须与纹理文件的名称相同。

URL url = getClass().getResource("/models/hst.3ds");
ModelImporter modelImporter = new TdsModelImporter();
modelImporter.read(url);
Node[] nodes = (Node[]) modelImporter.getImport();
Map<String, PhongMaterial> mapTexs = modelImporter.getNamedMaterials();
Iterator<String> it = mapTexs.keySet().iterator();
while (it.hasNext()) 
      String key = it.next();
      mapTexs.get(key).setDiffuseMap(new Image("/textures/" + key + ".bmp"));

方法 2

您在那里添加纹理,模型位于您的项目中。因此,就我而言,它们与我的模型具有相同的位置,这意味着我会将它们放入文件夹 models。这种方法比上一种方法简单得多。

二手模型不属于我所有。由DigitalSpace Corporation制作。

【讨论】:

以上是关于JavaFX 纹理导入的 3D 对象的主要内容,如果未能解决你的问题,请参考以下文章

纹理在openGL中使用2D纹理映射3D对象

3d一些术语

3D 模型和纹理创建

初步了解3D纹理和材质

如何在 Unity 中从 3D 对象中获取 2D 视图/纹理

我的渲染技术进阶之旅解决显示3D模型时因为使用stb_image库加载纹理时未翻转y轴导致模型纹理映射出错的问题