THREE.js 图片宽高比例

3

我在尝试如何根据图像大小将PlaneGeometry设置为良好的长宽比方面遇到了困难。

var material = new THREE.MeshBasicMaterial({
        map : THREE.ImageUtils.loadTexture('img/bunny.png')
});
var plane = new THREE.Mesh(new THREE.PlaneGeometry(20, 20*.75), material);
plane.position.set(0, 10, -60)
scene.add(plane);

到目前为止我尝试过的方法似乎有用,但是我意识到我仍然在Plane上设置了固定的宽度/高度。

我希望Plane可以根据图片大小来自适应,这样我就可以将其缩小。

2个回答

7
var planeGeom = new THREE.PlaneGeometry(20, 20);
var imgSrc = "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"
var mesh;
var tex = new THREE.TextureLoader().load(imgSrc, (tex) => {
  tex.needsUpdate = true;
  mesh.scale.set(1.0, tex.image.height / tex.image.width, 1.0);
});

var material = new THREE.MeshLambertMaterial({
  color: 0xffffff,
  map: tex
});
mesh = new THREE.Mesh(planeGeom, material);
scene.add(mesh);

//Working snippet is below...

var renderer = new THREE.WebGLRenderer();
var w = 300;
var h = 200;
renderer.setSize(w, h);
document.body.appendChild(renderer.domElement);

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(
  45, // Field of view
  w / h, // Aspect ratio
  0.1, // Near
  10000 // Far
);
camera.position.set(15, 10, 15);
camera.lookAt(scene.position);
controls = new THREE.OrbitControls(camera, renderer.domElement);

var light = new THREE.PointLight(0xFFFFFF);
light.position.set(20, 20, 20);
scene.add(light);
var light1 = new THREE.AmbientLight(0x808080);
light1.position.set(20, 20, 20);
scene.add(light1);

var planeGeom = new THREE.PlaneGeometry(20, 20);
var imgSrc = "https://upload.wikimedia.org/wikipedia/commons/5/5f/BBB-Bunny.png"
var mesh;
var tex = new THREE.TextureLoader().load(imgSrc, (tex) => {
  tex.needsUpdate = true;
  mesh.scale.set(1.0, tex.image.height / tex.image.width, 1.0);
});

var material = new THREE.MeshLambertMaterial({
  color: 0xffffff,
  map: tex
});
mesh = new THREE.Mesh(planeGeom, material);
scene.add(mesh);
renderer.setClearColor(0xdddddd, 1);


(function animate() {
  requestAnimationFrame(animate);
  controls.update();
  renderer.render(scene, camera);
})();
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>


谢谢,明白它的方向。然而图片在宽度上似乎缩小了一点...基本上兔子的脸变得更瘦了。 - anon
1
我已经寻找这个解决方案一年多了。非常感谢。 - Megan Byers

0

被接受的答案是有效的,但必须使用回调函数来设置宽度,因为加载器是异步的。现在,人们也可以使用{{link1:loadAsync}}方法,我认为这使代码更易读:

const getImageRatioPlane = async () => {
    const texture = await new TextureLoader().loadAsync(imgSrc);
    const material = new MeshBasicMaterial({ map: texture });
    const geometry = new PlaneGeometry(texture.image.width, texture.image.height);

    const plane = new Mesh(geometry, material);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接