import { ScreenQuad } from '@react-three/drei' import { useFrame, type ElementProps } from '@react-three/fiber' import { useContext, useEffect, useMemo, type FC } from 'react' import type { BufferGeometry, Color, Mesh, Vector3 } from 'three' import type { AtmosphereMaterialProps } from '../AtmosphereMaterialBase' import { SkyMaterial, skyMaterialParametersDefaults } from '../SkyMaterial' import { AtmosphereContext } from './Atmosphere' import { separateProps } from './separateProps' export type SkyImpl = Mesh export interface SkyProps extends ElementProps< typeof Mesh, Mesh & Required & { sun: boolean moon: boolean moonDirection: Vector3 moonAngularRadius: number lunarRadianceScale: number groundAlbedo: Color } > {} export const Sky: FC = ({ ref: forwardedRef, ...props }) => { const { textures, transientStates, ...contextProps } = useContext(AtmosphereContext) const [ atmosphereParameters, { sun, moon, moonDirection, moonAngularRadius, lunarRadianceScale, groundAlbedo, ...meshProps } ] = separateProps({ ...skyMaterialParametersDefaults, ...contextProps, ...textures, ...props }) const material = useMemo(() => new SkyMaterial(), []) useEffect(() => { return () => { material.dispose() } }, [material]) useFrame(() => { if (transientStates != null) { material.sunDirection.copy(transientStates.sunDirection) material.moonDirection.copy(transientStates.moonDirection) material.worldToECEFMatrix.copy(transientStates.worldToECEFMatrix) // TODO: Since cloud shadows are computed in post-processing, the shadow // length texture is delayed by 1 frame. material.shadowLength = transientStates.shadowLength } }) return ( ) }