묻고 답해요
160만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
-
미해결Three.js 3D 인터랙티브 바로 시작하기
캔버스 크기를 지정했을 때 onDocumentMouseMove 이벤트 관련
애초에 캔버스 크기를let WIDTH = 400; let HEIGHT = 400;이렇게 설정하고 마우스이벤트를const onDocumentMouseMove = (event) => { if (0 < event.clientX && WIDTH > event.clientX) { mouseX = event.clientX - windowHalfX; } if (0 < event.clientY && HEIGHT > event.clientY) { mouseY = event.clientY - windowHalfY; } };이렇게 설정해서 작동은 됩니다만혹시 다른 간단한 방법이 있을까요? 캔버스 크기를 설정하면 WIDTH, HEIGHT를 넘어가도 이벤트가 실행이 되어서요
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
GLF파일 export한 후에 three.js에서 렌더링 된 모델에는 텍스처 적용이 안되어있습니다..!
블렌더에서는 텍스처가 적용된걸로 보이는데, export한 후에 three.js에서 렌더링 하면 텍스처가 적용되지 않은 모델로 보입니다 ㅜㅜ제공된 ilbuni.glb 파일을 사용하면 문제가 없는걸로 보아 코드 문제는 아니고, 블렌더에서 뭔가 잘못된거 같은데 이유를 모르겠습니다..! 아시는분들 답변부탁드립니다!! 익스포트 설정
-
해결됨React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
'JSX.IntrinsicElements' 유형에 'mesh' 속성이 없습니다. 경고 해결법
전 영상과 똑같이 npm으로 설치하는 과정에서 에러가 발생하시는 분들을 위한 제 해결법입니다. (2025-02 기준) 강사님이 올려주신 소스코드 다운로드이 방법은 강사님이 올려주신 폴더를 열어서 npm i 만 하시면 됩니다.직접 다운그레이드R3F가 현재(2025-02) 기준 React 19를 지원을 안합니다.그렇기 때문에 React 18로 다운그레이드를 해줘야되는데요 React 다운그레이드React 최신버전 설치npm create vite@latest우선 최신버전을 설치한 이후에다운그레이드npm uninstall react react-dom npm install react@18 react-dom@18react와 react-dom을 삭제후 18버전으로 설치합니다.3. 확인npm list react react-dom터미널로 확인하시면 18버전으로 다운그레이드 됩니다. 하지만 여기서 끝이 아니라 Typescript와 drei 설치시에도 문제가 발생합니다. mesh를 작성하게 되면 "JSX.intrinsicElements" 형식에 "mesh" 속성이 없습니다. 라는 경고창이 옆에 계속 뜨는데요실행결과는 잘 출력 되지만 거슬려서 해결법을 적어봅니다. 'JSX.IntrinsicElements' 에러 해결법package.json 파일에type/react와 type/react-dom이 19버전으로 되어 있어 호환이 안되어 발생하는 에러입니다.npm install @types/react@18 @types/react-dom@18 터미널에 입력해주시면 package.json 파일에서 18버전으로 다운그레이드 됩니다. 또 drei를 설치할때three-mesh-bvh@0.7.8: Deprecated due to three.js version incompatibility. Please use v0.8.0, instead에러가 발생하는데요 이는 three.js버전과 three-mesh-bvh 버전 간의 호환성 문제입니다. drei 라이브러리 설치법터미널에npm install @react-three/dreinpm install three-mesh-bvh@0.8.0 --legacy-peer-deps 그럼 3가지 세팅이 완료됩니다
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
일반 유리, 강화 유리 강의에서 Glass 객체의 position X를 -1, 1로 설정한 이유를 모르겠어요
각 Glass 객체의 position X 값을 -1, 1로 설정하셨는데, 어떤 계산이 들어간걸까요? 아니면 값을 넣어보면서 맞추는건가요? // 유리판 for (let i = 0; i < numberOfGlass; i++) { const glass1 = new Glass({ name: 'glass', x: -1, y: 10.5, z: i * glassUnitSize * 2 - glassUnitSize * 9, }); const glass12 = new Glass({ name: 'glass', x: 1, y: 10.5, z: i * glassUnitSize * 2 - glassUnitSize * 9, }); }
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
그림자가 다르게 표현됩니다
강의 코드를 그대로 따라하면 mesh 색이 어두운 회색으로 표현되고 그림자가 생기지 않는 문제가 있습니다. 그래서 SpotLight의 위치와 강도를 조정했더니 그림자는 나타나는데 강의영상처럼 모든 집에대한 그림자가 동일하게 나오는 것이 아니라 맨 처음 집에 대한 그림자만 선명히 나타납니다! 빛을 한방향에서만 쏘기 때문에 저 처럼 표현되는게 맞는 것 같은데, 강의영상처럼 모두 동일한 그림자를 표현하려면 어떻게 해야할까요..? import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/Addons.js'; import { House } from './House'; import gsap from 'gsap'; // ----- 주제: 스크롤에 따라 움직이는 3D 페이지 // 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); renderer.shadowMap.enabled = true; // 그림자 설정, mesh도 함께 설정해야함 renderer.shadowMap.type = THREE.PCFSoftShadowMap; // 그림자 부드럽게 // 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 ); camera.position.set(-5, 2, 25); scene.add(camera); // Light const ambientLight = new THREE.AmbientLight('white', 2); scene.add(ambientLight); const spotLight = new THREE.SpotLight('white', 500); spotLight.position.set(-5, 10, 30); // 그림자 설정 spotLight.castShadow = true; spotLight.shadow.mapSize.width = 1024; // 그림자 퀄리티 조정(성능에 크게 영향을 미치지 않는 정도) spotLight.shadow.mapSize.height = 1024; // 그림자 퀄리티 조정(성능에 크게 영향을 미치지 않는 정도) spotLight.shadow.camera.near = 1; spotLight.shadow.camera.far = 1000; scene.add(spotLight); const spotLightHelper = new THREE.SpotLightHelper(spotLight, 'red'); scene.add(spotLightHelper); // --- (2) HemisphereLight 추가 --- // const hemiLight = new THREE.HemisphereLight('white', 'white', 2); // scene.add(hemiLight); const gltfLoader = new GLTFLoader(); // Mesh const floorMesh = new THREE.Mesh( new THREE.PlaneGeometry(100, 100), new THREE.MeshStandardMaterial({ color: 'white', roughness: 0.4, // 필요에 따라 조절 metalness: 0.2, // 필요에 따라 조절 toneMapped: false, }) // 강의에는 MeshStandartMaterial 사용했는데, 이거 사용시 floorMesh가 하얀색이 아닌 회색으로 보여서 변경 ); floorMesh.rotation.x = -Math.PI / 2; // 180//2 = 90도 floorMesh.receiveShadow = true; // floorMesh에 그림자가 그려지기 때문에 recieveShadow 사용 scene.add(floorMesh); // 하우스를 통해 그림자가 만들어져야 하므로 -> castShadow const houses = []; houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: -5, z: 20, height: 2, }) ); houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: 7, z: 10, height: 2, }) ); houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: -10, z: 0, height: 2, }) ); houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: 10, z: -10, height: 2, }) ); houses.push( new House({ gltfLoader, scene, modelSrc: '/models/house.glb', x: -5, z: -20, height: 2, }) ); // 그리기 const clock = new THREE.Clock(); function draw() { const delta = clock.getDelta(); renderer.render(scene, camera); renderer.setAnimationLoop(draw); spotLightHelper.update(); } let currentSection = 0; function setSection() { // console.log('setSection 실행!'); // setSection 스크롤할때마다 실행됨 const newSection = Math.round(window.scrollY / window.innerHeight); // 0,1,2,3,4 if (currentSection !== newSection) { console.log('animation!'); // section값이 바뀔때만 애니메이션이 동작하도록 gsap.to(camera.position, { duration: 1, x: houses[newSection].x, z: houses[newSection].z + 5, }); currentSection = newSection; } } function setSize() { camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); renderer.setSize(window.innerWidth, window.innerHeight); renderer.render(scene, camera); } // 이벤트 window.addEventListener('scroll', setSection); window.addEventListener('resize', setSize); draw();
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
setAnimationLoop 위치가...
현재 애니메이션 기본 수업부터 scale까지 봤는데,setAnimationLoop 가 draw 안에 등록되서 매번 반복으로 실행되는것 같은데,화면갱신에 관련된 render만 반복시키고setAnimationLoop는 바깥에서 한번만 등록하는게 옳은 방법이 아닌가 하고 의문이 드는데 어떤게 맞는건가요?동작은 둘다 똑같이 되긴 합니다. const draw = () => { /* 메쉬 애니메이션 처리 코드 들어갈 위치 ... */ renderer.render(scene, camera); } renderer.setAnimationLoop(draw);
-
미해결Three.js 3D 인터랙티브 바로 시작하기
코드에 대해 질문있습니다.
안녕하세요 Three.js 강의 열심히 듣고 있습니다. 강의를 듣다가 궁금한점이 일반적으로 Three.js 를 사용할때 z좌표의 이해강의부분에 있는 JS 코드처럼 저 코드를 전부다 해석이 가능할정도로 알아야 되는지 아니면 보통은 복붙을 하고 자주 쓰이는 부분의 코드만 만지는것인지 궁금합니다.
-
해결됨React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
onClick 이벤트함수로 raycaster 방향이 자동으로 set되나요?
const shoesClick = () => { const intersects = raycaster.intersectObjects( gltf.scene.children, true ); };강의에서는 위와 같이 raycaster.intersectObject 메서드 호출시에 scene에 children을 넘겨주시는데 클릭 이벤트의 eventObject 를 넘겨주지 않았는데도 raycaster에 마우스 방향을 set 가능한가요?
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
얼굴 그릴 때 붓이 깔끔하게 칠해지지 않고 얼룩덜룩해요
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
블렌더 texture paint 시 미러모드
눈을 하나씩 그리고 싶은데 그릴 때 마다 미러모드가 작동하는 것 처럼 그려져요
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
DragControls의 인자값을 바꾸지 않았는데 에러가 안떠요!
DragControls 1:05초에 인자를 바꾸지 않으면 에러가 나야하는데, 저는 에러가 안뜨는데 이유가 뭘까요??서버도 껐다가 다시 켜도 동작만 안될 뿐이고, 에러는 안납니다!import * as THREE from 'three'; import { DragControls } from 'three/examples/jsm/Addons.js'; // ----- 주제: PointerLockControls 클릭 시 마우스 커서 사라지고, 마인크래프트 스타일로 변경됨 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 DragControls(camera, renderer.domElement); // Mesh const geometry = new THREE.BoxGeometry(1, 1, 1); let mesh; let material; for (let i = 0; i < 20; i++) { material = new THREE.MeshStandardMaterial({ // rgb (0,0,0)~(255,255,255) => (0,0,0)인 경우 검은색에 가까워지므로 최소:50 최대:250-50 color: `rgb( ${50 + Math.floor(Math.random() * 205)}, ${50 + Math.floor(Math.random() * 205)}, ${50 + Math.floor(Math.random() * 205)} )`, }); mesh = new THREE.Mesh(geometry, material); mesh.position.x = (Math.random() - 0.5) * 5; mesh.position.y = (Math.random() - 0.5) * 5; mesh.position.z = (Math.random() - 0.5) * 5; scene.add(mesh); } // 그리기 const clock = new THREE.Clock(); function draw() { const delta = clock.getDelta(); 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(); }
-
해결됨React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
화면에 렌더링은 되는데 코드에서 빨간줄이 떠요
{ "files": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ], "compilerOptions": { "baseUrl": ".", "paths": { "@components/*": ["src/components/*"] } }, "types": ["node"] }import { Canvas } from "@react-three/fiber"; import { OrbitControls } from "@react-three/drei"; import ShowRoom from "@components/three/ShowRoom"; export default function Home() { return ( <> <Canvas> <axesHelper args={[5]} /> <gridHelper /> <OrbitControls /> <directionalLight position={[3, 3, 3]} /> <ShowRoom /> </Canvas> </> ); }//vite.config.ts import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import path from "path"; // https://vite.dev/config/ export default defineConfig({ plugins: [react()], resolve: { alias: [ { find: "@src", replacement: path.resolve(__dirname, "src"), }, { find: "@components", replacement: path.resolve(__dirname, "src/components"), }, ], }, });vite config, tsconfig.json을 바꿨는데 home.tsx에서 import ShowRoom from "@components/three/ShowRoom"; 불러오는데 Cannot find module '@components/three/ShowRoom' or its corresponding type declarations.ts(2307)못찾는다는 에러가 생깁니다뭐를 잘못했는지 모르겠습니다ㅠㅠㅠ
-
미해결Three.js로 1인칭 3D 웹사이트 만들기
desk 가 밑으로 떨어졌을 때, "y 값이 문자열"에 대한 내용입니다.
우선 원인은...MeshObject 클래스 속성 중 differenceY 의 값에 OR 연산자를 사용., main.js 에서 ground 변수에 '0' 문자열 값을 할당해서 그런데요.ground 는 y 속성값을 할당하지 않았기 때문에 MeshObject 클래스에서 info.y 는 undefined 이고, this.y 는 "this.height / 2 + this.differenceY" 의 계산이 적용되서 " 0.1 / 2 + '0' " 즉, 문자열 '0.20' 이 출력됩니다.산술 연산자 '+' 가 들어가게되면, 그 계산식의 결과값은 반드시 문자열이 나옵니다.x, y, z, differenceY 는 모두 좌표와 연관된 값으로, 모두 숫자 데이터 타입을 할당받아야 하는 일관성이 필요한데 ground, floor 에서만 differenceY 가 문자열을 받아 발생한 이슈입니다.강의를 들어보던 중 강사님께서 처음에 숫자 0 을 사용하셨고, this.differenceY 속성에 값을 할당할때 OR 연산자를 쓰심으로인해 숫자 0 이 null/undefined 로 인식되는 것 때문에 문자열로 바꾸신거 같더라구요.조금 더 정확하게 하자면, OR 연산자가 아닌 ?? 연산자를 사용해 숫자 0을 값 그대로 사용할 수 있도록 바꾸고 ground 에도 문자열 '0' 이 아닌 숫자 0 을 넣어주면 될것같습니다.x, y, z 에 곱하기 1을 하는 추가코드는 필요없어집니다.
-
해결됨React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
문제 해결했습니다.
import { defineConfig } from 'vite' import react from '@vitejs/plugin-react-swc' import path, {resolve} from 'path' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], // resolve:{ // alias: [ // { // find: "@src", // replacement: path.resolve(__dirname, "src") // // @src 를 쓰면 src 폴더를 의미하게 된다. // // ../../ 이런거 안 써도 된다. // }, // { // find: "@components", // replacement: path.resolve(__dirname, "src/components") // } // ] // } resolve: { alias: { '@components': path.resolve(__dirname, 'src/components'), '@src': path.resolve(__dirname, 'src') } } })chatGPT 가 알려줬어여 ㅎㅎ
-
해결됨React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
문제 있어요! alias Path @ 문제
{ "compilerOptions": { "baseUrl": ".", "paths": { "@components/*" : ["src/components/*"], "@src/*" : ["src/*"] } }, "files": [], "references": [ { "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" } ] } 6분 08초 인데, 제꺼는 강사님꺼와 다르게 tsconfig 가 위와 같이 되어 있고, 여기 부분에서 넘어가 지지 않습니다. import React from "react"; import { Canvas } from "@react-three/fiber" import ShowRoom from "@components/ShowRoom" import { OrbitControls } from "@react-three/drei"; export default function Home(){ return ( <> <Canvas> <OrbitControls/> <directionalLight position={[5, 5, 5]}/> <axesHelper args={[5]}/> <gridHelper/> <ShowRoom/> </Canvas> </> ) } import ShowRoom from "@components/ShowRoom" 여기부분에 에러가 뜹니다에러메세지 [plugin:vite:import-analysis] Failed to resolve import "@components/ShowRoom" from "components/Home.tsx". Does the file exist? vite.config.js 는 아래와 같이 설정 했습니다. import { defineConfig } from 'vite' import react from '@vitejs/plugin-react-swc' import path from 'path' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], resolve:{ alias: [ { find: "@src", replacement: path.resolve(__dirname, "src") // @src 를 쓰면 src 폴더를 의미하게 된다. // ../../ 이런거 안 써도 된다. }, { find: "@components", replacement: path.resolve(__dirname, "src/components") } ] } }) 파일 구조입니다.
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
blender 에서 색칠하기 편 Texter paint slot추가없음
blender 색칠하기 편을 보고 작업을 진행중 입니다. 영상에서는 Texture Paint를 누르면 mesh가보라색이 된다고 나오며 이후 오른쪽 창에 플러스 버튼을 눌러서 Texture Paint Slot을 추가하는 장면이 나오지만 저의 경우 캐릭터가 보라색으로 바뀌지도, 해당 플러스 버튼이있지도 않습니다. 이유를 알 수 있을까요? 사진 첨부하겠습니다.
-
해결됨React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
dom / svg / canvas
혹시 웹에서 원하는 곳에 이미지를 애니메이션으로 보내거나 웹을 구성할때 canvas로는 좌표를 찍어 위치를 조정하기 쉬워보이는데 dom / svg를 활용할땐 웹에 원하는 곳으로 배치하기 위해선 그리드를 활용해야하나요 보통?
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
fin 버전도 그냥 실행이 안돼요
자꾸 하다가 오류메세지도 안뜨는데 혹시나 싶어서 fin버전도 실행해봤는데 아무것도 안뜨고 그냥 흰색 배경만 뜨네요. 라이브러리가 설치되지 않았다고 하기엔 다른 강의로 실행한 three.js는 실행이 됐었는데....그리고 canvas크기가 브라우저 창이 아니라 300^150으로만 설정되고 제가 변경해도 변경되지 않습니다.....
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
자바스크립트 실행이 안되는 것 같아요
개발자 도구 열어보면 저런 메세지가 뜨는데요, 강의를 듣다가 제가 코드를 잘못짠줄 알고 강의자료 완성된 코드도 열어보니 실행이 안됩니다. eval을 쓰면 안된다는데 뭔가 보안 상의 문제가 있는건지.vsc에서 npm start하고 나서 webpack 5.92.1 compiled successfully in 1447 ms이렇게 떴는데도 웹 상에서는 아무것도 안뜨고 그러네용 뭐가 문제인지 모르겠어요
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
모니터 해상도에 따라 mesh의 크기가 변할 수 있나요?
imac에서 mesh의 크기를 원하는 크기로 맞춰놓았습니다.그런데 일반 노트북이나 다른 모니터를 이용해서 작업할려고 보니까 imac에서 맞춰놓은 mesh의 크기값이 다르게 보이는 이유가 뭔가요?