【问题标题】:Color based on .obj model基于 .obj 模型的颜色
【发布时间】:2019-10-06 05:28:51
【问题描述】:

我想根据我的模型的高度设置颜色,这是一个 .obj 文件。我希望颜色从绿色变为红色,具体取决于高度,最小点为绿色,最大点为红色。这是我目前的代码:

loader.load(nombreMapa, function (object) {
    loader.setMaterials(material);
    escena.add(object);
    object.position.y = -10;
    if (object instanceof THREE.Object3D)
    {
    object.traverse (function (mesh)
    {
        if (! (mesh instanceof THREE.Mesh)) return;
        mesh.material = new THREE.MeshNormalMaterial();
        mesh.material.side = THREE.DoubleSide;
        var geometry = new THREE.EdgesGeometry( mesh.geometry );
        var material1 = new THREE.LineBasicMaterial( { color: 0x000000, linewidth: 1000 } );
        var edges = new THREE.LineSegments( geometry, material1 );
        mesh.add( edges );
    });
}});

【问题讨论】:

    标签: javascript html three.js


    【解决方案1】:

    您可以做到这一点,使用THREE.Color()THREE.Box3().lerp() 方法设置每个子网格几何体中每个顶点的颜色。

    var scene = new THREE.Scene();
    var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
    camera.position.set(0, 60, 250);
    var renderer = new THREE.WebGLRenderer();
    renderer.setSize(window.innerWidth, window.innerHeight);
    renderer.setClearColor(0x404040);
    document.body.appendChild(renderer.domElement);
    
    var controls = new THREE.OrbitControls(camera, renderer.domElement);
    controls.target.set(0, 60, 0);
    controls.update();
    
    var mat = new THREE.MeshBasicMaterial({
      wireframe: true,
      vertexColors: THREE.VertexColors
    }); // the same material for all the children of the object
    
    var loader = new THREE.OBJLoader();
    loader.load('https://threejs.org/examples/models/obj/male02/male02.obj', function(obj) {
    
      var size = new THREE.Vector3();
      var box3 = new THREE.Box3().setFromObject(obj);
      box3.getSize(size);
      console.log(size);
    
      var v3 = new THREE.Vector3(); // for re-use
      
      var c = [
        new THREE.Color(0x00ff00),
        new THREE.Color(0xff0000)
      ];
      var cTemp = new THREE.Color(); // for re-use
    
      obj.traverse(child => {
        if (child.isMesh) {
          
          let colors = []; // array for color values of the current mesh's geometry
          
          let pos = child.geometry.attributes.position;
          
          for(let i = 0; i < pos.count; i++){
            
            v3.fromBufferAttribute(pos, i);
            
            obj.localToWorld(v3); // box3 is in world coords so we have to convert coortinates of the vertex from local to world
            
            let a = (v3.y - box3.min.y) / size.y; // find the value in range 0..1
            
            cTemp.copy(c[0]).lerp(c[1], a); // lerp the colors
            
            colors.push(cTemp.r, cTemp.g, cTemp.b); // save values in the array
            
            child.geometry.addAttribute("color", new THREE.BufferAttribute(new Float32Array(colors), 3)); // add a buffer attribute for colors
            
            child.material = mat;
          }
        }
      });
      scene.add(obj);
    })
    
    renderer.setAnimationLoop(() => {
      renderer.render(scene, camera)
    });
    body {
      overflow: hidden;
      margin: 0;
    }
    <script src="https://threejs.org/build/three.min.js"></script>
    <script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
    <script src="https://threejs.org/examples/js/loaders/OBJLoader.js"></script>

    另外,请查看SO answer,了解如何应用渐变的其他选项。

    【讨论】:

    • 我做了这个并且它有效,但是渲染我的自定义 .obj 需要很长时间。我尝试使用您在示例中提供的模型并以正常速度渲染,但使用我拥有的模型 (1 MB) 需要太长时间。为什么会这样?有什么想法吗?
    • @Gjaa 看看这个SO answer 了解更多关于渐变的想法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-10-02
    • 2018-08-26
    • 2012-09-11
    • 1970-01-01
    • 2020-07-02
    • 2020-01-17
    • 1970-01-01
    相关资源
    最近更新 更多