2026-06-26 14:05:26 -05:00
|
|
|
import { createPortal, useFrame, useThree } from "@react-three/fiber";
|
|
|
|
|
import { memo, useState } from "react";
|
|
|
|
|
import { DepthTexture, Scene, Vector2 } from "three";
|
2026-09-27 16:46:22 -05:00
|
|
|
import { spacedArmorRenderTarget } from "./PrimaryArmorRenderTarget";
|
|
|
|
|
import { PrimaryArmorScene } from "./PrimaryArmorScene";
|
|
|
|
|
import { SpacedArmorScene } from "./SpacedArmorScene";
|
2024-02-27 11:52:36 -06:00
|
|
|
|
2026-09-27 16:46:22 -05:00
|
|
|
export const DynamicArmor = memo(() => {
|
2025-04-14 18:52:49 -05:00
|
|
|
const rootScene = useThree((state) => state.scene);
|
2024-02-28 22:29:21 -06:00
|
|
|
const [spacedArmorScene] = useState(() => new Scene());
|
2025-04-14 18:52:49 -05:00
|
|
|
const [primaryArmorScene] = useState(() => {
|
|
|
|
|
const primaryArmorScene = new Scene();
|
|
|
|
|
primaryArmorScene.fog = rootScene.fog;
|
|
|
|
|
|
|
|
|
|
return primaryArmorScene;
|
|
|
|
|
});
|
2024-02-27 11:52:36 -06:00
|
|
|
const spacedArmorPortal = createPortal(
|
2024-02-28 22:29:21 -06:00
|
|
|
<SpacedArmorScene scene={spacedArmorScene} />,
|
2024-02-27 11:52:36 -06:00
|
|
|
spacedArmorScene,
|
|
|
|
|
);
|
2024-07-29 20:46:57 -05:00
|
|
|
const primaryArmorPortal = createPortal(
|
|
|
|
|
<PrimaryArmorScene />,
|
|
|
|
|
primaryArmorScene,
|
|
|
|
|
);
|
2024-02-27 11:52:36 -06:00
|
|
|
|
|
|
|
|
const renderSize = new Vector2();
|
|
|
|
|
const newRenderSize = new Vector2();
|
|
|
|
|
|
|
|
|
|
useFrame(({ gl, camera, scene }) => {
|
|
|
|
|
gl.getSize(newRenderSize).multiplyScalar(gl.getPixelRatio());
|
|
|
|
|
|
|
|
|
|
if (!newRenderSize.equals(renderSize)) {
|
|
|
|
|
renderSize.copy(newRenderSize);
|
|
|
|
|
spacedArmorRenderTarget.depthTexture = new DepthTexture(
|
|
|
|
|
renderSize.x,
|
|
|
|
|
renderSize.y,
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
spacedArmorRenderTarget.setSize(renderSize.x, renderSize.y);
|
|
|
|
|
gl.setRenderTarget(spacedArmorRenderTarget);
|
|
|
|
|
gl.render(spacedArmorScene, camera);
|
|
|
|
|
|
|
|
|
|
gl.autoClear = false;
|
|
|
|
|
|
|
|
|
|
gl.setRenderTarget(null);
|
|
|
|
|
gl.render(scene, camera);
|
|
|
|
|
|
|
|
|
|
gl.clearDepth();
|
2024-07-29 20:46:57 -05:00
|
|
|
gl.render(primaryArmorScene, camera);
|
2026-10-02 18:34:50 +13:00
|
|
|
|
|
|
|
|
gl.autoClear = true;
|
2024-02-27 11:52:36 -06:00
|
|
|
}, 1);
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
|
|
|
|
{spacedArmorPortal}
|
2024-07-29 20:46:57 -05:00
|
|
|
{primaryArmorPortal}
|
2024-02-27 11:52:36 -06:00
|
|
|
</>
|
|
|
|
|
);
|
2024-02-27 17:15:24 -06:00
|
|
|
});
|