gpt4 book ai didi

javascript - 三个 : PlaneGeometry load texture to specific faces

转载 作者:行者123 更新时间:2023-11-30 09:27:36 26 4
gpt4 key购买 nike

是否可以将纹理加载到 PlaneGeometry 对象的特定面?我想要做的是将单独的纹理映射到 PlaneGeometry 对象的特定 2 个三 Angular 形。

这里有一些例子,用一些颜色给 PlaneGeometry 对象的每 2 个三 Angular 形上色并且它有效:

<!DOCTYPE html>
<html lang="en">
<head>
<title>title</title>
<meta charset="utf-8">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>

<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
<script>

var camera, scene, renderer, geometry, material, mesh;

init();
animate();

function init() {

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);

// geometry
var thumbnail_width = 32;
var thumbnail_height = 32;
var width_segments = 10;
var height_segments = 10;
var plane_geometry_width = width_segments * thumbnail_width;
var plane_geometry_height = height_segments * thumbnail_height;
var geometry = new THREE.PlaneGeometry(plane_geometry_width, plane_geometry_height, width_segments, height_segments); // faces.length = widthSegments*heightSegments*2

//Draw grid with static colors
// materials
var materials = [];
materials.push(new THREE.MeshBasicMaterial({
color: 0xff0000, side:THREE.DoubleSide
}));
materials.push(new THREE.MeshBasicMaterial({
color: 0x00ff00, side:THREE.DoubleSide
}));
materials.push(new THREE.MeshBasicMaterial({
color: 0x0000ff, side:THREE.DoubleSide
}));
// Add materialIndex to face
var l = geometry.faces.length / 2;
for (var i = 0; i < l; i++) {
var j = 2 * i;
geometry.faces[j].materialIndex = i % 3;
geometry.faces[j + 1].materialIndex = i % 3;
}

// mesh
mesh = new THREE.Mesh(geometry, materials);
scene.add(mesh);

// WebGL renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}

function animate() {
requestAnimationFrame(animate);
render();
}

function render() {
renderer.render(scene, camera);
}

</script>
</body>

结果如下: enter image description here

但是,当我尝试以相同方式映射纹理时,它映射到所有三 Angular 形,这不是我想要的:

<!DOCTYPE html>
<html lang="en">
<head>
<title>title</title>
<meta charset="utf-8">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>

<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/87/three.min.js"></script>
<script>

var camera, scene, renderer, geometry, material, mesh;

init();
animate();

function init() {

scene = new THREE.Scene();

camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 500;
scene.add(camera);

// geometry
var thumbnail_width = 32;
var thumbnail_height = 32;
var width_segments = 10;
var height_segments = 10;
var plane_geometry_width = width_segments * thumbnail_width;
var plane_geometry_height = height_segments * thumbnail_height;
var geometry = new THREE.PlaneGeometry(plane_geometry_width, plane_geometry_height, width_segments, height_segments); // faces.length = widthSegments*heightSegments*2

var texture = new THREE.TextureLoader().load("image_small/item_1.png")

var materials = [];
materials.push(new THREE.MeshBasicMaterial({map : texture, side: THREE.DoubleSide}));
materials.push(new THREE.MeshBasicMaterial({color: 0xff0000, side:THREE.DoubleSide}));
materials.push(new THREE.MeshBasicMaterial({color: 0x00ff00, side:THREE.DoubleSide}));

// Add materialIndex to face
var l = geometry.faces.length / 2;
for (var i = 0; i < l; i++) {
var j = 2 * i;
geometry.faces[j].materialIndex = i % 3;
geometry.faces[j + 1].materialIndex = i % 3;
}

// mesh
mesh = new THREE.Mesh(geometry, materials);
scene.add(mesh);

// WebGL renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}

function animate() {
requestAnimationFrame(animate);
render();
}

function render() {
renderer.render(scene, camera);
}

</script>
</body>

结果如下: enter image description here

更新:

@WestLangley 建议的第二种解决方案的部分代码

    var texture = new THREE.TextureLoader().load("image_small/item_1.png")
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 10, 10 );
var materials = [];
materials.push(new THREE.MeshBasicMaterial({map : texture, side: THREE.DoubleSide}));
materials.push(new THREE.MeshBasicMaterial({color: 0xff0000, side:THREE.DoubleSide}));
materials.push(new THREE.MeshBasicMaterial({color: 0x00ff00, side:THREE.DoubleSide}));
// Add materialIndex to face
var l = geometry.faces.length / 2;
for (var i = 0; i < l; i++) {
var j = 2 * i;
geometry.faces[j].materialIndex = i % 3;
geometry.faces[j + 1].materialIndex = i % 3;
}
geometry.sortFacesByMaterialIndex();
// Mesh
mesh = new THREE.Mesh(geometry, materials);
scene.add(mesh);
// WebGL renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

结果: enter image description here

更新 2:

    var texture = new THREE.TextureLoader().load("image_small/item_1.png")
texture.flipY = true
var materials = [];
materials.push(new THREE.MeshBasicMaterial({map : texture, side: THREE.DoubleSide}));
for (var i = 0; i < geometry.faces.length; i++) {
geometry.faces[i].materialIndex = 0;
}
var uvs = geometry.faceVertexUvs[ 0 ]; // widthSegments*heightSegments*2

//UV
// (0,1) (1,1)
// (0,0) (1,0)
// For THREE.PlaneGeometry, UV ( 0, 0 ) is located at the bottom left, and ( 1, 1 ) the top right.
for (var i = 0; i < uvs.length; i++) {
if(i % 2 == 0)
{
// (0,1)[2] x
// (0,0)[1] (1,0)[3]
uvs[i][0].x = 0.0;
uvs[i][0].y = 0.0;
uvs[i][1].x = 0.0;
uvs[i][1].y = 1.0;
uvs[i][2].x = 1.0;
uvs[i][2].y = 0.0;

}
else
{
// (0,1)[1] (1,1)[2]
// x (1,0)[3]
uvs[i][0].x = 0.0;
uvs[i][0].y = 1.0;
uvs[i][1].x = 1.0;
uvs[i][1].y = 1.0;
uvs[i][2].x = 1.0;
uvs[i][2].y = 0.0;

}
}

var mesh = new THREE.Mesh(geometry, materials);
scene.add(mesh);
// WebGL renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

结果: enter image description here

最佳答案

你有两个选择。

一种是更改几何体的 UV,使每个正方形的 UV 范围从 ( 0, 0 ) 左下角到 ( 1, 1 ) 右上角。

另一个解决方案是设置纹理的repeat:

texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 10, 10 );

顺便说一句,在控制台中输入 renderer.info,您会看到生成了 100 个绘制调用。

设置 Material 索引后,将以下内容添加到您的代码中:

geometry.sortFacesByMaterialIndex();

您现在应该只看到 3 个绘制调用。

three.js r.89

关于javascript - 三个 : PlaneGeometry load texture to specific faces,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48385258/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com