작성
·
240
0
답변 1
0
말씀대로 three.js 특정 버전 이후부터 faces 속성 자체가 없어진 것으로 알고 있습니다. 퍼포먼스 이유였다고 본 것 같은데 정확히 모르겠네요^^; 결국 각 Vertex들을 컨트롤 해야하는데, 다루기가 복잡해서 차라리 CanvasTexture를 이용해서 하는 방법이 어떨까 싶습니다.
(참고로 VertexColors를 컨트롤 하는 부분은 Particle 섹션에 다루는 부분이 있습니다)
여러개의 Material을 적용하는 큐브를 만들고, 각 면에 CanvasTexture를 적용하는 거라고 생각하시면 될 것 같습니다. Material 섹션을 학습하셨다면 아마 두 개념 모두 알고 계실 것 같아요~
이런걸 말씀하신건지 모르겠지만, 질문하신 걸 보고 만들어두면 저도 쓸 일이 있을 것 같아서, 겸사겸사 한번 만들어 봤습니다. 여기에 조금 기능을 붙여서, 강의에 보너스 콘텐츠로 추가 해도 좋을 것 같다는 생각이 드네요^^
값이 클 수록 초록색이 밝게 보이도록 해보았는데요, 그라데이션으로 색상 처리하는 부분을 원하시는 형태로 수정해보시면 될 것 같습니다.
일단 소스코드 공유해 드릴게요-
ex01.js 이런 것 처럼 똑같이 추가해서 같은 방식으로 실행해보시면 됩니다.
아, 참고로 vertexColors를 활용한 큐브 예제는 찾아보니 이런게 있네요.
https://jsfiddle.net/vptec390/2/
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
// ----- 주제: 여러 개의 CanvasTexture로 막대 그래프 만들어 보기
export default function example() {
// Renderer
const canvas = document.querySelector('#three-canvas');
const renderer = new THREE.WebGLRenderer({
canvas,
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1);
// Scene
const scene = new THREE.Scene();
scene.background = new THREE.Color('white');
// Camera
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
scene.add(camera);
// Controls
const controls = new OrbitControls(camera, renderer.domElement);
const barGroup = new THREE.Group();
scene.add(barGroup);
// 샘플 값
const values = [4, 2.5, 7, 1, 2, 4, 3, 5];
const maxValue = Math.max(...values);
const barWidthDepth = 0.5;
const barDistance = 1;
const barGeometry = new THREE.BoxGeometry(barWidthDepth, 1, barWidthDepth);
const maxBarHeight = values.length; // 최대 막대 높이
camera.position.z = values.length;
barGroup.position.x = -(barDistance * (values.length - 1)) / 2;
barGroup.position.y = -maxBarHeight / 2;
class Bar {
constructor(info = {}) {
this.container = info.container;
this.value = info.value || 0;
const heightValue = this.value / maxValue * maxBarHeight;
this.x = info.x || 0;
this.y = heightValue / 2;
this.z = info.z || 0;
this.topCanvas = document.createElement('canvas');
this.topCanvas.width = 500;
this.topCanvas.height = 500;
this.topContext = this.topCanvas.getContext('2d');
this.bottomCanvas = document.createElement('canvas');
this.bottomCanvas.width = 500;
this.bottomCanvas.height = 500;
this.bottomContext = this.bottomCanvas.getContext('2d');
this.sideCanvas = document.createElement('canvas');
this.sideCanvas.width = 500;
this.sideCanvas.height = 500;
this.sideContext = this.sideCanvas.getContext('2d');
const textureTop = new THREE.CanvasTexture(this.topCanvas);
const textureBottom = new THREE.CanvasTexture(this.bottomCanvas);
const textureSide = new THREE.CanvasTexture(this.sideCanvas);
this.materials = [
new THREE.MeshBasicMaterial({ map: textureSide }),
new THREE.MeshBasicMaterial({ map: textureSide }),
new THREE.MeshBasicMaterial({ map: textureTop }),
new THREE.MeshBasicMaterial({ map: textureBottom }),
new THREE.MeshBasicMaterial({ map: textureSide }),
new THREE.MeshBasicMaterial({ map: textureSide })
];
this.mesh = new THREE.Mesh(barGeometry, this.materials);
this.mesh.position.set(this.x, this.y, this.z);
this.mesh.scale.y = heightValue;
this.container.add(this.mesh);
this.draw();
}
draw() {
const colorValue = `${this.value / maxValue * 255}`;
// 위
this.topContext.fillStyle = `rgb(0, ${colorValue}, 0)`;
this.topContext.fillRect(0, 0, this.topCanvas.width, this.topCanvas.height);
// 바닥
this.bottomContext.fillStyle = 'black';
this.bottomContext.fillRect(0, 0, this.bottomCanvas.width, this.bottomCanvas.height);
// 옆 4면(그라데이션)
const gradient = this.sideContext.createLinearGradient(0, 0, 0, this.sideCanvas.height);
gradient.addColorStop(0, `rgb(0, ${colorValue}, 0`);
gradient.addColorStop(1, 'black');
this.sideContext.fillStyle = gradient;
this.sideContext.fillRect(0, 0, this.sideCanvas.width, this.sideCanvas.height);
}
}
// value가 클 수록 색상이 밝음
values.forEach((value, i) => {
new Bar({ value, container: barGroup, x: i * barDistance, y: 0, z: 0 });
});
// 그리기
const clock = new THREE.Clock();
function draw() {
renderer.render(scene, camera);
renderer.setAnimationLoop(draw);
}
function setSize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
}
// 이벤트
window.addEventListener('resize', setSize);
draw();
}
답변 정말 감사합니다.
정말 큰도움됐습니다.
감사합니다^^