feat(environment): add wind-driven cloud system

This commit is contained in:
Tom Boullay
2026-05-27 00:33:53 +02:00
parent a6787a7ecb
commit 4ebb5b8c25
6 changed files with 250 additions and 0 deletions
+53
View File
@@ -0,0 +1,53 @@
import { useMemo } from "react";
import * as THREE from "three";
import { useGLTF } from "@react-three/drei";
import { useThree } from "@react-three/fiber";
import { CLOUD_CONFIG } from "@/data/world/cloudConfig";
import { optimizeGLTFSceneTextures } from "@/utils/three/optimizeGLTFScene";
interface CloudModelProps {
castShadow?: boolean;
receiveShadow?: boolean;
}
function applyCloudSettings(
scene: THREE.Object3D,
castShadow: boolean,
receiveShadow: boolean,
): void {
scene.traverse((child) => {
if (child instanceof THREE.Mesh) {
child.castShadow = castShadow;
child.receiveShadow = receiveShadow;
const materials = Array.isArray(child.material)
? child.material
: [child.material];
for (const material of materials) {
material.fog = false;
}
}
});
}
export function CloudModel({
castShadow = false,
receiveShadow = false,
}: CloudModelProps): React.JSX.Element {
const { scene } = useGLTF(CLOUD_CONFIG.modelPath);
const maxAnisotropy = useThree((state) =>
state.gl.capabilities.getMaxAnisotropy(),
);
const cloud = useMemo(() => {
optimizeGLTFSceneTextures(scene, maxAnisotropy);
const model = scene.clone(true);
applyCloudSettings(model, castShadow, receiveShadow);
return model;
}, [castShadow, maxAnisotropy, receiveShadow, scene]);
return <primitive object={cloud} />;
}
useGLTF.preload(CLOUD_CONFIG.modelPath);