【问题标题】:How to animate in oscillation a N surface in Three.js如何在 Three.js 中对 N 面进行振荡动画
【发布时间】:2020-05-21 07:15:57
【问题描述】:

我想创建一个 NURBS 曲面,使用 Three.js 进行振荡动画。

这是我对 NURBS 的初始化:

this.nsControlPoints = [
      [
        new THREE.Vector4 ( -20, -20, 10, 1 ),
        new THREE.Vector4 ( -20, -10, -20, 1 ),
        new THREE.Vector4 ( -20, 10, 25, 1 ),
        new THREE.Vector4 ( -20, 20, -10, 1 )
      ],
      [
        new THREE.Vector4 ( 0, -20, 0, 1 ),
        new THREE.Vector4 ( 0, -10, -10, 5 ),
        new THREE.Vector4 ( 0, 10, 15, 5 ),
        new THREE.Vector4 ( 0, 20, 0, 1 )
      ],
      [
        new THREE.Vector4 ( 20, -20, -10, 1 ),
        new THREE.Vector4 ( 20, -10, 20, 1 ),
        new THREE.Vector4 ( 20, 10, -25, 1 ),
        new THREE.Vector4 ( 20, 20, 10, 1 )
      ]
    ];
    var degree1 = 2;
    var degree2 = 3;
    var knots1 = [0, 0, 0, 1, 1, 1];
    var knots2 = [0, 0, 0, 0, 1, 1, 1, 1];
    this.nurbsSurface = new NURBSSurface(degree1, degree2, knots1, knots2, this.nsControlPoints);

    var map = new THREE.TextureLoader().load( 'assets/img/tile.jpg' );
    map.wrapS = map.wrapT = THREE.RepeatWrapping;
    map.anisotropy = 16;

    let nurbsSurface = this.nurbsSurface;
    let start = this.start;

    function getSurfacePoint(u, v, target) {

      return nurbsSurface.getPoint(u, v, target);

    }

    this.geometry = new THREE.ParametricBufferGeometry( getSurfacePoint, 20, 20 );
    var material = new THREE.MeshBasicMaterial( { wireframe: true, color: 0x666666, opacity: 1.0 } );
    this.objectSurface = new THREE.Mesh( this.geometry, material );
    this.objectSurface.position.set( - 200, -100, 0 );
    this.objectSurface.rotateX(90);
    this.objectSurface.scale.multiplyScalar( 50 );
    this.scene.add( this.objectSurface );

这就是我试图做的动画:

...
var position = this.geometry.attributes.position;
position.setXYZ(1, position.x + ( Date.now() - this.start ), position.y + ( Date.now() - this.start ), position.z + ( Date.now() - this.start ));

if(position instanceof THREE.BufferAttribute) {
    position.needsUpdate = true;
} else {
    position.data.needsUpdate = true;
}
...
this.renderer.render(this.scene, this.camera);

有什么建议吗?我在互联网上没有找到这个主题的任何解决方案。

提前致谢!!!

【问题讨论】:

    标签: javascript animation three.js surface nurbs


    【解决方案1】:

    以下实时 sn-p 显示您可以变换由 ParametricBufferGeometry 的实例表示的 NURBS 曲面的顶点。请注意如何使用BufferAttribute.setUsage() 来告诉 WebGL 您将要每帧动态更改位置属性。

    动画非常基本,但代码应说明预期的方法。

    var geometry, renderer, scene, camera, controls, clock;
    
    var vertex = new THREE.Vector3();
    
    init();
    animate();
    
    function init() {
    
        // renderer
        renderer = new THREE.WebGLRenderer();
        renderer.setSize( window.innerWidth, window.innerHeight );
        renderer.setPixelRatio( window.devicePixelRatio );
        document.body.appendChild( renderer.domElement );
    
        // scene
        scene = new THREE.Scene();
        
        // camera
        camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
        camera.position.set( 50, 50, 50 );
    
        // controls
        controls = new THREE.OrbitControls( camera, renderer.domElement );
    		
        clock = new THREE.Clock();
        
        // axes
        scene.add( new THREE.AxesHelper( 20 ) );
    
        var nsControlPoints = [
          [
            new THREE.Vector4 ( -20, -20, 10, 1 ),
            new THREE.Vector4 ( -20, -10, -20, 1 ),
            new THREE.Vector4 ( -20, 10, 25, 1 ),
            new THREE.Vector4 ( -20, 20, -10, 1 )
          ],
          [
            new THREE.Vector4 ( 0, -20, 0, 1 ),
            new THREE.Vector4 ( 0, -10, -10, 5 ),
            new THREE.Vector4 ( 0, 10, 15, 5 ),
            new THREE.Vector4 ( 0, 20, 0, 1 )
          ],
          [
            new THREE.Vector4 ( 20, -20, -10, 1 ),
            new THREE.Vector4 ( 20, -10, 20, 1 ),
            new THREE.Vector4 ( 20, 10, -25, 1 ),
            new THREE.Vector4 ( 20, 20, 10, 1 )
          ]
        ];
        var degree1 = 2;
        var degree2 = 3;
        var knots1 = [0, 0, 0, 1, 1, 1];
        var knots2 = [0, 0, 0, 0, 1, 1, 1, 1];
        var nurbsSurface = new THREE.NURBSSurface(degree1, degree2, knots1, knots2, nsControlPoints);
    
        function getSurfacePoint(u, v, target) {
    
                return nurbsSurface.getPoint(u, v, target);
    
        }
    
        geometry = new THREE.ParametricBufferGeometry( getSurfacePoint, 20, 20 );
        var material = new THREE.MeshBasicMaterial( { wireframe: true, color: 0x666666 } );
        var objectSurface = new THREE.Mesh( geometry, material );
        scene.add( objectSurface );
    		
        geometry.attributes.position.setUsage( THREE.DynamicDrawUsage );
    
    }
    
    function animate() {
    
        requestAnimationFrame( animate );
    		
        var elapsedTime = clock.getElapsedTime();
    	
        var position = geometry.attributes.position;
        
        for ( var i = 0; i < position.count; i ++ ) {
    		
    	        var z = position.getZ( i );
    
    	        z += Math.sin( elapsedTime ) * 0.1;
    			
    	        position.setZ( i, z );
    		
        }
    		
        position.needsUpdate = true;
    
        renderer.render( scene, camera );
    
    }
    <script src="https://rawcdn.githack.com/mrdoob/three.js/r113/build/three.js"></script>
    <script src="https://rawcdn.githack.com/mrdoob/three.js/r113/examples/js/controls/OrbitControls.js"></script>
    <script src="https://rawcdn.githack.com/mrdoob/three.js/r113/examples/js/curves/NURBSUtils.js"></script>
    <script src="https://rawcdn.githack.com/mrdoob/three.js/r113/examples/js/curves/NURBSSurface.js"></script>

    【讨论】:

    • 感谢您的回答 Mugen87。但我想像波涛汹涌的大海一样摆动,不改变绝对位置,只改变顶点。
    • 如果你仔细研究代码,你会看到顶点是动画的。不是 3D 对象本身。波浪效果的风格当然取决于你的用例。
    猜你喜欢
    • 2012-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-08-14
    • 2021-05-18
    • 1970-01-01
    • 2014-06-25
    • 1970-01-01
    相关资源
    最近更新 更多