묻고 답해요
150만명의 커뮤니티!! 함께 토론해봐요.
인프런 TOP Writers
순위 정보를
불러오고 있어요
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
점프 애니메이션 stop
normal 유리판을 클릭했을 때, actions[0] 를 stop해서 default 모션은 삭제를 하지만 점프 모션은 계속 하더라구요. 사진처럼 점프도 삭제를 해야 정상적으로 작동이 되는데 혹시 강의에서는 따로 삭제를 안해도 점프모션이 반복되지 않는 이유가 뭘까요?!추가로 strong을 선택할때도 1초 후에는 다시 점프모션을 stop 해주었습니다.
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
사양에 따른 다른 결과
강의에서 사용하신 컴퓨터는 애플사 맥북이신거 같은데 저는 윈도우로 실습했습니다. 그래서인지 사실 기둥 세우고 바 설치하고부터 슬슬 렉이 심하게 걸리더라구요. 아무래도 사양이나 렌더링 능력치에 따라 다른 실습하시는 분들도 렉 걸리시거나 안걸리실텐데.. 그 이번 강의에서 일분이의 점프 동작을 구현할 때, gsap에서 y 값을 12로 설정하고 duration을 0.4초로 주셨잖아요? 똑같이 설정하고 실행했을 때, 1초보다 긴 체공시간을 갖고 떨어지더라구요. 근데 0.01초로 주어도 똑같이 체공하다가 떨어졌어요4초로 주었을 땐 정말 4초동안 체공하다가 떨어졌는데 이게 렉이 심해서 버벅여서 그렇게 보이는걸까요?! 쾌적한 환경에서 실습하지 못해서 아쉽긴 하지만 이러한 사양문제에 따라서 체공시간 같은 결과가 다르게 보일 수도 있을까요?
-
미해결React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
material 파트까지 들은 후 생긴 궁금증
안녕하세요 선생님. material까지 강의를 들으면서 두 가지 궁금한 점이 생겼습니다. 로컬 서버에서 ctrl+s 하면 자동으로 핫로딩되어 코드 변경사항이 화면에 반영되는 것으로 알고 있습니다. (리액트의 경우는 root부터 리렌더링) 그런데 핫로딩을 했을 때 바로 반영되는 코드가 있고, 직접 브라우저에서 새로고침해줘야 반영되는 코드가 있었습니다. <핫로딩 시 안변함 (only 새로고침으로만 변경사항 반영됨)> material wireframe 적용camera fov, far 속성그 외 등등 <핫로딩 시 변함> Geometry 종류 변경 transform 속성 변경 (position, scale, rotation)mesh color 변경materal 종류 변경그 외 등등 위와 같은 차이가 발생하는 이유를 잘 모르겠습니다. 내부 동작면에서 뭔가 다른게 있는 걸까요? (three.js 코드를 까보면 좀 명확해지려나요...) Mesh의 정의를 어떻게 내려야할지 잘 모르겠습니다. 아래 두 가지 중 어느 쪽이 더 맞는 설명일까요?Geometry와 material을 감싼 껍데기 Geometry와 material로 이루어진 하나의 물체 또, 종종 3D 모델링에서 정육면체, 삼각형 등을 오브젝트라고 부르는 걸 들은 적 있는 것 같은데, 해당 오브젝트라는 명칭이 맞는 명칭인가요? 그렇다면, Mesh = 오브젝트 라고 부를 수 있을까요? 감사합니다.
-
미해결React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
zoom과 fov의 차이점이 잘 이해가 안됩니다.
섹션3- 3D 구성요소 알아보기 강의 에서 설명주신것중 강의에서는 fov와 zoom의 수치를 감소시키거나 증가시켰을때, 선이라고 해야하나요? Cam이 찍고있는 좁아지고 넓어지는 그 선의 범위가 fov와 zoom이 같은 것 같아서 헷갈립니다!혹시 어떤 차이가 있는지 알려주실 수 있으실까요?
-
해결됨React Three fiber(R3F)로 배우는 인터렉티브 3D 웹 개발
1강 관련하여 의견을 여쭙고 싶은 게 있습니다.
안녕하세요 선생님. 무료보기 시청 후 바로 결제해서 달리고 있습니다. 하루 1강씩 뚫어보려고 합니다 😋 다름이아니라 DOM, SVG, Canvas를 비교해서 설명해주신 부분에서 의견을 여쭙고 싶은 내용이 있었습니다. Canvas의 2D Context보다 3D Context(WebGL)가 더 빠른 이유 이전에 2D Context를 공부하면서, 3D Context는 하드웨어 가속이 가능하기 때문에 더 빠르다는 글을 읽은 적이 있었습니다. 그런데 렌더링 자체는 Canvas 2D도 하드웨어 가속으로 처리되는 걸로 알고 있어서요. (간단한 작업은 CPU에서 처리한다는 글도 읽은 적 있었는데 어느 쪽이 맞는 말인지 사실 잘 모르겠습니다...) 아래 두 가지 중 어느 쪽이 WebGL Context가 2D Context보다 더 빠른 이유에 더 적합할까요?2D Context는 일부 CPU에서 렌더링하기도 하지만, WebGL은 전부 GPU에서 렌더링한다.WebGL은 셰이더를 GPU에서 실행시키기 때문에 2D Context보다 CPU 처리량이 적다.수많은 개체를 애니메이션 할 때 더 적합한 쪽 : WebGL API vs DOM(or SVG) + transform 속성 DOM 계산은 기본적으로 비용이 많이 발생하니, 수많은 개체를 '렌더링' 할 때에는 WebGL이 훨씬 유리할 것 같았는데, 위치를 옮긴다던가, 크기를 변경하는 애니메이션을 적용할 때에는 강사님께서는 WebGL과 transform 속성 중 어느 쪽을 더 선호하시나요? WebGL도 transform 속성도 레이아웃 재계산을 발생시키지 않지만, 전자는 JS로 조작해야하고, 후자는 조작은 css로 하지만 브라우저 레이어를 활용하는 것으로 알고 있어서요. 어느 쪽이 더 효율적일까요...?강의 중 보여주신 아래 그림에서, SVG의 사각형과 텍스트만 테두리가 좀 흐리게 보이고 있는데 이런 현상이 왜 발생하는걸까요? 이론 적으로는 SVG가 가장 깔끔해야할 것 같은데 픽셀이 깨질 정도로 확대하지 않는 이상은 SVG 쪽이 더 흐릿하게 보이는 것 같아 여쭤봅니다. 사실 강의도 강의지만, 평소에 고민하던 것을 여쭤본 것이기도 해서 가볍게 답변해주시더라도 너무 감사할 것 같습니다. 힘내서 완강해보겠습니다..! 감사합니다.
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
중복 질문 삭제
비슷한 질문 답변 올라온 게 있네요
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
혹시 이 빛의 범위를 조절할 수 있는 방법이 있나요?
사진처럼 DirectionalLight의 위치를 z: 10, y: 5로 주어 위치하였는데요. 도미노 중간부분이 오히려 어떤 무언가에 가려진 듯 어둡고, 끝 부분에는 가려진게 없는 듯이 밝습니다. 혹시 Light에 near, far 같은 옵션이 있어서 그런건지 아니면 위에 무언가가 가리고 있는건지 잘 모르겠습니다 하하..
-
미해결떠먹는 Three.js
roughness이 안 먹혀요 ㅜ
Material 수업강의 중2:44초에 roughness이 안먹힙니다..빛반사가 안되는데 확인 부탁드려요 ㅜ <script async src="https://ga.jspm.io/npm:es-module-shims@2.0.10/dist/es-module-shims.js"></script> <script type="importmap"> { "imports":{ "three" : "https://cdn.jsdelivr.net/npm/three@0.174.0/build/three.module.js", "three/addons/": "https://cdn.jsdelivr.net/npm/three@0.174.0/examples/jsm/" } } import * as THREE from "three"; const $result = document.querySelector("#result"); // 1. Scene : 화면에서 보여주려는 객체를 담는 공간 const scene = new THREE.Scene(); // scene.add(요소) scene.background = new THREE.Color(0xffe287); // 2. Camera : 신을 바라볼 시점을 결정 const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(2, 2, 2); camera.lookAt(0, 0, 0); // 3. Renderer : Scene+Camera, 화면을 그려주는 역할 const renderer = new THREE.WebGLRenderer({ canvas: $result, antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); // console.log(renderer); // document.body.appendChild(renderer.domElement) const light = new THREE.DirectionalLight(0xffffff); light.position.set(2, 4, 3); scene.add(light); const geometry = new THREE.BoxGeometry(1, 1, 1) const basic = new THREE.MeshBasicMaterial({ color: 0x2e6ff2, // wireframe: true, transparent: true, opacity: 0.5 }); // 가장 일반적으로 사용 됨. const standard = new THREE.MeshStandardMaterial({ color: 0xffaaaa, roughness: 0.2, }); const mesh = new THREE.Mesh(geometry, standard); scene.add(mesh); function animate() { // box.rotation.y += 0.01; // box.rotation.x += 0.01; // console.log(box.rotation.y); renderer.render(scene, camera); requestAnimationFrame(animate); } animate(); // 반응형을 위한 함수 window.addEventListener("resize", () => { // 1. 카메라의 종횡비 camera.aspect = window.innerWidth / window.innerHeight; camera.updateProjectionMatrix(); //카메라 업데이트 // 2. renderer의 크기 renderer.setSize(window.innerWidth, window.innerHeight); });
-
미해결Three.js로 시작하는 3D 인터랙티브 웹
gltf.scene.children 이 없는데도 모델이 화면에 떠요
ilbuniMesh를 위 사진과 같이gltf.scene.children[0]으로 정의하였는데,console.log(gltf)를 해보면 따로 children이 없는데도 정상적으로 출력됩니다. 또한 gltf.scene.children[0]가 아닌gltf.scenes[0].children[0] 으로 해도 정상적으로 출력되는데 혹시 어떤 차이점이 있는건지도 답변이 가능할까요?? 저 또한 블렌더에서 Object만 선택한 후 export 하면 애니메이션 오류가 뜨고 (uuid) Object와 뼈대를 같이 선택한 후에 export 해야 정상적으로 출력됩니다 ㅠㅠ
-
미해결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(); }
주간 인기글
순위 정보를
불러오고 있어요