Reputation: 463
I have tried a lot but still can't solve this..
How can I render a tetrahedron with different texture on each face?
At beginning I was trying this way.
import * as THREE from 'three';
window.onload = () => {
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
const renderer = new THREE.WebGLRenderer({ antialias: true })
renderer.setSize(window.innerWidth, window.innerHeight)
document.body.appendChild(renderer.domElement)
var geometry = new THREE.CylinderGeometry(0, 2, 3, 3, 3, false)
var materials = [
new THREE.MeshBasicMaterial({ color: 0xff00ff }),
new THREE.MeshBasicMaterial({ color: 0xff0000 }),
new THREE.MeshBasicMaterial({ color: 0x0000ff }),
new THREE.MeshBasicMaterial({ color: 0x5100ff })
]
var tetra = new THREE.Mesh(geometry, materials)
scene.add(tetra)
renderer.render(scene, camera)
camera.position.z = 5;
var ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(ambientLight)
function animate() {
requestAnimationFrame(animate)
tetra.rotation.x += 0.04;
tetra.rotation.y += 0.04;
renderer.render(scene, camera)
}
animate()
}
I use a cylinder geometry to "make" a fake tetrahedron.
But I found that I can't texturing each face of this "tetrahedron", bc cylinder geometry actually have only 3 faces.
Does anyone know how to do it?
P.S. I have also tried TetrahedronGeometry but it just didn't work, I guessed it was because TetrahedronGeometry is basically BufferGeometry and there are no faces property on it.
Upvotes: 1
Views: 378
Reputation: 463
Finally I understood how to make it work using three.js
TetrahedronGeometry
.
Actually making our own geo is not necessary, but we will have to reset uv array
if we are using three.js
TetrahedronGeometry
.
private initGeometry(){
const radius = this.config.size*Math.sqrt(6)/4;
this.geometry = new THREE.TetrahedronGeometry(radius,0);
console.log(this.geometry.attributes.uv.array);
this.geometry.addGroup(0, 3, 0);
this.geometry.addGroup(3, 3, 1);
this.geometry.addGroup(6, 3, 2);
this.geometry.addGroup(9, 3, 3);
this.geometry.setAttribute("uv", new THREE.Float32BufferAttribute([ // UVs,
//numbers here are to describe uv coordinate, so they are actually customizable
// if you want to customize it, you have to check the vertices position array first.
0,0,
1, 0,
0.5, 1,
//
1, 0,
0.5, 1,
0,0,
//
1, 0,
0.5, 1,
0,0,
//
0,0,
1, 0,
0.5, 1
], 2));
this.geometry.rotateY(-Math.PI);
}
Upvotes: 1
Reputation: 17596
You can build your own geometry or modify an existing one. To have different materials on sides, use groups
.
body{
overflow: hidden;
margin: 0;
}
<script type="module">
import * as THREE from "https://cdn.skypack.dev/[email protected]";
import {OrbitControls} from "https://cdn.skypack.dev/[email protected]/examples/jsm/controls/OrbitControls"
let scene = new THREE.Scene();
let camera = new THREE.PerspectiveCamera(60, innerWidth / innerHeight, 1, 1000);
camera.position.set(0, 5, 10).setLength(3);
let renderer = new THREE.WebGLRenderer();
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener("resize", event => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
rendrer.setSize(innerWidth, innerHeight);
})
let controls = new OrbitControls(camera, renderer.domElement);
// https://discourse.threejs.org/t/tetrahedron-non-indexed-buffer-geometry/12542
// tetrahedron
// ---------------------------------------------------------------------------------------
var pts = [ // https://en.wikipedia.org/wiki/Tetrahedron#Coordinates_for_a_regular_tetrahedron
new THREE.Vector3(Math.sqrt(8 / 9), 0, -(1 / 3)),
new THREE.Vector3(-Math.sqrt(2 / 9), Math.sqrt(2 / 3), -(1 / 3)),
new THREE.Vector3(-Math.sqrt(2 / 9), -Math.sqrt(2 / 3), -(1 / 3)),
new THREE.Vector3(0, 0, 1)
];
var faces = [ // triangle soup
pts[0].clone(), pts[2].clone(), pts[1].clone(),
pts[0].clone(), pts[1].clone(), pts[3].clone(),
pts[1].clone(), pts[2].clone(), pts[3].clone(),
pts[2].clone(), pts[0].clone(), pts[3].clone()
];
var geom = new THREE.BufferGeometry().setFromPoints(faces);
geom.rotateX(-Math.PI * 0.5);
geom.computeVertexNormals();
geom.setAttribute("uv", new THREE.Float32BufferAttribute([ // UVs
0.5, 1, 0.06698729810778059, 0.2500000000000001, 0.9330127018922194, 0.2500000000000001,
0.06698729810778059, 0.2500000000000001, 0.9330127018922194, 0.2500000000000001, 0.5, 1,
0.06698729810778059, 0.2500000000000001, 0.9330127018922194, 0.2500000000000001, 0.5, 1,
0.06698729810778059, 0.2500000000000001, 0.9330127018922194, 0.2500000000000001, 0.5, 1
], 2));
geom.addGroup(0, 3, 0);
geom.addGroup(3, 3, 1);
geom.addGroup(6, 3, 2);
geom.addGroup(9, 3, 3);
// ---------------------------------------------------------------------------------------
let tl = new THREE.TextureLoader();
let tp = "https://threejs.org/examples/textures/";
let tetra = new THREE.Mesh(geom, [
new THREE.MeshBasicMaterial({map: tl.load(tp + "uv_grid_opengl.jpg")}),
new THREE.MeshBasicMaterial({map: tl.load(tp + "colors.png")}),
new THREE.MeshBasicMaterial({map: tl.load(tp + "brick_diffuse.jpg")}),
new THREE.MeshBasicMaterial({map: tl.load(tp + "758px-Canestra_di_frutta_(Caravaggio).jpg")})
])
scene.add(tetra);
renderer.setAnimationLoop(()=> {
renderer.render(scene, camera);
});
</script>
Upvotes: 2