From a41859d4ad7b93cb826fda5d8016a6e3d4642676 Mon Sep 17 00:00:00 2001 From: NISHIZAWA Shuntaro Date: Tue, 5 Nov 2024 14:00:42 +0900 Subject: [PATCH] =?UTF-8?q?feat:=20=E3=83=9E=E3=83=86=E3=83=AA=E3=82=A2?= =?UTF-8?q?=E3=83=AB=E3=82=92=E3=83=88=E3=82=A5=E3=83=BC=E3=83=B3=E8=AA=BF?= =?UTF-8?q?=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/components/ModelLoad.tsx | 38 +++++++++++++++++++++--- package.json | 1 + pnpm-lock.yaml | 54 +++++++++++++++++++++++++++++++++++ public/assets/threeTone.jpg | Bin 0 -> 11040 bytes 4 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 public/assets/threeTone.jpg diff --git a/app/components/ModelLoad.tsx b/app/components/ModelLoad.tsx index ecb5ccf..a732e40 100644 --- a/app/components/ModelLoad.tsx +++ b/app/components/ModelLoad.tsx @@ -1,5 +1,6 @@ -import { Environment, OrbitControls, useGLTF } from "@react-three/drei"; +import { OrbitControls, useGLTF } from "@react-three/drei"; import { Canvas } from "@react-three/fiber"; +import { Bloom, EffectComposer } from "@react-three/postprocessing"; import { type ReactNode, useEffect, useRef } from "react"; import type { Group, MeshStandardMaterial } from "three"; import * as THREE from "three"; @@ -10,6 +11,7 @@ const HAIR_MESH_NAMES = [ "hairback", "hairfront", "hairtail", + "hairside", "hairsid", "hair", ] as const; @@ -36,6 +38,29 @@ function useCharacterSetting(setting: CharacterSetting) { const modelPath = `/models/web_${setting.character}.glb`; const { scene } = useGLTF(modelPath); + + useEffect(() => { + const threeTone = new THREE.TextureLoader().load("/assets/threeTone.jpg"); + threeTone.minFilter = THREE.NearestFilter; + threeTone.magFilter = THREE.NearestFilter; + + scene.traverse((child) => { + if (!(child as THREE.Mesh).isMesh) return; + const mesh = child as THREE.Mesh; + const oldMaterial = mesh.material as MeshStandardMaterial; + const newMaterial = new THREE.MeshToonMaterial({ + name: oldMaterial.name, + color: oldMaterial.color, + gradientMap: threeTone, + map: oldMaterial.map, + emissive: oldMaterial.emissive, + emissiveIntensity: oldMaterial.emissiveIntensity, + emissiveMap: oldMaterial.emissiveMap, + }); + mesh.material = newMaterial; + }); + }, [scene]); + useEffect(() => { scene.traverse((child) => { if (!(child as THREE.Mesh).isMesh) return; @@ -83,15 +108,20 @@ export function ModelViewer({ characterSetting }: ModelProps): ReactNode { - {/* 環境を設定*/} - + {/* ライトを設定 */} + + + {/* ポストプロセッシング */} + + + {/* GLBモデルの読み込みと表示 */} {/* カメラコントロールの追加(ユーザーが自由にカメラを操作できるようにする) */} diff --git a/package.json b/package.json index 8137866..80b8e91 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "@radix-ui/react-slot": "1.1.0", "@react-three/drei": "9.114.6", "@react-three/fiber": "8.17.10", + "@react-three/postprocessing": "2.16.3", "@remix-run/react": "2.13.1", "@supabase/supabase-js": "2.45.6", "@types/three": "0.169.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3507e32..fbe9fc2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -23,6 +23,9 @@ importers: '@react-three/fiber': specifier: 8.17.10 version: 8.17.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.169.0) + '@react-three/postprocessing': + specifier: 2.16.3 + version: 2.16.3(@react-three/fiber@8.17.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.169.0))(@types/three@0.169.0)(react@18.3.1)(three@0.169.0) '@remix-run/react': specifier: 2.13.1 version: 2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3) @@ -1221,6 +1224,13 @@ packages: react-native: optional: true + '@react-three/postprocessing@2.16.3': + resolution: {integrity: sha512-ftodXpUsy0/mzn0KqyV7MBau71dD9C5UOFnB3kHhCLNoxjKYQWZa9do0olJTSkl3owYXRfNHcLriK1Xn8wxZJw==} + peerDependencies: + '@react-three/fiber': '>=8.0' + react: '>=18.0' + three: '>= 0.138.0' + '@remix-run/dev@2.13.1': resolution: {integrity: sha512-7+06Dail6zMyRlRvgrZ4cmQjs2gUb+M24iP4jbmql+0B7VAAPwzCRU0x+BF5z8GSef13kDrH3iXv/BQ2O2yOgw==} engines: {node: '>=18.0.0'} @@ -3252,6 +3262,12 @@ packages: '@types/three': '>=0.134.0' three: '>=0.134.0' + maath@0.6.0: + resolution: {integrity: sha512-dSb2xQuP7vDnaYqfoKzlApeRcR2xtN8/f7WV/TMAkBC8552TwTLtOO0JTcSygkYMjNDPoo6V01jTw/aPi4JrMw==} + peerDependencies: + '@types/three': '>=0.144.0' + three: '>=0.144.0' + magic-string@0.27.0: resolution: {integrity: sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==} engines: {node: '>=12'} @@ -3557,6 +3573,12 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + n8ao@1.9.3: + resolution: {integrity: sha512-OZX+u8LaEfxLi6lupuyT8gIv80D6D8FIeKbBNkCyY0nE+1wmm6sQ4yeyW3a15lFMrfTcEhe0AU8QhhDejHg7sg==} + peerDependencies: + postprocessing: '>=6.30.0' + three: '>=0.137' + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -3937,6 +3959,11 @@ packages: resolution: {integrity: sha512-cDWgoah1Gez9rN3H4165peY9qfpEo+SA61oQv65O3cRUE1pOEoJWwddwcqKE8XZYjbblOJlYDlLV4h67HrEVDg==} engines: {node: '>=12'} + postprocessing@6.36.3: + resolution: {integrity: sha512-GtMLwoqg0xdYAgm9lbf6qlKay7HQPb8Z+xAPSzbCUspud/qBj3Y/orJSkqEQVlfxTtm7YAUSv+J39ir51/IwaQ==} + peerDependencies: + three: '>= 0.157.0 < 0.170.0' + potpack@1.0.2: resolution: {integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==} @@ -5994,6 +6021,19 @@ snapshots: optionalDependencies: react-dom: 18.3.1(react@18.3.1) + '@react-three/postprocessing@2.16.3(@react-three/fiber@8.17.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.169.0))(@types/three@0.169.0)(react@18.3.1)(three@0.169.0)': + dependencies: + '@react-three/fiber': 8.17.10(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(three@0.169.0) + buffer: 6.0.3 + maath: 0.6.0(@types/three@0.169.0)(three@0.169.0) + n8ao: 1.9.3(postprocessing@6.36.3(three@0.169.0))(three@0.169.0) + postprocessing: 6.36.3(three@0.169.0) + react: 18.3.1 + three: 0.169.0 + three-stdlib: 2.33.0(three@0.169.0) + transitivePeerDependencies: + - '@types/three' + '@remix-run/dev@2.13.1(@remix-run/react@2.13.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.6.3))(@types/node@22.8.2)(typescript@5.6.3)(vite@5.4.10(@types/node@22.8.2))': dependencies: '@babel/core': 7.26.0 @@ -8287,6 +8327,11 @@ snapshots: '@types/three': 0.169.0 three: 0.169.0 + maath@0.6.0(@types/three@0.169.0)(three@0.169.0): + dependencies: + '@types/three': 0.169.0 + three: 0.169.0 + magic-string@0.27.0: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -8759,6 +8804,11 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + n8ao@1.9.3(postprocessing@6.36.3(three@0.169.0))(three@0.169.0): + dependencies: + postprocessing: 6.36.3(three@0.169.0) + three: 0.169.0 + nanoid@3.3.7: {} nearley@2.20.1: @@ -9122,6 +9172,10 @@ snapshots: postgres@3.4.5: {} + postprocessing@6.36.3(three@0.169.0): + dependencies: + three: 0.169.0 + potpack@1.0.2: {} prettier@2.8.8: {} diff --git a/public/assets/threeTone.jpg b/public/assets/threeTone.jpg new file mode 100644 index 0000000000000000000000000000000000000000..58278acb40c1efb7a2af4c65520e865bc55c9863 GIT binary patch literal 11040 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