首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GLTF创建实例

GLTF创建实例
EN

Stack Overflow用户
提问于 2017-08-14 08:02:46
回答 2查看 3.7K关注 0票数 6

我是新来的三年级学生。在过去,我使用过AFRAME,铯,XEOGL和BABYLONJS。但最终,由于内存消耗和性能,我意识到制作CAD可视化器的最佳产品是THREEJS。

BABYLONJS需要超过4分钟来加载一个大GLTF文件(400 30 ),而THREEJS只需要30秒。BABYLONJS占用的内存是THREEJS的4倍。

我知道在THREEJS中仍然有一些问题需要从加载的GLTF文件中创建实例(GPU),但是我只需要更改每个实例中的位置和旋转,不需要任何动画。

我尝试了GLTF1.0和GLTF2.0,问题也是一样的。当我加载GLTF模型时,我得到了一个场景。从这个场景中,我试图从子数组中获取缓冲区几何。然而,当我尝试对一个实例进行分类时,它是无效的。我的对象是静态的(根本没有动画)。

是否有任何方法来创建Object3D的实例或从其缓冲区几何学创建实例?

在BABYLONJS中,从加载的GLTF文件创建实例非常简单。我真的需要使用实例来保存RAM和使用GPU代替CPU资源。我的场景需要加载许多相同对象的副本来复合场景。

使用GLFT加载程序时,我看到了一些问题:

    1. 您必须标识包含有效几何的所有object3Ds。在本例中,在第335行:

var geo = data.scene.children[0].children[0].children[0].children[0].geometry

    1. 合并示例不起作用。在最初的示例中,这两种方法都不起作用。

    1. 实例化似乎根本不能改善业绩:

  • 10000个对象,多材料-> 4FPS
  • 10000个对象,单声道-> 4FPS
  • 10000个对象,实例-> 4FPS
  • 10000个对象,合并->不工作
    1. 当选择instanced时,几何形状没有正确地呈现。

