Quick start
Vapor on an aircraft in a few lines.
<WingVapor> is a group where the aircraft's reference point sits, usually its
model's origin. Put it inside the model, and give it the airframe, the flight
and the day:
import { Canvas } from "@react-three/fiber";
import { WingVapor } from "@aeronautic/wing-vapor/react";
import { webgpu_gl } from "@aeronautic/core/react";
const Jet = () => (
<group>
<JetModel />
<WingVapor
// The model flies along its local -Z, with +Y up (the defaults)
forward={[0, 0, -1]}
airframe={{
spanM: 14,
rootChordM: 9.2,
tipChordM: 1.6,
leadingEdgeSweepRad: (55 * Math.PI) / 180,
apexM: -5.66, // the leading edge meets the centreline 5.66 m ahead
}}
flight={{ airspeedMPerS: 170, angleOfAttackRad: 0.35 }}
air={{ altitudeM: 300, relativeHumidity: 0.9 }}
look={{ sunDirection: [5, 10, 5] }}
/>
</group>
);
export const App = () => (
<Canvas gl={webgpu_gl()}>
<Jet />
</Canvas>
);The vapor reads the scene's depth, so it stops at the wing it sits on. Give
look.sunDirection the same direction as your scene's sun, so the cloud is
lit as the skin is.
Rather than typing the planform
Let the package measure the model from six depth views:
const { scene } = useGLTF("/jet.glb");
<group>
<primitive object={scene} />
<WingVapor
capture={scene}
// Not the shape the air flies round
captureFilter={(mesh) => !/Gear|Pylon|Missile/.test(mesh.name)}
flight={flight}
air={air}
/>
</group>;See Any shape.
Every frame
The flight changes every frame in a real scene. Write it through the ref, which costs no React render:
const vapor = useRef<WingVaporHandle>(null);
useFrame(() => {
vapor.current?.updateFlight({
airspeedMPerS: airspeed_m_s,
angleOfAttackRad: angle_of_attack_rad,
});
});
<WingVapor ref={vapor} airframe={airframe} />;Next, fly it, or see it on the fighter.