如何在 Three.js 中为 N 表面的振荡设置动画
How to animate in oscillation a N surface in Three.js
我想创建一个带有 Three.js 振荡动画的 NURBS 曲面。
这是我对 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);
有什么建议吗?我没有在互联网上找到任何与此主题相关的解决方案。
提前致谢!!!
以下实时片段显示您可以变换由 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>
我想创建一个带有 Three.js 振荡动画的 NURBS 曲面。
这是我对 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);
有什么建议吗?我没有在互联网上找到任何与此主题相关的解决方案。
提前致谢!!!
以下实时片段显示您可以变换由 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>