是否可以在平面上同时添加两个纹理?还是一个立方体?
我想在平面的上半部分应用一个纹理,在下半部分应用不同的纹理。
这样的事情:
这是我到目前为止设置的
var geometry = new THREE.PlaneGeometry( 2, 2 );
var loader = new THREE.TextureLoader();
var texture = loader.load( 'textures/stone.png');
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 4, 4 );
var material = new THREE.MeshBasicMaterial( { map: texture } );
var mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
答案 0 :(得分:1)
您需要分割几何体,并使用多种材质。
这意味着您将使用PlaneGeometry
的widthSegments
和heightSegments
参数来定义一个只有两个面的平面。这是必要的,因为每张脸只能有一种材料(除非你做了一些非常花哨的混合)。
获得分段平面后,您可以指定每个面的materialIndex
指向单独的材质。
您还将使用材质数组定义网格,而不仅仅是一个 - 每个面的materialIndex
引用材质数组中的索引。
我要做的最后一件事就是调整面部UV和纹理重复/包裹,以达到你想要的效果。
如果您对此主题有其他疑问,请发表评论,我会尝试解决这些问题。
// https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.js
// https://threejs.org/examples/js/controls/TrackballControls.js
/**********************/
/* Initialization */
/**********************/
var renderer = new THREE.WebGLRenderer( {
canvas: document.getElementById( "view" ),
antialias: true,
alpha: true
} );
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 28, 1, 1, 1000 );
camera.position.z = 50;
camera.add( new THREE.PointLight( 0xffffff, 1, Infinity ) );
scene.add( camera );
var controls = new THREE.TrackballControls( camera, renderer.domElement );
controls.addEventListener( "change", render );
/**********************/
/* Populate the Scene */
/**********************/
var texLoader = new THREE.TextureLoader();
var tex1 = texLoader.load( "https://upload.wikimedia.org/wikipedia/commons/2/2b/WallRGB.png", render ); // bricks
var tex2 = texLoader.load( "https://upload.wikimedia.org/wikipedia/commons/6/6f/NGC772_-_SDSS_DR14.png", render ); // space
var mat1 = new THREE.MeshLambertMaterial( { map: tex1 } );
var mat2 = new THREE.MeshLambertMaterial( { map: tex2 } );
// First, segment your geometry however you need it.
// This one is segmented into 1 horizontal segment with 2 vertical segments.
var planeGeo = new THREE.PlaneGeometry( 10, 10, 1, 2 );
// Next you need to set up your faces to use specific materials.
planeGeo.faces[ 0 ].materialIndex = 0;
planeGeo.faces[ 1 ].materialIndex = 0;
planeGeo.faces[ 2 ].materialIndex = 1;
planeGeo.faces[ 3 ].materialIndex = 1;
// You can create a mesh using an array of materials, referenced by materialIndex.
var mesh = new THREE.Mesh( planeGeo, [ mat1, mat2 ] );
scene.add( mesh );
/**********************/
/* Render Function */
/**********************/
function render () {
renderer.render( scene, camera );
}
render();
/**********************/
/* Animation Loop */
/**********************/
function animate () {
requestAnimationFrame( animate );
controls.update();
}
animate();
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1,IE=edge">
<title>TEST</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/89/three.js"></script>
<script src="https://threejs.org/examples/js/controls/TrackballControls.js"></script>
</head>
<body>
<canvas id="view" width="500" height="500" style="border: 1px black solid;"></canvas>
<script src="test.js"></script>
</body>
</html>
答案 1 :(得分:0)
作为@ TheJim01的答案的补充,下面的代码将调整地板几何图形上的UV坐标,以使其平铺:
var tileSize = 24;
var textureSize = 256;
var floorScale = tileSize/textureSize;
floorGeometry.faceVertexUvs.forEach(layer => layer.forEach((face, i) => {
const base = layer[i % 2];
if (i % 2) {
face[0].x = 0;
face[0].y = floorScale;
face[1].x = floorScale;
face[1].y = floorScale;
face[2].x = floorScale;
face[2].y = 0;
} else {
face[0].x = 0;
face[0].y = 0;
face[1].x = 0;
face[1].y = floorScale;
face[2].x = floorScale;
face[2].y = 0;
}
}));