在 Three.js 纹理上保持方面 [英] Maintain aspect on Three.js texture

查看:47
本文介绍了在 Three.js 纹理上保持方面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当纹理显示在不同大小的框中时,我试图保持纹理居中.

我看过这个答案

在这方面的值是

图片:{width:399 height:275}纹理:{宽:1,高:0.75}

在这方面的值是

图片:{width:399 height:275}纹理:{宽:2,高:1}

如何修复它以使图形始终居中、保持外观且不失真?

解决方案

我希望我没听错,这里有一个关于如何将其居中的选项:

var scene = new THREE.Scene();var camera = new THREE.PerspectiveCamera(60, innerWidth/innerHeight, 1, 1000);相机位置设置(0, 0, 10);var renderer = new THREE.WebGLRenderer();renderer.setSize(innerWidth,innerHeight);document.body.appendChild(renderer.domElement);var planeGeom = new THREE.PlaneBufferGeometry(16, 9);var planeMat = new THREE.MeshBasicMaterial({地图:新的 THREE.TextureLoader().load("https://threejs.org/examples/textures/758px-Canestra_di_frutta_(Caravaggio).jpg", tex => {//console.log(tex);//console.log(tex.image.width, tex.image.height);让 imgRatio = tex.image.width/tex.image.height;让planeRatio = planeGeom.parameters.width/planeGeom.parameters.height;//console.log(imgRatio, planeRatio);tex.wrapS = THREE.RepeatWrapping;//THREE.ClampToEdgeWrapping;tex.repeat.x = 平面比例/图像比例;tex.offset.x = -0.5 * ((planeRatio/imgRatio) - 1);})});var plane = new THREE.Mesh(planeGeom,planeMat);场景.添加(平面);renderer.setAnimationLoop(() => {renderer.render(场景,相机);})

body {溢出:隐藏;边距:0;}

<script src="https://threejs.org/build/three.min.js"></script>

附加:如何为 ShapeBufferGeometry 重新计算 UV

var box = new THREE.Box3().setFromObject(mesh);//使用 ShapeBufferGeometry 进行网格划分var size = new THREE.Vector3();box.getSize(size);var vec3 = new THREE.Vector3();//温度向量var attPos = mesh.geometry.attributes.position;var attUv = mesh.geometry.attributes.uv;for (让 i = 0; i < attPos.count; i++){vec3.fromBufferAttribute(attPos, i);attUv.setXY(i,(vec3.x - box.min.x)/size.x,(vec3.y - box.min.y)/size.y);}attUv.needsUpdate = true;//以防万一

I'm trying to keep a texture centered when it's shown in a different sized box.

I've seen this answer

Three.js: Make image texture fit object without distorting or repeating

But it's not quite doing it for me.

  this.texture = new THREE.Texture(this.image)
  const vec = new THREE.Vector3()
  new THREE.Box3().setFromObject( this.rounded ).getSize(vec)
  const imageAspect = this.image.width/this.image.height
  const boxAspect = vec.x/vec.y

  this.texture.wrapT = THREE.RepeatWrapping;
  this.texture.offset.y =  0.5 * ( 1 - boxAspect/imageAspect )

  //texture.wrapT = THREE.RepeatWrapping; texture.repeat.x = geometryAspectRatio / imageAspectRatio; texture.offset.x = 0.5 * ( 1 - texture.repeat.x )

  this.texture.needsUpdate = true 
  this.rounded.material = new THREE.MeshPhongMaterial( { map: this.texture, side: THREE.DoubleSide } ) 

In this aspect the values are

Image: {width:399  height:275}
Texture: {width:1, height: 0.75}

In this aspect the values are

Image: {width:399  height:275}
Texture: {width:2, height: 1}

How do I fix it so the graphic is always central, maintains the aspect and is not distorted?

解决方案

I hope I got you correctly, here is an option of how you can center it:

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 0, 10);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);

var planeGeom = new THREE.PlaneBufferGeometry(16, 9);
var planeMat = new THREE.MeshBasicMaterial({
  map: new THREE.TextureLoader().load("https://threejs.org/examples/textures/758px-Canestra_di_frutta_(Caravaggio).jpg", tex => {
    //console.log(tex);
    //console.log(tex.image.width, tex.image.height);
    let imgRatio = tex.image.width / tex.image.height;
    let planeRatio = planeGeom.parameters.width / planeGeom.parameters.height;
    //console.log(imgRatio, planeRatio);
    tex.wrapS = THREE.RepeatWrapping; // THREE.ClampToEdgeWrapping;
    tex.repeat.x = planeRatio / imgRatio;
    tex.offset.x = -0.5 * ((planeRatio / imgRatio) - 1);
  })
});
var plane = new THREE.Mesh(planeGeom, planeMat);
scene.add(plane);

renderer.setAnimationLoop(() => {
  renderer.render(scene, camera);
})

body {
  overflow: hidden;
  margin: 0;
}

<script src="https://threejs.org/build/three.min.js"></script>

Addition: how to re-compute UVs for ShapeBufferGeometry

var box = new THREE.Box3().setFromObject(mesh); // mesh with ShapeBufferGeometry
var size = new THREE.Vector3();
box.getSize(size);
var vec3 = new THREE.Vector3(); // temp vector
var attPos = mesh.geometry.attributes.position;
var attUv = mesh.geometry.attributes.uv;
for (let i = 0; i < attPos.count; i++){
    vec3.fromBufferAttribute(attPos, i);
    attUv.setXY(i,
    (vec3.x - box.min.x) / size.x,
    (vec3.y - box.min.y) / size.y
  );
}
attUv.needsUpdate = true; // just in case

这篇关于在 Three.js 纹理上保持方面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