【问题标题】:THREE.js fails to apply Gradient colors to Imported OBJ fileTHREE.js 无法将渐变颜色应用于导入的 OBJ 文件
【发布时间】:2021-05-16 17:52:24
【问题描述】:

我正在尝试从位于此处的名为 "WaltHead.obj"THREE.js GIT 加载示例文件并为其着色:

https://github.com/mrdoob/three.js/blob/dev/examples/models/obj/walt/WaltHead.obj

我可以将它加载到我的项目中,但是当我尝试使用已经对我使用 GLTF/GLB 模型 100% 有效的代码使用渐变颜色绘制它时 - 它不适用于这个“.obj "文件。

我做了一个小提琴来让生活更轻松 - 但由于某种原因,模型没有加载到小提琴文件中:

https://jsfiddle.net/gilomer88/tp2hkxne/27/

希望有人可以修复它以便加载?

不管怎样,就像我说的那样,我正在尝试用渐变对其进行着色 - 但它显示为完全黑色。 代码在小提琴中,也在这里:

const loader = new OBJLoader();

loader.load( "https://github.com/mrdoob/three.js/blob/dev/examples/models/obj/walt/WaltHead.obj", function ( theScene ) {
       console.log("  =>'theScene' = ", theScene);

       theScene.traverse(function(child) {
       console.log("\n==>Traversing the Scene now...");
          if(child.isMesh) {
             console.log("1. 'child' - FULL MESH INFO = ", child);
      
             if(child.name) {
                console.log(" 2. 'child.name' = ", child.name);
                console.log(" 3. 'child.geometry' = ", child.geometry, "\n");

                if(child.name.startsWith("Mesh_Mesh_head")) {
                   // Calling a convenience method I made here - code below:
                   let theColors = makeSmoothGradientColorsForMesh(child, "orange", "white");

                   child.geometry.setAttribute("color", new THREE.Float32BufferAttribute(theColors, 3));     
                   child.material.vertexColors = true;
                   child.material.flatShading = false;
                } 
             } 
          } 
       }); 
  
      scene.add(theScene);
      theScene.position.set(0, 0, 0);
    }) 

这是我的便捷方法:

function makeSmoothGradientColorsForMesh(theMesh, c1, c2) {
   console.log("\n\n===>In 'makeSmoothGradientColorsForMesh()'!\n");
   console.log(">Incoming meshObject: \n", theMesh);

   let meshGeometry = theMesh.geometry;
   let meshMaterial = theMesh.material;

   // Do the Geometry-Dance:
   const positionAttribute = meshGeometry.getAttribute("position");
   console.log(">positionAttribute = \n", positionAttribute);
   meshGeometry.computeVertexNormals();

   // "BoundingBox" business:
   meshGeometry.computeBoundingBox();
   const aabb = meshGeometry.boundingBox;
   console.log(">aabb = \n", aabb);
   const f = aabb.max.z - aabb.min.z;
   const vertex = new THREE.Vector3();

   // COLORS business:
   let randomColor = new THREE.Color();
   let colorsArray = [];
   const c = new THREE.Color();                     

   console.log("positionAttribute.count = ", positionAttribute.count);

   for(let i = 0; i < positionAttribute.count; i++) {
      vertex.fromBufferAttribute( positionAttribute, i );
      c.lerpColors( c1, c2, ( vertex.z - aabb.min.z) / f );
      colorsArray.push(c.r, c.g, c.b); 
   }

   console.log("\n\n-->Will be returning the following colors:\n");
   console.log(colorsArray);

   return colorsArray;
}

由于某种原因,我的makeSmoothGradientColorsForMesh()方法返回的颜色,返回如下:

Array(145440) [ NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, NaN, … ]

【问题讨论】:

    标签: colors three.js mesh .obj


    【解决方案1】:

    您的c.lerpColors() 实现是错误的。您正在尝试将字符串传递给该方法 ("orange", "white"),它无法识别并返回 NaN

    该方法需要两个 THREE.Color 对象,因此您应该先初始化它们:

    // We use the strings to init our THREE.Colors
    let color1 = new THREE.Color(c1);
    let color2 = new THREE.Color(c2);
    
    for(let i = 0; i < positionAttribute.count; i++) {
      vertex.fromBufferAttribute( positionAttribute, i );
      // Now we can use them for color lerping
      c.lerpColors( color1, color2, ( vertex.z - aabb.min.z) / f );
      colorsArray.push(c.r, c.g, c.b); 
    }
    

    【讨论】:

    • 啊,早上好!当然!我应该传递颜色,而不是字符串。我真傻!好的,谢谢 - 非常感谢!
    • @Marqizzo - 你有没有机会告诉我为什么我的小提琴没有从 THREE.js git 加载那个“.obj”模型?很高兴知道我将来创作的小提琴。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-10
    • 1970-01-01
    • 2022-08-18
    • 2019-02-22
    • 1970-01-01
    • 2015-01-15
    • 1970-01-01
    相关资源
    最近更新 更多