[英]Why is my Three.js animation slower in Vue.js?
我正在尝试在 Vue.js 中重新创建这个很棒的波浪模拟: https: //codepen.io/cheekymonkey/pen/vMvYNV。 但是,当我在 Vue.js 中重新创建 animation 时,它真的很慢
我尝试制作与 Vue.js 方法相同的所有功能,并将变量包含在组件的数据属性中。
<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 或者我是如何设置的。 非常感谢任何建议!
发生这种情况是因为 Vue 在后台使每个附加到实例的组件都具有反应性。 深度反应。 打开开发工具并查看您的 memory 足迹,当我在我的机器上运行您的代码片段时,它约为 300mb,而 codepen 示例约为 20mb。
当您使用console.log(this.scene)
时,您看到的是允许 Vue 跟踪对象的 getter/setter。
下面的代码片段将 three.js 对象从 Vue 数据 object 中提取出来,并将它们附加到vue 静态object 中。 此插件允许您将某些变量设置为非反应性。
<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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.