11"use client" ; 
22
33import  *  as  THREE  from  "three" ; 
4- import  {  memo  }  from  "react" ; 
5- import  {  Environment , OrbitControls  }  from  "@react-three/drei" ; 
6- import  {  useFrame  }  from  "@react-three/fiber" ; 
7- import  {  useStickers  }  from  "./useStickers" ; 
4+ import  {  useMemo , useRef  }  from  "react" ; 
5+ import  {  OrbitControls  }  from  "@react-three/drei" ; 
6+ import  {  useFrame , createPortal , extend , useThree  }  from  "@react-three/fiber" ; 
7+ import  {  useStickers  }  from  "./StickerBall/ useStickers" ; 
88import  {  CanvasState  }  from  "./CanvasState" ; 
99import  {  StickerBall  }  from  "./StickerBall" ; 
10- import  {  Easing ,  Utils  }  from  "@/packages/use-shader-fx/src" ; 
10+ import  { 
11+  Easing , 
12+  Utils , 
13+  useResizeBoundary , 
14+  useSingleFBO , 
15+ }  from  "@/packages/use-shader-fx/src" ; 
16+ import  {  Background  }  from  "./Background" ; 
17+ import  {  FxMaterial ,  FxMaterialProps  }  from  "./romanticism/FxMaterial" ; 
18+ import  {  useRomanticism  }  from  "./romanticism/useRomanticism" ; 
1119
12- const  Background  =  memo ( ( {  stickerMap } : {  stickerMap : THREE . Texture  } )  =>  { 
13-  return  ( 
14-  < > 
15-  < Environment  preset = "warehouse"  environmentIntensity = { 0.5 }  /> 
16-  < mesh  scale = { 100 } > 
17-  < sphereGeometry  args = { [ 3 ,  32 ,  32 ] }  /> 
18-  < meshBasicMaterial 
19-  color = { new  THREE . Color ( 0x444444 ) } 
20-  map = { stickerMap } 
21-  side = { THREE . BackSide } 
22-  /> 
23-  </ mesh > 
24-  </ > 
25-  ) ; 
26- } ) ; 
27- Background . displayName  =  "Background" ; 
20+ extend ( {  FxMaterial } ) ; 
2821
2922export  const  Playground  =  ( )  =>  { 
30-  const  {  stickerMap ,  normalMap ,  isReady ,  silhouette  }  =  useStickers ( ) ; 
23+  const  {  camera ,  size ,  viewport ,  gl  }  =  useThree ( ) ; 
3124
3225 const  canvasState  =  CanvasState . getInstance ( ) ; 
3326
34-  useFrame ( ( {  camera,  clock } ,  delta )  =>  { 
27+  // 1000以上リサイズした場合のみリサイズする 
28+  const  resizeBoundary  =  useResizeBoundary ( { 
29+  gl, 
30+  size, 
31+  boundFor : "larger" , 
32+  threshold : 1000 , 
33+  } ) ; 
34+ 35+  // stickers 
36+  const  {  stickerMap,  normalMap,  isReady,  silhouette }  = 
37+  useStickers ( resizeBoundary ) ; 
38+ 39+  // offscreen to stickers 
40+  const  offscreenScene  =  useMemo ( ( )  =>  new  THREE . Scene ( ) ,  [ ] ) ; 
41+  const  [ portalStickers ,  updatePortalStickers ]  =  useSingleFBO ( { 
42+  scene : offscreenScene , 
43+  camera, 
44+  size, 
45+  dpr : viewport . dpr , 
46+  depthBuffer : true , 
47+  isSizeUpdate : resizeBoundary . isUpdate , 
48+  } ) ; 
49+ 50+  // romanticism 
51+  const  romanticism  =  useRomanticism ( portalStickers . texture ) ; 
52+  const  materialRef  =  useRef < FxMaterialProps > ( null ) ; 
53+ 54+  useFrame ( ( {  camera,  clock,  pointer,  gl } )  =>  { 
3555 if  ( ! isReady )  { 
3656 return ; 
3757 } 
3858
39-  // control camera state 
40-  if  ( canvasState . cameraState . point . z  <  canvasState . CAMERA_Z . default )  { 
41-  canvasState . cameraState . point . z  +=  delta ; 
59+  // update portalized stickers 
60+  updatePortalStickers ( gl ) ; 
61+ 62+  // update romanticism 
63+  if  ( materialRef . current )  { 
64+  materialRef . current . u_time  =  clock . getElapsedTime ( ) ; 
4265 } 
43-  camera . position . lerp ( canvasState . cameraState . point ,  0.16 ) ; 
66+ 67+  // control camera state 
68+  const  _pointer  =  pointer . clone ( ) . multiplyScalar ( 0.32 ) ; 
69+  canvasState . cameraState . point . lerp ( 
70+  { 
71+  ..._pointer ,  // uncomment this line to enable camera movement 
72+  // x: 0, 
73+  // y: 0, 
74+  z : canvasState . CAMERA_Z . default , 
75+  } , 
76+  0.12 
77+  ) ; 
78+  camera . position . lerp ( canvasState . cameraState . point ,  0.14 ) ; 
4479 camera . lookAt ( 0 ,  0 ,  0 ) ; 
4580
4681 // control clock state 
@@ -61,23 +96,37 @@ export const Playground = () => {
6196 } 
6297 } ) ; 
6398 return  ( 
64-  < mesh  visible = { isReady } > 
65-  < StickerBall 
66-  stickerMap = { stickerMap } 
67-  normalMap = { normalMap } 
68-  silhouetteMap = { silhouette } 
69-  /> 
70-  < Background  stickerMap = { stickerMap }  /> 
71-  < OrbitControls 
72-  enabled = { true } 
73-  enableZoom = { false } 
74-  enablePan = { false } 
75-  rotateSpeed = { 0.12 } 
76-  minAzimuthAngle = { - 0.785 }  // -45 
77-  maxAzimuthAngle = { 0.785 }  // 45 
78-  minPolarAngle = { 1.134 }  // 65 
79-  maxPolarAngle = { 1.919 }  // 110 
80-  /> 
81-  </ mesh > 
99+  < > 
100+  { createPortal ( 
101+  < mesh  visible = { isReady } > 
102+  < StickerBall 
103+  stickerMap = { stickerMap } 
104+  normalMap = { normalMap } 
105+  silhouetteMap = { silhouette } 
106+  /> 
107+  < Background  stickerMap = { stickerMap }  scene = { offscreenScene }  /> 
108+  < OrbitControls 
109+  enabled = { true } 
110+  enableZoom = { false } 
111+  enablePan = { false } 
112+  rotateSpeed = { 0.12 } 
113+  minAzimuthAngle = { - 0.785 }  // -45 
114+  maxAzimuthAngle = { 0.785 }  // 45 
115+  minPolarAngle = { 1.134 }  // 65 
116+  maxPolarAngle = { 1.919 }  // 110 
117+  /> 
118+  </ mesh > , 
119+  offscreenScene 
120+  ) } 
121+  < mesh  visible = { isReady } > 
122+  < planeGeometry  args = { [ 2 ,  2 ] }  /> 
123+  < fxMaterial 
124+  ref = { materialRef } 
125+  u_romance = { romanticism } 
126+  u_original = { portalStickers . texture } 
127+  key = { FxMaterial . key } 
128+  /> 
129+  </ mesh > 
130+  </ > 
82131 ) ; 
83132} ; 
0 commit comments