这里有我的代码,使用Duck GLTF示例:

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>three.js webgl - interactive instances (gpu)</title>
    <meta charset="utf-8" />
    <meta
      name="viewport"
      content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0"
    />
    <style>
      body {
        font-family: Monospace;
        background-color: #f0f0f0;
        margin: 0px;
        overflow: hidden;
      }
      .info {
        position: absolute;
        background-color: black;
        opacity: 0.8;
        color: white;
        text-align: center;
        top: 0px;
        width: 100%;
      }
      .info a {
        color: #00ffff;
      }
      #notSupported {
        width: 50%;
        margin: auto;
        border: 2px red solid;
        margin-top: 20px;
        padding: 10px;
      }
    </style>
  </head>
  <body>
    <div class="info">
      <a href="http://threejs.org" target="_blank" rel="noopener">three.js</a>
      webgl - gpu picking of geometry instances
      <div id="notSupported" style="display: none">
        Sorry your graphics card + browser does not support hardware instancing
      </div>
      <br /><br />
      <div>
        This demo compares different methods of constructing and rendering many
        instances of a single geometry.
      </div>
      <br />
      <div>
        <div style="display: inline-block">
          <span>number of<br />geometry instances</span>
          <br />
          <select id="instanceCount">
            <option>100</option>
            <option>500</option>
            <option selected>1000</option>
            <option>2000</option>
            <option>3000</option>
            <option>5000</option>
            <option>10000</option>
            <option>20000</option>
            <option>30000</option>
            <option>50000</option>
            <option>100000</option>
          </select>
        </div>
        &nbsp;&nbsp;&nbsp;
        <div style="display: inline-block">
          <span>method of<br />construction/rendering</span>
          <br />
          <select id="method">
            <option>instanced</option>
            <option>merged</option>
            <option selected>singleMaterial</option>
            <option>multiMaterial</option>
          </select>
        </div>
        &nbsp;&nbsp;&nbsp;
        <div style="display: inline-block">
          <span>render continuously<br />(to get fps reading)</span>
          <br />
          <input id="animate" type="checkbox" />
        </div>
        &nbsp;&nbsp;&nbsp;
        <div style="display: inline-block">
          <span
            >use override material<br />(only effects singleMaterial
            method)</span
          >
          <br />
          <input id="override" type="checkbox" checked />
        </div>
        &nbsp;&nbsp;&nbsp;
        <div style="display: inline-block">
          <span>construct anew<br />(to get additional timings)</span>
          <br />
          <button id="construct" type="button">do it</button>
        </div>
      </div>
      <br />
      <div>
        <span>Materials: #<span id="materialCount"></span></span>
        &nbsp;&nbsp;&nbsp;
        <span>Objects: #<span id="objectCount"></span></span>
        &nbsp;&nbsp;&nbsp;
        <span>Drawcalls: #<span id="drawcalls"></span></span>
        &nbsp;&nbsp;&nbsp;
        <span>Construction time: <span id="initTime"></span>&nbsp;ms</span>
        &nbsp;&nbsp;&nbsp;
      </div>
    </div>
    <div id="container"></div>
    <script src="../build/three.js"></script>
    <script src="js/controls/TrackballControls.js"></script>
    <script src="js/libs/stats.min.js"></script>
    <script src="js/loaders/GLTF2Loader.js"></script>
    <script id="vertMerged" type="x-shader/x-vertex">
      #define SHADER_NAME vertMerged
      precision highp float;
      uniform mat4 modelViewMatrix;
      uniform mat4 projectionMatrix;
      attribute vec3 position;
      #ifdef PICKING
      attribute vec3 pickingColor;
      #else
      attribute vec3 color;
      varying vec3 vPosition;
      #endif
      varying vec3 vColor;
      void main()   {
      vec3 positionEye = ( modelViewMatrix * vec4( position, 1.0 ) ).xyz;
      #ifdef PICKING
      vColor = pickingColor;
      #else
      vColor = color;
      vPosition = positionEye;
      #endif
      gl_Position = projectionMatrix * vec4( positionEye, 1.0 );
      }
    </script>
    <script id="fragMerged" type="x-shader/x-fragment">
      #define SHADER_NAME fragMerged
      #extension GL_OES_standard_derivatives : enable
      precision highp float;
      varying vec3 vColor;
      #ifndef PICKING
      varying vec3 vPosition;
      #endif
      void main()   {
      #ifdef PICKING
      gl_FragColor = vec4( vColor, 1.0 );
      #else
      vec3 fdx = dFdx( vPosition );
      vec3 fdy = dFdy( vPosition );
      vec3 normal = normalize( cross( fdx, fdy ) );
      float diffuse = dot( normal, vec3( 0.0, 0.0, 1.0 ) );
      gl_FragColor = vec4( diffuse * vColor, 1.0 );
      #endif
      }
    </script>
    <script id="vertInstanced" type="x-shader/x-vertex">
      #define SHADER_NAME vertInstanced
      precision highp float;
      uniform mat4 modelViewMatrix;
      uniform mat4 projectionMatrix;
      attribute vec3 position;
      attribute vec3 mcol0;
      attribute vec3 mcol1;
      attribute vec3 mcol2;
      attribute vec3 mcol3;
      #ifdef PICKING
      attribute vec3 pickingColor;
      #else
      attribute vec3 color;
      varying vec3 vPosition;
      #endif
      varying vec3 vColor;
      void main()   {
      mat4 matrix = mat4(
      vec4( mcol0, 0 ),
      vec4( mcol1, 0 ),
      vec4( mcol2, 0 ),
      vec4( mcol3, 1 )
      );
      vec3 positionEye = ( modelViewMatrix * matrix * vec4( position, 1.0 ) ).xyz;
      #ifdef PICKING
      vColor = pickingColor;
      #else
      vColor = color;
      vPosition = positionEye;
      #endif
      gl_Position = projectionMatrix * vec4( positionEye, 1.0 );
      }
    </script>
    <script id="fragInstanced" type="x-shader/x-fragment">
      #define SHADER_NAME fragInstanced
      #extension GL_OES_standard_derivatives : enable
      precision highp float;
      varying vec3 vColor;
      #ifndef PICKING
      varying vec3 vPosition;
      #endif
      void main()   {
      #ifdef PICKING
      gl_FragColor = vec4( vColor, 1.0 );
      #else
      vec3 fdx = dFdx( vPosition );
      vec3 fdy = dFdy( vPosition );
      vec3 normal = normalize( cross( fdx, fdy ) );
      float diffuse = dot( normal, vec3( 0.0, 0.0, 1.0 ) );
      gl_FragColor = vec4( diffuse * vColor, 1.0 );
      #endif
      }
    </script>
    <script id="vertMaterial" type="x-shader/x-vertex">
      #define SHADER_NAME vertMaterial
      precision highp float;
      uniform mat4 modelViewMatrix;
      uniform mat4 projectionMatrix;
      attribute vec3 position;
      #ifndef PICKING
      varying vec3 vPosition;
      #endif
      void main()   {
      vec3 positionEye = ( modelViewMatrix * vec4( position, 1.0 ) ).xyz;
      #ifndef PICKING
      vPosition = positionEye;
      #endif
      gl_Position = projectionMatrix * vec4( positionEye, 1.0 );
      }
    </script>
    <script id="fragMaterial" type="x-shader/x-fragment">
      #define SHADER_NAME fragMaterial
      #extension GL_OES_standard_derivatives : enable
      precision highp float;
      #ifdef PICKING
      uniform vec3 pickingColor;
      #else
      uniform vec3 color;
      varying vec3 vPosition;
      #endif
      void main()   {
      #ifdef PICKING
      gl_FragColor = vec4( pickingColor, 1.0 );
      #else
      vec3 fdx = dFdx( vPosition );
      vec3 fdy = dFdy( vPosition );
      vec3 normal = normalize( cross( fdx, fdy ) );
      float diffuse = dot( normal, vec3( 0.0, 0.0, 1.0 ) );
      gl_FragColor = vec4( diffuse * color, 1.0 );
      #endif
      }
    </script>
    <script>
      var container, stats;
      var camera, controls, scene, renderer;
      var pickingData, pickingRenderTarget, pickingScene;
      var useOverrideMaterial = true;
      var singleMaterial, singlePickingMaterial;
      var highlightBox;
      var materialList = [];
      var geometryList = [];
      var objectCount = 0;
      var geometrySize;
      var mouse = new THREE.Vector2();
      var scale = 1.03;
      var loader = new THREE.GLTF2Loader();
      var pixelBuffer = new Uint8Array(4);
      var instanceCount, method, doAnimate;
      gui();
      init();
      initMesh();
      if (doAnimate) animate();
      function gui() {
        var instanceCountElm = document.getElementById("instanceCount");
        instanceCount = parseInt(instanceCountElm.value);
        instanceCountElm.addEventListener("change", function () {
          instanceCount = parseInt(instanceCountElm.value);
          initMesh();
        });
        var methodElm = document.getElementById("method");
        method = methodElm.value;
        methodElm.addEventListener("change", function () {
          method = methodElm.value;
          initMesh();
        });
        var animateElm = document.getElementById("animate");
        doAnimate = animateElm.checked;
        animateElm.addEventListener("click", function () {
          doAnimate = animateElm.checked;
          animate();
        });
        var overrideElm = document.getElementById("override");
        useOverrideMaterial = overrideElm.checked;
        overrideElm.addEventListener("click", function () {
          useOverrideMaterial = overrideElm.checked;
          initMesh();
        });
        var constructElm = document.getElementById("construct");
        constructElm.addEventListener("click", function () {
          initMesh();
        });
      }
      function clean() {
        THREE.Cache.clear();
        materialList.forEach(function (m) {
          m.dispose();
        });
        geometryList.forEach(function (g) {
          g.dispose();
        });
        scene = new THREE.Scene();
        scene.background = new THREE.Color(0xffffff);
        scene.add(camera);
        scene.add(highlightBox);
        pickingScene = new THREE.Scene();
        pickingData = {};
        materialList = [];
        geometryList = [];
        objectCount = 0;
        singleMaterial = undefined;
        singlePickingMaterial = undefined;
      }
      var randomizeMatrix = (function () {
        var position = new THREE.Vector3();
        var rotation = new THREE.Euler();
        var quaternion = new THREE.Quaternion();
        var scale = new THREE.Vector3();
        return function (matrix) {
          position.x = Math.random() * 40 - 20;
          position.y = Math.random() * 40 - 20;
          position.z = Math.random() * 40 - 20;
          rotation.x = Math.random() * 2 * Math.PI;
          rotation.y = Math.random() * 2 * Math.PI;
          rotation.z = Math.random() * 2 * Math.PI;
          quaternion.setFromEuler(rotation, false);
          scale.x = scale.y = scale.z = 0.001;
          matrix.compose(position, quaternion, scale);
        };
      })();
      function initMesh() {
        clean();
        loader.load("models/gltf/Duck/glTF-Binary/Duck.glb", function (data) {
          console.log(data);
          var geo =
            data.scene.children[0].children[0].children[0].children[0].geometry;
          console.log("geo:");
          console.log(geo);
          geo.computeBoundingBox();
          geometrySize = geo.boundingBox.getSize();
          geometryList.push(geo);
          var start = window.performance.now();
          switch (method) {
            case "merged":
              makeMerged(geo);
              break;
            case "instanced":
              makeInstanced(geo);
              break;
            case "singleMaterial":
              makeSingleMaterial(geo);
              break;
            case "multiMaterial":
              makeMultiMaterial(geo);
              break;
          }
          render();
          var end = window.performance.now();
          document.getElementById("materialCount").innerText =
            materialList.length;
          document.getElementById("objectCount").innerText = objectCount;
          document.getElementById("drawcalls").innerText =
            renderer.info.render.calls;
          document.getElementById("initTime").innerText = (end - start).toFixed(
            2
          );
        });
      }
      function makeMultiMaterial(geo) {
        var vert = document.getElementById("vertMaterial").textContent;
        var frag = document.getElementById("fragMaterial").textContent;
        var material = new THREE.RawShaderMaterial({
          vertexShader: vert,
          fragmentShader: frag,
          uniforms: {
            color: {
              value: new THREE.Color(),
            },
          },
        });
        var pickingMaterial = new THREE.RawShaderMaterial({
          vertexShader: "#define PICKING\n" + vert,
          fragmentShader: "#define PICKING\n" + frag,
          uniforms: {
            pickingColor: {
              value: new THREE.Color(),
            },
          },
        });
        var matrix = new THREE.Matrix4();
        for (var i = 0; i < instanceCount; i++) {
          var object = new THREE.Mesh(geo, material);
          objectCount++;
          randomizeMatrix(matrix);
          object.applyMatrix(matrix);
          var pickingObject = object.clone();
          objectCount++;
          object.material = material.clone();
          object.material.uniforms.color.value.setHex(Math.random() * 0xffffff);
          materialList.push(object.material);
          pickingObject.material = pickingMaterial.clone();
          pickingObject.material.uniforms.pickingColor.value.setHex(i + 1);
          materialList.push(pickingObject.material);
          pickingData[i + 1] = object;
          scene.add(object);
          pickingScene.add(pickingObject);
        }
        material.dispose();
        pickingMaterial.dispose();
      }
      function makeSingleMaterial(geo) {
        var vert = document.getElementById("vertMaterial").textContent;
        var frag = document.getElementById("fragMaterial").textContent;
        var material = new THREE.RawShaderMaterial({
          vertexShader: vert,
          fragmentShader: frag,
          uniforms: {
            color: {
              value: new THREE.Color(),
            },
          },
        });
        materialList.push(material);
        var pickingMaterial = new THREE.RawShaderMaterial({
          vertexShader: "#define PICKING\n" + vert,
          fragmentShader: "#define PICKING\n" + frag,
          uniforms: {
            pickingColor: {
              value: new THREE.Color(),
            },
          },
        });
        materialList.push(pickingMaterial);
        if (useOverrideMaterial) {
          singleMaterial = material;
          singlePickingMaterial = pickingMaterial;
        }
        var matrix = new THREE.Matrix4();
        function onBeforeRender(
          renderer,
          scene,
          camera,
          geometry,
          material,
          group
        ) {
          var updateList = [];
          var u = material.uniforms;
          var d = this.userData;
          if (u.pickingColor) {
            u.pickingColor.value.setHex(d.pickingColor);
            updateList.push("pickingColor");
          }
          if (u.color) {
            u.color.value.setHex(d.color);
            updateList.push("color");
          }
          if (updateList.length) {
            var materialProperties = renderer.properties.get(material);
            if (materialProperties.program) {
              var gl = renderer.getContext();
              var p = materialProperties.program;
              gl.useProgram(p.program);
              var pu = p.getUniforms();
              updateList.forEach(function (name) {
                pu.setValue(gl, name, u[name].value);
              });
            }
          }
        }
        for (var i = 0; i < instanceCount; i++) {
          var object = new THREE.Mesh(geo, material);
          objectCount++;
          randomizeMatrix(matrix);
          object.applyMatrix(matrix);
          var pickingObject;
          if (!useOverrideMaterial) {
            pickingObject = object.clone();
            objectCount++;
          }
          object.material = material;
          object.userData["color"] = Math.random() * 0xffffff;
          if (useOverrideMaterial) {
            object.userData["pickingColor"] = i + 1;
            object.onBeforeRender = onBeforeRender;
          } else {
            pickingObject.material = pickingMaterial;
            pickingObject.userData["pickingColor"] = i + 1;
            pickingObject.onBeforeRender = onBeforeRender;
          }
          pickingData[i + 1] = object;
          scene.add(object);
          if (!useOverrideMaterial) pickingScene.add(pickingObject);
        }
      }
      function makeMerged(geo) {
        var vert = document.getElementById("vertMerged").textContent;
        var frag = document.getElementById("fragMerged").textContent;
        var material = new THREE.RawShaderMaterial({
          vertexShader: vert,
          fragmentShader: frag,
        });
        materialList.push(material);
        var pickingMaterial = new THREE.RawShaderMaterial({
          vertexShader: "#define PICKING\n" + vert,
          fragmentShader: "#define PICKING\n" + frag,
        });
        materialList.push(pickingMaterial);
        var bgeo = geo.clone();
        geometryList.push(bgeo);
        var mgeo = new THREE.BufferGeometry();
        geometryList.push(mgeo);
        var pos = bgeo.attributes.position;
        var posLen = bgeo.attributes.position.count * 3;
        var vertices = new THREE.BufferAttribute(
          new Float32Array(instanceCount * posLen),
          3
        );

        var matrix = new THREE.Matrix4();
        for (var i = 0, ul = instanceCount; i < ul; i++) {
          randomizeMatrix(matrix);
          var object = new THREE.Object3D();
          objectCount++;
          object.applyMatrix(matrix);
          pickingData[i + 1] = object;
          vertices.set(pos.array, i * posLen);
          //matrix.applyToVector3Array( vertices.array, i * posLen, posLen )
        }
        mgeo.addAttribute("position", vertices);
        var colCount = posLen / 3;
        var colors = new THREE.BufferAttribute(
          new Float32Array(instanceCount * colCount * 3),
          3
        );

        var randCol = function () {
          return Math.random();
        };
        for (var i = 0, ul = instanceCount; i < ul; i++) {
          var r = randCol(),
            g = randCol(),
            b = randCol();
          for (var j = i * colCount, jl = (i + 1) * colCount; j < jl; j++) {
            colors.setXYZ(j, r, g, b);
          }
        }
        mgeo.addAttribute("color", colors);
        var col = new THREE.Color();
        var pickingColors = new THREE.BufferAttribute(
          new Float32Array(instanceCount * colCount * 3),
          3
        );
        for (var i = 0, ul = instanceCount; i < ul; i++) {
          col.setHex(i + 1);
          for (var j = i * colCount, jl = (i + 1) * colCount; j < jl; j++) {
            pickingColors.setXYZ(j, col.r, col.g, col.b);
          }
        }
        mgeo.addAttribute("pickingColor", pickingColors);
        var mesh = new THREE.Mesh(mgeo, material);
        scene.add(mesh);
        var pickingMesh = new THREE.Mesh(mgeo, pickingMaterial);
        pickingScene.add(pickingMesh);
      }
      function makeInstanced(geo) {
        var vert = document.getElementById("vertInstanced").textContent;
        var frag = document.getElementById("fragInstanced").textContent;
        var material = new THREE.RawShaderMaterial({
          vertexShader: vert,
          fragmentShader: frag,
        });
        materialList.push(material);
        var pickingMaterial = new THREE.RawShaderMaterial({
          vertexShader: "#define PICKING\n" + vert,
          fragmentShader: "#define PICKING\n" + frag,
        });
        materialList.push(pickingMaterial);
        var bgeo = geo.clone();
        geometryList.push(bgeo);
        var igeo = new THREE.InstancedBufferGeometry();
        geometryList.push(igeo);
        var vertices = bgeo.attributes.position.clone();
        igeo.addAttribute("position", vertices);
        var mcol0 = new THREE.InstancedBufferAttribute(
          new Float32Array(instanceCount * 3),
          3,
          1
        );
        var mcol1 = new THREE.InstancedBufferAttribute(
          new Float32Array(instanceCount * 3),
          3,
          1
        );
        var mcol2 = new THREE.InstancedBufferAttribute(
          new Float32Array(instanceCount * 3),
          3,
          1
        );
        var mcol3 = new THREE.InstancedBufferAttribute(
          new Float32Array(instanceCount * 3),
          3,
          1
        );
        var matrix = new THREE.Matrix4();
        var me = matrix.elements;
        for (var i = 0, ul = mcol0.count; i < ul; i++) {
          randomizeMatrix(matrix);
          var object = new THREE.Object3D();
          objectCount++;
          object.applyMatrix(matrix);
          pickingData[i + 1] = object;
          mcol0.setXYZ(i, me[0], me[1], me[2]);
          mcol1.setXYZ(i, me[4], me[5], me[6]);
          mcol2.setXYZ(i, me[8], me[9], me[10]);
          mcol3.setXYZ(i, me[12], me[13], me[14]);
        }
        igeo.addAttribute("mcol0", mcol0);
        igeo.addAttribute("mcol1", mcol1);
        igeo.addAttribute("mcol2", mcol2);
        igeo.addAttribute("mcol3", mcol3);
        var randCol = function () {
          return Math.random();
        };
        var colors = new THREE.InstancedBufferAttribute(
          new Float32Array(instanceCount * 3),
          3,
          1
        );
        for (var i = 0, ul = colors.count; i < ul; i++) {
          colors.setXYZ(i, randCol(), randCol(), randCol());
        }
        igeo.addAttribute("color", colors);
        var col = new THREE.Color();
        var pickingColors = new THREE.InstancedBufferAttribute(
          new Float32Array(instanceCount * 3),
          3,
          1
        );
        for (var i = 0, ul = pickingColors.count; i < ul; i++) {
          col.setHex(i + 1);
          pickingColors.setXYZ(i, col.r, col.g, col.b);
        }
        igeo.addAttribute("pickingColor", pickingColors);
        var mesh = new THREE.Mesh(igeo, material);
        scene.add(mesh);
        var pickingMesh = new THREE.Mesh(igeo, pickingMaterial);
        pickingScene.add(pickingMesh);
      }
      function init() {
        camera = new THREE.PerspectiveCamera(
          70,
          window.innerWidth / window.innerHeight,
          1,
          100
        );
        camera.position.z = 40;
        pickingRenderTarget = new THREE.WebGLRenderTarget(
          window.innerWidth,
          window.innerHeight
        );
        pickingRenderTarget.texture.generateMipmaps = false;
        pickingRenderTarget.texture.minFilter = THREE.NearestFilter;
        highlightBox = new THREE.Mesh(
          new THREE.BoxGeometry(1, 1, 1),
          new THREE.MeshLambertMaterial({
            emissive: 0xffff00,
            transparent: true,
            opacity: 0.5,
            side: THREE.FrontSide,
          })
        );
        container = document.getElementById("container");
        renderer = new THREE.WebGLRenderer({
          antialias: true,
          alpha: true,
        });
        if (renderer.extensions.get("ANGLE_instanced_arrays") === false) {
          document.getElementById("notSupported").style.display = "";
          return;
        }
        renderer.setPixelRatio(window.devicePixelRatio);
        renderer.setSize(window.innerWidth, window.innerHeight);
        container.appendChild(renderer.domElement);
        if (renderer.extensions.get("ANGLE_instanced_arrays") === false) {
          throw "ANGLE_instanced_arrays not supported";
        }
        controls = new THREE.TrackballControls(camera, renderer.domElement);
        controls.staticMoving = true;
        stats = new Stats();
        container.appendChild(stats.dom);
        renderer.domElement.addEventListener("mousemove", onMouseMove);
        window.addEventListener("resize", onWindowResize, false);
      }
      //
      function onMouseMove(e) {
        mouse.x = e.clientX;
        mouse.y = e.clientY;
        controls.update();
        requestAnimationFrame(render);
      }
      function onWindowResize(event) {
        camera.aspect = window.innerWidth / window.innerHeight;
        camera.updateProjectionMatrix();
        renderer.setSize(window.innerWidth, window.innerHeight);
        pickingRenderTarget.setSize(window.innerWidth, window.innerHeight);
      }
      function animate() {
        if (doAnimate) {
          requestAnimationFrame(animate);
        }
        controls.update();
        stats.update();
        document.getElementById("materialCount").innerText =
          materialList.length;
        document.getElementById("objectCount").innerText = objectCount;
        document.getElementById("drawcalls").innerText =
          renderer.info.render.calls;
        render();
      }
      function pick() {
        highlightBox.visible = false;
        if (singlePickingMaterial) {
          scene.overrideMaterial = singlePickingMaterial;
          renderer.render(scene, camera, pickingRenderTarget);
          scene.overrideMaterial = null;
        } else {
          renderer.render(pickingScene, camera, pickingRenderTarget);
        }
        renderer.readRenderTargetPixels(
          pickingRenderTarget,
          mouse.x,
          pickingRenderTarget.height - mouse.y,
          1,
          1,
          pixelBuffer
        );
        var id =
          (pixelBuffer[0] << 16) | (pixelBuffer[1] << 8) | pixelBuffer[2];
        var object = pickingData[id];
        if (object) {
          if (object.position && object.rotation && object.scale) {
            highlightBox.position.copy(object.position);
            highlightBox.rotation.copy(object.rotation);
            highlightBox.scale
              .copy(object.scale)
              .multiply(geometrySize)
              .multiplyScalar(scale);
            highlightBox.visible = true;
          }
        } else {
          highlightBox.visible = false;
        }
      }
      function render() {
        pick();
        renderer.render(scene, camera);
      }
    </script>
  </body>
</html>
EN

回答 2

Stack Overflow用户

发布于 2017-08-14 23:38:35

您的问题似乎主要是,如何在three.js中执行实例?一旦加载了模型,您使用什么格式创建它并不重要。

在这种情况下,您可能只想查看three.js实例或使用像三层网格这样的助手。

第二个链接展示了如何进行,一旦您从模型中获取了几何图形:

代码语言:javascript
复制
// Assumes your model only contains one mesh.
var geometry;
model.traverse(function (node) => {
  if (node.isMesh) {
    geometry = node.geometry;
  }
});

//material that the geometry will use 
var material = new THREE.MeshPhongMaterial();

//the instance group 
var cluster = new THREE.InstancedMesh( 
  geometry,
  material, 
  10000, //instance count 
  false, //is it dynamic 
  false  //does it have color 
  true,  //uniform scale
);

var _v3 = new THREE.Vector3();
var _q = new THREE.Quaternion();

for ( var i ; i < 10000 ; i ++ ) {

  cluster.setQuaternionAt( i , _q );
  cluster.setPositionAt( i , v3.set( Math.random() , Math.random(), Math.random() ) );
  cluster.setScaleAt( i , v3.set(1,1,1) );

}

scene.add( cluster );
票数 7
EN

Stack Overflow用户

发布于 2017-09-05 07:36:43

经过一段时间的调查后,我发现了为什么使用instancedBuffer几何学不适用于我的GLTF文件中的缓冲区。

问题是GLTF格式使用索引缓冲几何学,解决方法非常简单,只需使用toNonIndexed()方法来转换它们。

问题解决了。

诚挚的问候

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45669968

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档