웹 페이지에 버튼 누를 때마다 다른 .glb 파일(3D) 보이는 기능 구현 질문 채택완료
컴공컴공컴공
4년 전
조회 4,162

현재 위에 이미지처럼 웹 페이지에 .glb를 보여주는 것까지는 구현하였습니다.
이제 버튼를 누를 때마다 다른 glb 파일을 불러와서 버튼마다 다른 3D 모델을 보여주고 싶은데
어떻게 해야할지 도저히 감이 오지 않아 질문합니다!
body에 아래 코드 넣고 실행하면 웹페이지에 버튼만 뜨고 아무것도 뜨지 않습니다.
</p>
<p><style></p>
<p> #c {</p>
<p> width: 100%;</p>
<p> height: 100%;</p>
<p> display: block;</p>
<p> }</p>
<p> </style></p>
<p> <button id="show_3d1" onclick="show_3d1()">모양1</button></p>
<p> <button id="show_3d2" onclick="show_3d2()">모양2</button></p>
<p> <canvas id="c"></canvas></p>
<p> <script type="module"></p>
<p> function show_3d1() {</p>
<p> import * as THREE from '<a href="https://threejsfundamentals.org/threejs/resources/threejs/r127/build/three.module.js';" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/threejs/r127/build/three.module.js';</a></p>
<p> import {OrbitControls} from '<a href="https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/controls/OrbitControls.js';" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/controls/OrbitControls.js';</a></p>
<p> import {GLTFLoader} from '<a href="https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/loaders/GLTFLoader.js';" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/loaders/GLTFLoader.js';</a></p>
<p> function main() {</p>
<p> const canvas = document.querySelector('#c');</p>
<p> const renderer = new THREE.WebGLRenderer({canvas});</p>
<p> </p>
<p> const fov = 45;</p>
<p> const aspect = 2; // the canvas default</p>
<p> const near = 0.1;</p>
<p> const far = 100;</p>
<p> const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);</p>
<p> camera.position.set(0, 10, 20);</p>
<p> </p>
<p> const controls = new OrbitControls(camera, canvas);</p>
<p> controls.target.set(0, 5, 0);</p>
<p> controls.update();</p>
<p> </p>
<p> const scene = new THREE.Scene();</p>
<p> scene.background = new THREE.Color('#fffff0'); //배경색</p>
<p> </p>
<p> {</p>
<p> const planeSize = 40; //바닥 사이즈 결정</p>
<p> </p>
<p> const loader = new THREE.TextureLoader();</p>
<p> const texture = loader.load('<a href="https://threejsfundamentals.org/threejs/resources/images/checker.png'); //바닥 이미지" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/images/checker.png'); //바닥 이미지</a></p>
<p> texture.wrapS = THREE.RepeatWrapping;</p>
<p> texture.wrapT = THREE.RepeatWrapping;</p>
<p> texture.magFilter = THREE.NearestFilter;</p>
<p> const repeats = planeSize / 20; //체크 바닥 사용할거면 필요</p>
<p> texture.repeat.set(repeats, repeats);</p>
<p> </p>
<p> const planeGeo = new THREE.PlaneGeometry(planeSize, planeSize);</p>
<p> const planeMat = new THREE.MeshPhongMaterial({</p>
<p> map: texture,</p>
<p> side: THREE.DoubleSide</p>
<p> });</p>
<p> //아래 코드 지우면 바닥 없어짐</p>
<p> // const mesh = new THREE.Mesh(planeGeo, planeMat);</p>
<p> // mesh.rotation.x = Math.PI * -.5;</p>
<p> // scene.add(mesh);</p>
<p> }</p>
<p> </p>
<p> //바닥색 설정</p>
<p> {</p>
<p> const skyColor = 0xB1E1FF; // light blue</p>
<p> const groundColor = 0xB97A20; // brownish orange(바닥 밑면)</p>
<p> const intensity = 1;</p>
<p> const light = new THREE.HemisphereLight(skyColor, groundColor, intensity);</p>
<p> scene.add(light);</p>
<p> }</p>
<p> </p>
<p> //light 색 설정</p>
<p> {</p>
<p> const color = 0xFFFFFF;</p>
<p> const intensity = 1;</p>
<p> const light = new THREE.DirectionalLight(color, intensity);</p>
<p> light.position.set(5, 10, 2);</p>
<p> scene.add(light);</p>
<p> scene.add(light.target);</p>
<p> }</p>
<p> </p>
<p> //3D 모델 불러오는 코드</p>
<p> const gltfLoader = new GLTFLoader();</p>
<p> gltfLoader.load('./3D/basic_cylinder_cake.glb', (gltf) => {</p>
<p> const root = gltf.scene;</p>
<p> scene.add(root); //여기까지</p>
<p> });</p>
<p> </p>
<p> function resizeRendererToDisplaySize(renderer) {</p>
<p> const canvas = renderer.domElement;</p>
<p> const width = canvas.clientWidth;</p>
<p> const height = canvas.clientHeight;</p>
<p> const needResize = canvas.width !== width || canvas.height !== height;</p>
<p> if (needResize) {</p>
<p> renderer.setSize(width, height, false);</p>
<p> }</p>
<p> return needResize;</p>
<p> }</p>
<p> </p>
<p> function render() {</p>
<p> if (resizeRendererToDisplaySize(renderer)) {</p>
<p> const canvas = renderer.domElement;</p>
<p> camera.aspect = canvas.clientWidth / canvas.clientHeight;</p>
<p> camera.updateProjectionMatrix();</p>
<p> }</p>
<p> renderer.render(scene, camera);</p>
<p> requestAnimationFrame(render);</p>
<p> }</p>
<p> requestAnimationFrame(render);</p>
<p> }</p>
<p> main();</p>
<p> }</p>
<p> </p>
<p> function show_3d2() {</p>
<p> import * as THREE from '<a href="https://threejsfundamentals.org/threejs/resources/threejs/r127/build/three.module.js';" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/threejs/r127/build/three.module.js';</a></p>
<p> import {OrbitControls} from '<a href="https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/controls/OrbitControls.js';" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/controls/OrbitControls.js';</a></p>
<p> import {GLTFLoader} from '<a href="https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/loaders/GLTFLoader.js';" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/loaders/GLTFLoader.js';</a></p>
<p> function main() {</p>
<p> const canvas = document.querySelector('#c');</p>
<p> const renderer = new THREE.WebGLRenderer({canvas});</p>
<p> </p>
<p> const fov = 45;</p>
<p> const aspect = 2; // the canvas default</p>
<p> const near = 0.1;</p>
<p> const far = 100;</p>
<p> const camera = new THREE.PerspectiveCamera(fov, aspect, near, far);</p>
<p> camera.position.set(0, 10, 20);</p>
<p> </p>
<p> const controls = new OrbitControls(camera, canvas);</p>
<p> controls.target.set(0, 5, 0);</p>
<p> controls.update();</p>
<p> </p>
<p> const scene = new THREE.Scene();</p>
<p> scene.background = new THREE.Color('#fffff0'); //배경색</p>
<p> </p>
<p> {</p>
<p> const planeSize = 40; //바닥 사이즈 결정</p>
<p> </p>
<p> const loader = new THREE.TextureLoader();</p>
<p> const texture = loader.load('<a href="https://threejsfundamentals.org/threejs/resources/images/checker.png'); //바닥 이미지" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/images/checker.png'); //바닥 이미지</a></p>
<p> texture.wrapS = THREE.RepeatWrapping;</p>
<p> texture.wrapT = THREE.RepeatWrapping;</p>
<p> texture.magFilter = THREE.NearestFilter;</p>
<p> const repeats = planeSize / 20; //체크 바닥 사용할거면 필요</p>
<p> texture.repeat.set(repeats, repeats);</p>
<p> </p>
<p> const planeGeo = new THREE.PlaneGeometry(planeSize, planeSize);</p>
<p> const planeMat = new THREE.MeshPhongMaterial({</p>
<p> map: texture,</p>
<p> side: THREE.DoubleSide</p>
<p> });</p>
<p> //아래 코드 지우면 바닥 없어짐</p>
<p> // const mesh = new THREE.Mesh(planeGeo, planeMat);</p>
<p> // mesh.rotation.x = Math.PI * -.5;</p>
<p> // scene.add(mesh);</p>
<p> }</p>
<p> </p>
<p> //바닥색 설정</p>
<p> {</p>
<p> const skyColor = 0xB1E1FF; // light blue</p>
<p> const groundColor = 0xB97A20; // brownish orange(바닥 밑면)</p>
<p> const intensity = 1;</p>
<p> const light = new THREE.HemisphereLight(skyColor, groundColor, intensity);</p>
<p> scene.add(light);</p>
<p> }</p>
<p> </p>
<p> //light 색 설정</p>
<p> {</p>
<p> const color = 0xFFFFFF;</p>
<p> const intensity = 1;</p>
<p> const light = new THREE.DirectionalLight(color, intensity);</p>
<p> light.position.set(5, 10, 2);</p>
<p> scene.add(light);</p>
<p> scene.add(light.target);</p>
<p> }</p>
<p> </p>
<p> //3D 모델 불러오는 코드</p>
<p> const gltfLoader = new GLTFLoader();</p>
<p> gltfLoader.load('./3D/basic_square_cake.glb', (gltf) => {</p>
<p> const root = gltf.scene;</p>
<p> scene.add(root); //여기까지</p>
<p> });</p>
<p> </p>
<p> function resizeRendererToDisplaySize(renderer) {</p>
<p> const canvas = renderer.domElement;</p>
<p> const width = canvas.clientWidth;</p>
<p> const height = canvas.clientHeight;</p>
<p> const needResize = canvas.width !== width || canvas.height !== height;</p>
<p> if (needResize) {</p>
<p> renderer.setSize(width, height, false);</p>
<p> }</p>
<p> return needResize;</p>
<p> }</p>
<p> </p>
<p> function render() {</p>
<p> if (resizeRendererToDisplaySize(renderer)) {</p>
<p> const canvas = renderer.domElement;</p>
<p> camera.aspect = canvas.clientWidth / canvas.clientHeight;</p>
<p> camera.updateProjectionMatrix();</p>
<p> }</p>
<p> renderer.render(scene, camera);</p>
<p> requestAnimationFrame(render);</p>
<p> }</p>
<p> requestAnimationFrame(render);</p>
<p> }</p>
<p> main();</p>
<p> }</p>
<p> </script></p>
<p>
댓글을 작성하려면 로그인이 필요합니다.
답변 2개
채택된 답변
+20 포인트
4년 전
중복 제거
</p>
<p> <script type="module">
import * as THREE from '<a href="https://threejsfundamentals.org/threejs/resources/threejs/r127/build/three.module.js';" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/threejs/r127/build/three.module.js';</a>
import {OrbitControls} from '<a href="https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/controls/OrbitControls.js';" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/controls/OrbitControls.js';</a>
import {GLTFLoader} from '<a href="https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/loaders/GLTFLoader.js';" target="_blank" rel="noopener noreferrer">https://threejsfundamentals.org/threejs/resources/threejs/r127/examples/jsm/loaders/GLTFLoader.js';</a>
function show_3d1() {</p>
<p>:</p>
<p>}</p>
<p> function show_3d1() {</p>
<p>:</p>
<p>}</p>
<p> </p>
<p>window.show_3d1 = show_3d1;
window.show_3d2 = show_3d2;</p>
<p>
어차피 중복이니, 함수 하나만 남기고, glb 파일명을 넘기는 것이 낫겠네요.
로그인 후 평가할 수 있습니다
답변에 대한 댓글 1개
�
컴공컴공컴공
4년 전
와... 오늘 새벽부터 못하고 있었는데 덕분에 해결했어요 너무 감사합니다!
댓글을 작성하려면 로그인이 필요합니다.
답변을 작성하려면 로그인이 필요합니다.
로그인