React + Three.js에서 waving flag
사용한 샘플을 찾지 못했기 때문에
@react-three/fiber
나는 각종 조사 결과를 쓰고 싶다.깃발을 흔드는 생각/방법
PlaneGeometry의
vertices
(정점) 속성만 업데이트하면 된다는 것을 알고 있습니다.그러나three-fiber를 사용할 때
vertices
에는 속성을 찾을 수 없습니다.정점 좌표를 획득하고 업데이트하는 방법
정점의 좌표 정보가
position
속성에 들어간 것 같습니다.Three.js의 샘플 코드는 Vector3입니다. 여기는 모두 배열되어 있습니다.써본 코드
github에 예시된 코드에서 다음 좌표를 얻을 수 있습니다:.
//x
position.array[index * 3]
//y
position.array[index * 3 + 1]
//z
position.array[index * 3 + 2]
아래 코드는 필요 없어요@react-three/cannon
. 하지만 usePlane
연결이 편리해서 썼어요.모든 코드
import { TextureLoader } from "three/src/loaders/TextureLoader";
import { Canvas, useFrame, useLoader, useThree } from "@react-three/fiber";
import { Physics, usePlane, Debug } from "@react-three/cannon";
import CameraControls from "camera-controls";
import * as THREE from "three";
import { useMemo } from "react";
CameraControls.install({ THREE });
const TeamFlag = ({img_url}) => {
const Flag = () => {
const map = useLoader(TextureLoader,
img_url
);
const [mesh] = usePlane(() => ({
rotation: [-0.1, 0, 0],
position: [0, 0, 0],
type: "Static",
mass: 100,
args: [3, 3, 15, 9],
}));
useFrame((state) => {
const t = state.clock.getElapsedTime();
function* enumerate(count) {
let i = 0;
while (i < count) yield i++;
}
const { geometry } = mesh.current;
const { position, normal, uv } = geometry.attributes;
for (const index of enumerate(position.count)) {
const waveX1 = 0.5 * Math.sin(position.array[index * 3] * 2 + t*4);
const waveX2 = 0.25 * Math.sin(position.array[index * 3] * 3 + t *2);
const waveY1 =
0.25 * Math.sin(position.array[index * 3 + 1] * 3 + t / 5);
const multi = (position.array[index * 3] + 2) / 5;
//z
position.array[index * 3 + 2] = (waveX1 + waveX2 + waveY1) * multi;
}
position.needsUpdate = true;
geometry.computeVertexNormals();
});
return (
<mesh ref={mesh}>
<planeGeometry args={[3, 3, 15, 9]}/>
<meshBasicMaterial map={map} opacity={1} />
</mesh>
);
};
function Controls({
zoom,
focus,
pos = new THREE.Vector3(),
look = new THREE.Vector3(),
}) {
const camera = useThree((state) => state.camera);
const gl = useThree((state) => state.gl);
const controls = useMemo(
() => new CameraControls(camera, gl.domElement),
[]
);
return useFrame((state, delta) => {
state.camera.position.lerp(pos, 0.5);
state.camera.updateProjectionMatrix();
controls.setLookAt(
state.camera.position.x,
state.camera.position.y,
state.camera.position.z,
look.x,
look.y,
look.z,
true
);
return controls.update(delta);
});
}
return (
<div>
<Canvas
style={{
width:80,
height:80
}}
>
<Physics>
<Flag />
</Physics>
<Controls
zoom={false}
focus={{}}
pos={new THREE.Vector3(0, 0, 2.2)}
look={new THREE.Vector3(0, 0, 0)}
/>
</Canvas>
</div>
);
};
export default TeamFlag;
참조 링크
Reference
이 문제에 관하여(React + Three.js에서 waving flag), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/ckoshien/articles/7156daefb791778d4152텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)