Constconst [bloodDecals, setBloodDecals] = useState<BloodDecal[]>([]);
const characterMeshRef = useRef<THREE.Mesh>(null);
// On hit event
const handleHit = (position: [number, number, number], normal: [number, number, number]) => {
setBloodDecals([...bloodDecals, {
id: generateId(),
position,
normal,
size: [0.15, 0.15, 0.05],
rotation: Math.random() * Math.PI * 2,
opacity: 0.8,
timestamp: Date.now(),
isLaceration: false,
}]);
};
<mesh ref={characterMeshRef}>
<capsuleGeometry args={[0.5, 1.6, 16, 32]} />
<meshStandardMaterial color={0xcccccc} />
</mesh>
<BloodDecals3D
decals={bloodDecals}
targetMeshRef={characterMeshRef}
enabled={violenceSettings.blood}
isMobile={isMobile}
onDecalComplete={(id) => {
setBloodDecals(prev => prev.filter(d => d.id !== id));
}}
/>
BloodDecals3D Component
Renders persistent blood decals on 3D character models using decal projection. Decals fade over time and can persist across combat rounds for injury tracking.
Performance optimized: