首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么我的Three.js动画在Vue.js中变慢了?

为什么我的Three.js动画在Vue.js中变慢了?
EN

Stack Overflow用户
提问于 2019-10-25 21:09:02
回答 1查看 1.3K关注 0票数 0

我正在尝试在Vue.js中重新创建一个很棒的wave模拟:https://codepen.io/cheekymonkey/pen/vMvYNV。然而,当我在Vue.js中重新创建动画时,它真的很慢

我已经尝试使所有函数都与Vue.js方法相同,并将变量包含在组件的data属性中。

代码语言:javascript
复制
<template>
    <div id="container" style="width:100%; height:100vh;"></div>
</template>

<script>
import * as Three from 'three'
import SimplexNoise from'simplex-noise'

export default {
  name: 'ThreeTest',
  data() {
    return {
      camera: Three.PerspectiveCamera,
      scene: Three.Scene,
      renderer: Three.WebGLRenderer,
      mesh: Three.Mesh,
      noise: SimplexNoise,
      geometry: null,
      factor: 0
    }
  },
  methods: {
    init: function() {
      this.createScene();
      this.createCamera();
      this.createShape();
      this.addSpotlight('#fdffab');
      this.addAmbientLight();
      this.animate();
      window.addEventListener('resize', this.onResize())

    },
    onResize: function() {
      let container = document.getElementById('container');
      this.renderer.setSize(container.clientWidth, container.clientHeight);
      this.camera.aspect = container.clientWidth / container.clientHeight;
      this.camera.updateProjectionMatrix();
    },
    createScene: function() {
      this.scene = new Three.Scene();
      this.renderer = new Three.WebGLRenderer({
        antialias: true,
        alpha: true
      });
      let container = document.getElementById('container');
      this.renderer.setSize(container.clientWidth, container.clientHeight);
      this.renderer.setPixelRatio(window.devicePixelRatio);
      this.renderer.setClearColor(new Three.Color('#fff'));
      //this.render.shadowMap.type = Three.PCFSoftShadowMap;
      this.noise = new SimplexNoise()
      container.appendChild(this.renderer.domElement);
    },
    createCamera: function() {
      this.camera = new Three.PerspectiveCamera(20, container.clientWidth/container.clientHeight, 1, 1000);
      this.camera.position.set(0, 0, 20);
    },
    createShape: function() {
      const seg = 100
      this.geometry = new Three.PlaneGeometry(5, 8, seg, seg)
      const material = new Three.MeshPhysicalMaterial({
        color: '#da0463',
        metalness: 0.6,
        emissive: '#000',
        side: Three.DoubleSide,
        wireframe: true
      })
      this.mesh = new Three.Mesh(this.geometry, material)
      this.mesh.receiveShadow = true
      this.mesh.castShadow = true
      this.mesh.position.set(0, 0, 0)
      this.mesh.rotation.x = -Math.PI / 3
      this.mesh.rotation.z = -Math.PI / 4
      this.scene.add(this.mesh)
    },
    addSpotlight: function(color) {
      const light = new Three.SpotLight(color, 2, 1000)
      light.position.set(0, 0, 30)
      this.scene.add(light)
    },
    addAmbientLight: function() {
      const light = new Three.AmbientLight('#fff', 0.5)
      this.scene.add(light)
    },
    addjustVertices: function() {
      for (let i = 0; i < this.geometry.vertices.length; i++) {
        const vertex = this.geometry.vertices[i]
        const x = vertex.x / 4
        const y = vertex.y / 6
        vertex.z = this.noise.noise2D(x, y + this.factor)
      }
      this.factor += 0.007
      this.geometry.verticesNeedUpdate = true
      this.geometry.computeVertexNormals()
    },
    animate: function() {
        requestAnimationFrame(this.animate);
        this.addjustVertices();
        this.camera.updateProjectionMatrix();
        this.renderer.render(this.scene, this.camera);
    }
  },
  mounted() {
      this.init();
  }
}
</script>

它可以正常工作,就像在波浪动画中一样,但它的速度要慢得多。不确定这是由于Vue.js还是我是如何设置的。任何建议都非常感谢!

