import React , { useMemo } from 'react' ; import { Story , Meta } from '@storybook/react' ; import { useLoader , Canvas } from '@react-three/fiber' ; import { OrbitControls } from '@react-three/drei' ; import * as THREE from 'three' ; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader' ; import Lightmap , { AutoUV2Ignore } from '../core/Lightmap' ; import Spinner from './Spinner' ; import { DebugOverlayRenderer , DebugOverlayWidgets } from './DebugOverlayScene' ; import sceneUrl from './tile-game-room6.glb' ; export default { title : 'glTF scene' , parameters : { layout : 'fullscreen' } , decorators : [ ( story ) => < div style = { { height : '100vh' } } > { story ( ) } < /div>] } as Meta ; const MainSceneContents = ( ) => { const { nodes } = useLoader ( GLTFLoader , sceneUrl ) ; const lightStub = nodes . Light ; const light = new THREE . DirectionalLight ( ) ; light . castShadow = true ; light . intensity = lightStub . scale . z ; light . shadow . camera . left = - lightStub . scale . x ; light . shadow . camera . right = lightStub . scale . x ; light . shadow . camera . top = lightStub . scale . y ; light . shadow . camera . bottom = - lightStub . scale . y ; light . position . copy ( lightStub . position ) ; const target = new THREE . Object3D ( ) ; target . position . set ( 0 , 0 , - 1 ) ; target . position . applyEuler ( lightStub . rotation ) ; target . position . add ( lightStub . position ) ; light . target = target ; const baseMesh = nodes . Base ; if ( baseMesh instanceof THREE . Mesh && baseMesh . material instanceof THREE . MeshStandardMaterial ) { baseMesh . material . metalness = 0 ; baseMesh . material . side = THREE . FrontSide ; if ( baseMesh . material . map ) { baseMesh . material . map . magFilter = THREE . NearestFilter ; } baseMesh . castShadow = true ; baseMesh . receiveShadow = true ; } const coverMesh = nodes . Cover ; if ( coverMesh instanceof THREE . Mesh && coverMesh . material instanceof THREE . MeshStandardMaterial ) { coverMesh . castShadow = true ; coverMesh . material . depthWrite = false ; coverMesh . material . colorWrite = false ; } return ( < AutoUV2Ignore > < mesh position = { [ 0 , 0 , - 5 ] } > < planeBufferGeometry attach = "geometry" args = { [ 200 , 200 ] } / > < meshBasicMaterial attach = "material" color = "#171717" / > < /mesh> < primitive object = { light } dispose = { null } / > < primitive object = { light . target } dispose = { null } / > < primitive object = { baseMesh } dispose = { null } / > < primitive object = { coverMesh } dispose = { null } / > < spotLight position = { [ 0 , 0 , 2 ] } color = "#f00" castShadow penumbra = { 0.25 } intensity = { 0.5 } / > < /AutoUV2Ignore>); } ; export const Main = ( ) => ( < Canvas camera = { { position : [ - 4 , - 4 , 8 ] , up : [ 0 , 0 , 1 ] } } shadows onCreated = { ( { gl } ) => { gl . toneMapping = THREE . ACESFilmicToneMapping ; gl . toneMappingExposure = 0.9 ; gl . outputEncoding = THREE . sRGBEncoding ; } } > < DebugOverlayRenderer > < React . Suspense fallback = { < Spinner />}> < Lightmap textureFilter = { THREE . NearestFilter } > < MainSceneContents /> < DebugOverlayWidgets / > < /Lightmap> < /React.Suspense> < /DebugOverlayRenderer> < OrbitControls enableDamping dampingFactor = { 0.1 } rotateSpeed = { 0.5 } target = { new THREE . Vector3 ( 0 , 0 , 1 ) } / > < /Canvas>);