我正在制作一个简单的动画,其中我必须使平面的高度从100%变为0进行动画处理。平面上具有纹理。我检查了多个示例,无论网格的尺寸如何,都找不到一种使尺寸固定的纹理的方法。
我创建了动画here
的基本示例不能使用它,因为我的背景纹理可能不同(不是黑色)。
经过几个小时的搜索,我发现了这个question(当我自己要发布问题时)。找到了有趣的setUv()
函数。我修改了此函数以制作另一个example。
基本上,我会在每次迭代中放置几何体,并为新的几何体分配新的纹理(比上一个小)。
var group, mesh, geometry, meterial;
var planeHeight, planeWidth;
var UVwr, UVhr;
planeHeight = planeWidth = 3;
UVwr = UVhr = 1.5;
function drawElements(){
group = new THREE.Group();
geometry = new THREE.PlaneGeometry( planeWidth, planeHeight );
var texture = new THREE.Texture( generateTexture() );
texture.needsUpdate = true;
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(1,1);
material = new THREE.MeshBasicMaterial( { map: texture, transparent: true } );
plane = new THREE.Mesh( geometry, material );
var v = plane.geometry.faceVertexUvs[0];
setUv( v, 0, UVwr, UVhr );
group.add( plane );
scene.add( group );
}
/* Plane Geometry */
function setUv( v, index, wr, hr ) {
for (var i=index*2; i<(index+1)*2; i++) {
for (var j=0; j<3; j++) {
v[i][j].x = v[i][j].x * wr;
v[i][j].y = v[i][j].y * hr;
}
}
}
function animate(){
planeHeight -= 0.01;
UVhr -= 0.005;
planeHeight = planeHeight < 0.01 ? 3 : planeHeight;
UVhr = UVhr < 0.005 ? 1.5 : UVhr;
group.children[0].geometry.dispose();
group.children[0].geometry = new THREE.PlaneGeometry( planeWidth, planeHeight );
var v = plane.geometry.faceVertexUvs[0];
setUv( v, 0, UVwr, UVhr );
}
我想知道是否还有其他更好的方法来制作此动画。
也许我们可以使用2个纹理(1.图像纹理和2.透明纹理),然后应用具有偏移量的第二个纹理(透明纹理),然后从底部向上移动该纹理。这样,我们就不必每次都布置几何体。 (只是想知道那是否可能)
谢谢!
答案 0 :(得分:2)
您知道几何的参数,因此可以将其用于计算uv坐标:
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var planeGeom = new THREE.PlaneBufferGeometry(10, 10);
console.log(planeGeom);
var planeMat = new THREE.MeshBasicMaterial({
map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/UV_Grid_Sm.jpg")
});
var plane = new THREE.Mesh(planeGeom, planeMat);
scene.add(plane);
var clock = new THREE.Clock();
var y = 0,
yUv = 0,
h = planeGeom.parameters.height;
renderer.setAnimationLoop(() => {
y = Math.sin(clock.getElapsedTime()) * 2.5 + 2.5;
plane.position.y = y;
planeGeom.attributes.position.setY(0, h * 0.5 - y * 2);
planeGeom.attributes.position.setY(1, h * 0.5 - y * 2);
planeGeom.attributes.position.needsUpdate = true;
yUv = (Math.sin(clock.getElapsedTime()) * h * 0.5 + h * 0.5) / h;
planeGeom.attributes.uv.setY(0, 1 - yUv);
planeGeom.attributes.uv.setY(1, 1 - yUv);
planeGeom.attributes.uv.needsUpdate = true;
renderer.render(scene, camera);
});
body {
overflow: hidden;
margin: 0;
}
<script src="https://threejs.org/build/three.min.js"></script>