[英]ThreeJS different shapes object texture not working true
我在threejs上使用动态纹理。 当我使用不同形状的 object 时,纹理无法正常工作。 但是,当我使用 boxGeometry 时,它工作正常。
setCanvas =()=>{
this.canvas = window.document.getElementById("canvas");
var ctx = this.canvas.getContext("2d");
ctx.font = "20pt Arial";
ctx.fillStyle = "red";
ctx.fillRect(0, 0, this.canvas.width, this.canvas.height);
ctx.fillStyle = "white";
ctx.fillRect(10, 10, this.canvas.width - 20, this.canvas.height - 20);
ctx.fillStyle = "yellow";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText("asdasdasd", this.canvas.width / 2, this.canvas.height / 2);
}
不同形状 object 创建者
threeObjectCreator(mesh, position, color) {
const object = this.objectLoader.parse(mesh);
object.position.set(position.x, position.z, position.y);
object.rotation.x = Math.PI / 2;
let texture = new THREE.Texture(this.canvas);
object.material = new THREE.MeshPhongMaterial({
color,
side: THREE.DoubleSide,
shininess: 30,
//flatShading: THREE.FlatShading,
transparent: false,
map:texture
});
texture.needsUpdate = true;
return object;
}
带盒几何
let geometry = new THREE.BoxGeometry( 200, 200, 200 );
let mesh = new THREE.Mesh(geometry, material);
this.scene.add(mesh);
我怎么解决这个问题?
在 OpenGL(ThreeJS 通过 WebGL 使用纹理)中使用纹理时,正确设置面部的 UV 参数非常重要。
这些 UV 参数告诉如何将 2d 纹理变形和转换到 3d 空间。
让我们看看我们的简单盒子 model 上的 UV 参数( new THREE.BoxGeometry()
):
[[
[{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}],
[{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}],
[{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}],
[{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}],
[{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}],
[{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}],
[{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}],
[{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}],
[{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}],
[{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}],
[{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}],
[{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}]
]]
这看起来很吓人
要理解这些坐标,您必须了解我们的盒子由 12 个“面”或三角形组成,在这种情况下,每边 2 个三角形。
当我们修改 UV 网格中的 1 个坐标时会发生有趣的事情:
var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement ); var geometry = new THREE.BoxGeometry( 3,3,3 ); var material = new THREE.MeshBasicMaterial( { color: 0xffffff } ); new THREE.TextureLoader().load( "https://threejs.org/examples/textures/uv_grid_opengl.jpg", (texture) => { material.map = texture; renderer.render( scene, camera ); }); geometry.faceVertexUvs = [[ [{"x":0,"y":1},{"x":0,"y":-1},{"x":2,"y":1}], [{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}], [{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}], [{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}], [{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}], [{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}], [{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}], [{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}], [{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}], [{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}], [{"x":0,"y":1},{"x":0,"y":0},{"x":1,"y":1}], [{"x":0,"y":0},{"x":1,"y":0},{"x":1,"y":1}] ]] var cube = new THREE.Mesh( geometry, material ); cube.rotation.x = Math.PI / 3 cube.rotation.y = 0 cube.rotation.z = Math.PI / 3 scene.add( cube ); camera.position.z = 5;
body { margin: 0; font-size: 0; } canvas { width: 100%; height: 100% }
<script src="https://threejs.org/build/three.js"></script>
注意纹理是如何变化的? 这就是 UV 坐标如何帮助您将 2d 纹理应用到任何 3d 表面。 (尝试同时使用Texture.wrapS )
目前,在您的代码中,您正在从外部源加载对象,很可能是 OBJ 文件(基于您使用 ObjectLoader 的事实),并且由于不存在 MAT 文件,因此不存在信息关于材料的特性。
这意味着您尝试渲染到屏幕的对象没有任何“纹理坐标”,我们需要以某种方式“提供”这些信息。
虽然可以手工制作这些数据,但这并不总是那么可销售,所以我们不得不回退到另一个替代方案,根据项目的 position 生成这些数据。
生成 UV 坐标是一个复杂的话题,因为有许多不同的映射,我建议您找到并使用“THREE.js 生成 UV 坐标 - StackOverflow”中的解决方案之一。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.