EN

回答 1

Stack Overflow用户

发布于 2020-01-31 03:46:00

这是因为引擎盖下的Vue使附加到实例的每个组件具有响应性。Reactivity in Depth。打开dev工具并查看您的内存占用,当我在我的机器上运行您的代码片段时,它是~300mb,而不是codepen示例,它是~20mb。

当您使用console.log(this.scene)时,您看到的是允许Vue跟踪对象的getter/setter。

下面的代码片段将three.js对象从Vue data对象中拉出,并将它们附加到一个vue-static对象。此插件允许您将某些变量设置为非反应性。

代码语言:javascript
复制
<template>
    <div id="container" style="width:100%; height:100vh;"></div>
</template>

<script>
import * as Three from 'three'
import SimplexNoise from'simplex-noise'

export default {
  name: 'ThreeTest',
  static(){
    return {
      scene: new Three.Scene(),
      camera: null,
      renderer: Three.WebGLRenderer,
      mesh: new Three.Mesh,
      noise: SimplexNoise,
      factor:0
    }
  },
  mounted() {
    this.init();
  },
  methods: {
    init: function() {
      this.createScene();
      this.createCamera();
      this.createShape();
      this.addSpotlight('#fdffab');
      this.addAmbientLight();
      this.animate();
      window.addEventListener('resize', this.onResize())
    },
    onResize: function() {
      let container = document.getElementById('container');
      this.renderer.setSize(container.clientWidth, container.clientHeight);
      this.camera.aspect = container.clientWidth / container.clientHeight;
      this.camera.updateProjectionMatrix();
    },
    createScene: function() {

      console.log("TCL: this.$options.bigHairyHorseNuts ",this.bigHairyHorseNuts)

      this.renderer = new Three.WebGLRenderer({
        antialias: true,
        alpha: true
      });
      let container = document.getElementById('container');
      this.renderer.setSize(container.clientWidth, container.clientHeight);
      this.renderer.setPixelRatio(window.devicePixelRatio);
      this.renderer.setClearColor(new Three.Color('#fff'));
      //this.render.shadowMap.type = Three.PCFSoftShadowMap;
      this.noise = new SimplexNoise()
      container.appendChild(this.renderer.domElement);
    },
    createCamera: function() {
      this.camera = new Three.PerspectiveCamera(20, container.clientWidth/container.clientHeight, 1, 1000);
      this.camera.position.set(0, 0, 20);
    },
    createShape: function() {
      const seg = 100
      this.geometry = new Three.PlaneGeometry(5, 8, seg, seg)
      const material = new Three.MeshPhysicalMaterial({
        color: '#da0463',
        metalness: 0.6,
        emissive: '#000',
        side: Three.DoubleSide,
        wireframe: true
      })
      this.mesh = new Three.Mesh(this.geometry, material)
      this.mesh.receiveShadow = true
      this.mesh.castShadow = true
      this.mesh.position.set(0, 0, 0)
      this.mesh.rotation.x = -Math.PI / 3
      this.mesh.rotation.z = -Math.PI / 4
      this.scene.add(this.mesh)
    },
    addSpotlight: function(color) {
      const light = new Three.SpotLight(color, 2, 1000)
      light.position.set(0, 0, 30)
      this.scene.add(light)
    },
    addAmbientLight: function() {
      const light = new Three.AmbientLight('#fff', 0.5)
      this.scene.add(light)
    },
    addjustVertices: function() {
      for (let i = 0; i < this.geometry.vertices.length; i++) {
        const vertex = this.geometry.vertices[i]
        const x = vertex.x / 4
        const y = vertex.y / 6
        vertex.z = this.noise.noise2D(x, y + this.factor)
      }
      this.factor += 0.007
      this.geometry.verticesNeedUpdate = true
      this.geometry.computeVertexNormals()
    },
    animate: function() {
        requestAnimationFrame(this.animate);
        this.addjustVertices();
        this.camera.updateProjectionMatrix();
        this.renderer.render(this.scene, this.camera);
    }
  }
}
</script>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58559139

复制
相关文章

相似问题

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