A-Frame .obj model displaying but broken

痞子三分冷 提交于 2019-12-31 05:36:16

问题


Total beginner to a-frame here, have been through the tutorial scenes and am now setting up my first using .obj models.

Using a remote server, feel like that's important information.

I've seen questions about models not showing up but mine is displaying broken and I'm not sure where to start fixing it.

This is how it looks in windows 3D builder:

And this is how it looks in my project (backed on pink plane for contrast):

Here's the html:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Pokemon Stadium</title>
    <link href="css/main.css" rel="stylesheet">
    <script src="https://aframe.io/releases/0.4.0/aframe.min.js"></script>
    <script src="js/main.js"></script>
</head>
<body>


<!-- Scene -->
<a-scene onLoad="">
    <!------------------------------------------------ Assets --------------------------------------------------------->
    <a-assets>
        <a-asset-item id="stadium-obj" src="assets/models/stadium/Pokemon+Stadium.obj"></a-asset-item>
        <a-asset-item id="stadium-mtl" src="assets/models/stadium/Pokemon+Stadium.mtl"></a-asset-item>
        <a-asset-item id="ivy-obj" src="assets/models/ivysaur/Pokemon.obj"></a-asset-item>
        <a-asset-item id="ivy-mtl" src="assets/models/ivysaur/Pokemon.mtl"></a-asset-item>
    </a-assets>


    <!------------------------------------------------- Scene --------------------------------------------------------->
    <!-- Skybox -->
    <a-sky color="#279DF4"></a-sky>


    <!-- Abyss -->
    <a-plane scale="1000 1000" position="0 -10 0" color="#212121" rotation="-90 0 0" material="shader: flat"></a-plane>


    <!-- Stadium -->
    <a-entity obj-model="obj: #stadium-obj; mtl: #stadium-mtl" position="0 0 -30" scale="0.05 0.05 0.05" material="side: double"></a-entity>

    <!-- Bulbasaur -->
    <a-entity obj-model="obj: #ivy-obj; mtl: #ivy-mtl" position="15 10 0" scale="1 1 1" rotation="0 90 0"></a-entity>


    <!-- Camera + cursor -->
    <a-entity camera look-controls position="10 12 0" rotation="-23 -90 0">
        <a-cursor id="cursor"
                  animation__click="property: scale; startEvents: click; from: 0.1 0.1 0.1; to: 1 1 1; dur: 150"
                  animation__fusing="property: fusing; startEvents: fusing; from: 1 1 1; to: 0.1 0.1 0.1; dur: 1500"
                  event-set__1="_event: mouseenter; color: springgreen"
                  event-set__2="_event: mouseleave; color: black"
                  fuse="true"
                  raycaster="objects: .link"></a-cursor>
    </a-entity>
</a-scene>
</body>
</html>

回答1:


You probably have to set the type of side of the material to THREE.DoubleSide. With A-Frame you should be able to change the type using the following DOM attribute on an AEntity: material="side: double".

If this is not the case, you should update your post with a snippet of your scene elements.

EDIT:

As shown in the image, parts of my model are rendered incorrectly. The modelloader in THREEjs reads all meshes in a model and binds them to a grouped object. To fix this, you have to set the side of the material of the meshes to DoubleSided. Luckily in A-Frame, the obj-model component emits an event when the model has loaded successfully, we add a listener for the emitted event model-loaded on the DOM element and append a callback which returns a customevent. The customevent sends a reference to the model group. Query for the AEntity, I've appended an id modelEl to mine.

<script>
  (function(modelEl) {
    if (!window['AFRAME'] && !modelEl) {
      return;
    }

    modelEl.addEventListener('model-loaded', function(evt) {
        var model = evt.detail.model;

      traverse(model);
    });
  })(document.getElementById('stadium'));

  function traverse(node) {
    node.children.forEach(function(child) {
      if (child.children) {
        traverse(child);
      }

      updateMaterial(child['material'], THREE.DoubleSide);
    });
  }

  function updateMaterialSide(material, side) {
    if (!material) {
      return;
    }

    if (material instanceof THREE.Material) {
      material.side = side;
      material.needsUpdate = true
    } else if (material instanceof THREE.MultiMaterial) {
      material.materials.forEach(function(childMaterial) {
        updateMaterial(childMaterial, side);
      });
    }
  }
</script>

After running the above script, my model, and some of the texture loading, has been fixed.

Something to consider would be digging into creating custom components and modify or extend the obj-model component to prevent having to query for every model that may have the same issue. If none of this worked, I believe something might be wrong with your wavefront obj export settings.

EDIT2:

Regarding my comment, here is a result of the fixed obj file in A-Frame:

For convenience sake you can find the MTL and OBJ file here:

obj file

mtl file



来源:https://stackoverflow.com/questions/43892281/a-frame-obj-model-displaying-but-broken

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!