I am using three.js and I want to create geometry 16x16 size. I want that each segment is different color and some of them is transparent. What is the best solution for this problem? Should i render each pixel as a single plane geometry? Or there is possible way to change single segment color/transparency.
I suggest you an instance of PlaneGeometry
, transform it to a so called non-indexed geometry and then add an additional color buffer attribute. Full example:
let camera, scene, renderer;
init();
render();
function init() {
camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.01, 10);
camera.position.z = 1;
scene = new THREE.Scene();
// background
const canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = canvas.height = 128;
ctx.fillStyle = '#ddd';
ctx.fillRect(0, 0, 128, 128);
ctx.fillStyle = '#555';
ctx.fillRect(0, 0, 64, 64);
ctx.fillStyle = '#999';
ctx.fillRect(32, 32, 32, 32);
ctx.fillStyle = '#555';
ctx.fillRect(64, 64, 64, 64);
ctx.fillStyle = '#777';
ctx.fillRect(96, 96, 32, 32);
mapBg = new THREE.CanvasTexture(canvas);
mapBg.wrapS = mapBg.wrapT = THREE.RepeatWrapping;
mapBg.repeat.set(64, 32);
scene.background = mapBg;
// plane mesh
const geometry = new THREE.PlaneGeometry(1, 1, 10, 10).toNonIndexed();
const positionAttribute = geometry.getAttribute('position');
const colors = [];
const color = new THREE.Color();
for (let i = 0; i < positionAttribute.count; i += 6) {
color.setRGB(Math.random(), Math.random(), Math.random());
const alpha = Math.random();
colors.push(color.r, color.g, color.b, alpha);
colors.push(color.r, color.g, color.b, alpha);
colors.push(color.r, color.g, color.b, alpha);
colors.push(color.r, color.g, color.b, alpha);
colors.push(color.r, color.g, color.b, alpha);
colors.push(color.r, color.g, color.b, alpha);
}
geometry.setAttribute('color', new THREE.Float32BufferAttribute(colors, 4));
const material = new THREE.MeshBasicMaterial({
vertexColors: true,
transparent: true
});
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);
//
renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function render() {
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdn.jsdelivr.net/npm/three@0.141/build/three.min.js"></script>