1

我想创建一个 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);

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

提前致谢!!!

4

1 回答 1

2

以下实时代码段显示您可以变换由 的实例表示的 NURBS 曲面的顶点ParametricBufferGeometry。请注意如何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>

于 2020-02-05T14:33:18.910 回答