You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ThreeJS中使用OBJLoader加载3D模型后无法实现顶点动画的问题

Alright, let's figure out why your vertex animation isn't working with that OBJ model in Three.js. I spot a few common pitfalls in your code snippet—let's break them down and fix this step by step.

Fixing Vertex Animation for Your OBJ Model in Three.js

First, let's address the core issues with your current approach:

1. You're using outdated Geometry properties with BufferGeometry

OBJLoader in modern Three.js (r125+) loads models using BufferGeometry by default, not the old Geometry type. The verticesNeedUpdate property only applies to the deprecated Geometry—for BufferGeometry, you need to work with attribute arrays instead.

2. You're not updating vertices in an animation loop

Setting verticesNeedUpdate once during model load won't trigger ongoing animation. Vertex changes need to be recalculated every frame in your render loop.

3. Missing checks for Mesh objects

Your traverse call might hit non-Mesh objects (like groups), so you should verify the child is a Mesh before modifying geometry.

Here's the corrected implementation:

var loader = new THREE.OBJLoader();
// Store original vertex data to avoid animation drift
let originalPositions = null;

loader.load('assets/models/head/lee-perry-smith-head-scan.obj', function (object) {
    var faceMaterial = getMaterial('standard', 'rgb(255,200,200)');
    
    object.traverse(function(child) {
        // Target only Mesh objects with the correct name
        if (child.isMesh && child.name === 'Infinite') {
            child.material = faceMaterial;
            // Save original vertex positions (clone the array to preserve defaults)
            originalPositions = child.geometry.attributes.position.array.slice();
        }
    });

    scene.add(object);
});

// Add this animation loop (replace with your existing render loop if you have one)
function animate() {
    requestAnimationFrame(animate);

    // Update vertices every frame
    scene.traverse(function(child) {
        if (child.isMesh && child.name === 'Infinite' && originalPositions) {
            const positionAttribute = child.geometry.attributes.position;
            const positions = positionAttribute.array;

            // Example animation: sine wave distortion on Y-axis
            const time = Date.now() * 0.001;
            for (let i = 0; i < positions.length; i += 3) {
                const originalY = originalPositions[i + 1];
                // Modify Y position based on time and X coordinate for a wave effect
                positions[i + 1] = originalY + Math.sin(time + originalPositions[i] * 0.1) * 0.5;
            }

            // Tell Three.js the position data has changed
            positionAttribute.needsUpdate = true;
        }
    });

    renderer.render(scene, camera);
}

animate();

Key fixes explained:

  • BufferAttribute instead of vertices: We use child.geometry.attributes.position to access vertex data, which is the correct approach for modern Three.js.
  • Original vertex storage: Saving initial positions prevents animation drift (we don't overwrite the base data every frame).
  • Animation loop updates: Vertex modifications happen inside the animate function, so they refresh every frame to create smooth motion.
  • needsUpdate flag: Setting positionAttribute.needsUpdate = true after modifying the array tells Three.js to re-render the updated geometry.
  • Mesh type check: Added child.isMesh to avoid errors when traversing non-Mesh objects like empty groups.

If you're still stuck, double-check:

  • That the child object's name is exactly 'Infinite' (case-sensitive!)
  • That your getMaterial function returns a valid THREE.Material instance
  • That your animation loop is actually running and calling renderer.render() every frame

内容的提问来源于stack exchange,提问作者Zain Bokhari

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 10:05:36