파티클 레이캐스터터
351
작성한 질문수 20
레이캐스터를 파티클에 하면 제대로 선택이 안되는거 같은데 혹시 이유를 아시나요 ㅠ,ㅠ
답변 1
1
아래 코드를 참고해보세요~
ex06.js에 레이캐스터를 추가한 코드입니다.
import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls';
import { ImagePanel } from './ImagePanel';
import gsap from 'gsap';
// ----- 주제: 형태가 바뀌는 이미지 패널
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();
// Camera
const camera = new THREE.PerspectiveCamera(
75,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.y = 1.5;
camera.position.z = 4;
scene.add(camera);
// Light
const ambientLight = new THREE.AmbientLight('white', 0.5);
scene.add(ambientLight);
const directionalLight = new THREE.DirectionalLight('white', 1);
directionalLight.position.x = 1;
directionalLight.position.z = 2;
scene.add(directionalLight);
// Controls
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;
// Mesh
const planeGeometry = new THREE.PlaneGeometry(0.3, 0.3);
const textureLoader = new THREE.TextureLoader();
// Points
const sphereGeometry = new THREE.SphereGeometry(1, 8, 8);
const spherePositionArray = sphereGeometry.attributes.position.array;
const randomPositionArray = [];
for (let i = 0; i < spherePositionArray.length; i++) {
randomPositionArray.push((Math.random() - 0.5) * 10);
}
// 여러개의 Plane Mesh 생성
const meshes = [];
const imagePanels = [];
let imagePanel;
for (let i = 0; i < spherePositionArray.length; i += 3) {
imagePanel = new ImagePanel({
textureLoader,
scene,
geometry: planeGeometry,
imageSrc: `/images/0${Math.ceil(Math.random() * 5)}.jpg`,
x: spherePositionArray[i],
y: spherePositionArray[i + 1],
z: spherePositionArray[i + 2]
});
imagePanels.push(imagePanel);
meshes.push(imagePanel.mesh);
}
// 그리기
const clock = new THREE.Clock();
function draw() {
const delta = clock.getDelta();
controls.update();
renderer.render(scene, camera);
renderer.setAnimationLoop(draw);
}
function checkIntersects() {
raycaster.setFromCamera(mouse, camera);
const intersects = raycaster.intersectObjects(meshes);
for (const item of intersects) {
console.log(item.object.name);
item.object.material.color.set('red');
break;
}
// if (intersects[0]) {
// intersects[0].object.material.color.set('blue');
// }
}
function setSize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.render(scene, camera);
}
const raycaster = new THREE.Raycaster();
const mouse = new THREE.Vector2();
function setShape(e) {
const type = e.target.dataset.type;
let array;
switch (type) {
case 'random':
array = randomPositionArray;
break;
case 'sphere':
array = spherePositionArray;
break;
}
for (let i = 0; i < imagePanels.length; i++) {
// 위치 이동
gsap.to(
imagePanels[i].mesh.position,
{
duration: 2,
x: array[i * 3],
y: array[i * 3 + 1],
z: array[i * 3 + 2]
}
);
// 회전
if (type === 'random') {
gsap.to(
imagePanels[i].mesh.rotation,
{
duration: 2,
x: 0,
y: 0,
z: 0
}
);
} else if (type === 'sphere') {
gsap.to(
imagePanels[i].mesh.rotation,
{
duration: 2,
x: imagePanels[i].sphereRotationX,
y: imagePanels[i].sphereRotationY,
z: imagePanels[i].sphereRotationZ
}
);
}
}
}
// 버튼
const btnWrapper = document.createElement('div');
btnWrapper.classList.add('btns');
const randomBtn = document.createElement('button');
randomBtn.dataset.type = 'random';
randomBtn.style.cssText = 'position: absolute; left: 20px; top: 20px';
randomBtn.innerHTML = 'Random';
btnWrapper.append(randomBtn);
const sphereBtn = document.createElement('button');
sphereBtn.dataset.type = 'sphere';
sphereBtn.style.cssText = 'position: absolute; left: 20px; top: 50px';
sphereBtn.innerHTML = 'Sphere';
btnWrapper.append(sphereBtn);
document.body.append(btnWrapper);
// 이벤트
btnWrapper.addEventListener('click', setShape);
window.addEventListener('resize', setSize);
canvas.addEventListener('click', e => {
mouse.x = e.clientX / canvas.clientWidth * 2 - 1;
mouse.y = -(e.clientY / canvas.clientHeight * 2 - 1);
checkIntersects();
});
draw();
}
CDN으로 수업을 들을경우
0
16
1
리액트/next.js와 같이 사용하는 강의 계획은 없으신가요?
0
98
1
소스코드 파일이 강의랑 같나요?
0
138
2
materials 배열에 있는 top, bottom ... 들에 대해서
0
131
0
gltf 포맷 사용
0
262
1
점프 애니메이션 stop
0
143
2
사양에 따른 다른 결과
0
119
1
중복 질문 삭제
0
167
1
혹시 이 빛의 범위를 조절할 수 있는 방법이 있나요?
0
129
1
gltf.scene.children 이 없는데도 모델이 화면에 떠요
0
118
2
GLF파일 export한 후에 three.js에서 렌더링 된 모델에는 텍스처 적용이 안되어있습니다..!
0
180
1
일반 유리, 강화 유리 강의에서 Glass 객체의 position X를 -1, 1로 설정한 이유를 모르겠어요
0
85
0
그림자가 다르게 표현됩니다
0
155
1
setAnimationLoop 위치가...
0
111
1
얼굴 그릴 때 붓이 깔끔하게 칠해지지 않고 얼룩덜룩해요
0
150
1
블렌더 texture paint 시 미러모드
0
172
0
DragControls의 인자값을 바꾸지 않았는데 에러가 안떠요!
0
110
1
blender 에서 색칠하기 편 Texter paint slot추가없음
0
1025
2
fin 버전도 그냥 실행이 안돼요
0
304
2
자바스크립트 실행이 안되는 것 같아요
0
408
1
모니터 해상도에 따라 mesh의 크기가 변할 수 있나요?
0
247
1
live server와 localhost:8080
0
361
1
material에 canvas 를 texture 로 넣는방법이 궁금해요
0
279
1
모바일 조이스틱은 어떻게 만들 수 있을까요?
0
219
1





