平面几何,每段颜色不同,部分透明
Plane geometry, each segment different color, some of them transparent
我正在使用 three.js,我想创建 16x16 尺寸的几何图形。我希望每一段都是不同的颜色,其中一些是透明的。这个问题的最佳解决方案是什么?
我应该将每个像素渲染为一个平面几何体吗?或者有可能改变单个段 color/transparency.
Desired result
我建议您使用 PlaneGeometry
的实例,将其转换为所谓的 non-indexed 几何体,然后添加一个额外的颜色缓冲属性。完整示例:
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>
我正在使用 three.js,我想创建 16x16 尺寸的几何图形。我希望每一段都是不同的颜色,其中一些是透明的。这个问题的最佳解决方案是什么? 我应该将每个像素渲染为一个平面几何体吗?或者有可能改变单个段 color/transparency.
Desired result
我建议您使用 PlaneGeometry
的实例,将其转换为所谓的 non-indexed 几何体,然后添加一个额外的颜色缓冲属性。完整示例:
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>