-
-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
103 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
"vfx-composer-r3f": patch | ||
--- | ||
|
||
Added a first version of `<Particle>`, a scene-graph component that controls a single particle from the CPU. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
apps/vfx-composer-examples/src/examples/ControlledParticles.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { useFrame } from "@react-three/fiber" | ||
import { useRef } from "react" | ||
import { Group } from "three" | ||
import { Particle, Particles } from "vfx-composer-r3f" | ||
|
||
export default function ControlledParticlesExample() { | ||
const group = useRef<Group>(null!) | ||
|
||
useFrame(({ clock }) => { | ||
group.current.position.set( | ||
Math.cos(clock.elapsedTime * 1.3), | ||
Math.sin(clock.elapsedTime * 1.7), | ||
0 | ||
) | ||
}) | ||
|
||
return ( | ||
<group> | ||
<Particles> | ||
<sphereGeometry args={[0.5, 16, 16]} /> | ||
<meshStandardMaterial color="hotpink" /> | ||
|
||
<group ref={group}> | ||
<mesh> | ||
<boxGeometry /> | ||
<meshBasicMaterial wireframe /> | ||
</mesh> | ||
|
||
<Particle /> | ||
</group> | ||
</Particles> | ||
</group> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import { Object3DProps, useFrame } from "@react-three/fiber" | ||
import React, { | ||
forwardRef, | ||
useImperativeHandle, | ||
useLayoutEffect, | ||
useRef | ||
} from "react" | ||
import { Matrix4, Object3D } from "three" | ||
import { useParticlesContext } from "./Particles" | ||
|
||
const hideMatrix = new Matrix4().makeScale(0, 0, 0) | ||
|
||
const tmpMatrix = new Matrix4() | ||
|
||
/** | ||
* Use `<Particle>` to emit a single particle that remains CPU-controlled, meaning | ||
* that it will continuously update its instance matrix to match its transform | ||
* in the Three.js scene graph. | ||
* | ||
* **Note:** As soon as you use just a single `<Particle>` in your `<Particles>` effect, | ||
* it will disable the partial buffer updates, and result in a full buffer update every frame. | ||
*/ | ||
export const Particle = forwardRef<Object3D, Object3DProps>((props, ref) => { | ||
const sceneObject = useRef<Object3D>(null!) | ||
const particles = useParticlesContext() | ||
const id = useRef<number>() | ||
|
||
/* Hide the particle again on unmount */ | ||
useLayoutEffect(() => { | ||
const cursor = particles.cursor | ||
id.current = cursor | ||
particles.emit(1) | ||
|
||
return () => { | ||
particles.setMatrixAt(cursor, hideMatrix) | ||
} | ||
}, [particles]) | ||
|
||
/* Every frame, update the particle's matrix, and queue a re-upload */ | ||
useFrame(() => { | ||
if (id.current === undefined) return | ||
|
||
particles.setMatrixAt( | ||
id.current, | ||
tmpMatrix | ||
.copy(sceneObject.current.matrixWorld) | ||
.premultiply(particles.matrixWorld.invert()) | ||
) | ||
|
||
particles.instanceMatrix.needsUpdate = true | ||
}) | ||
|
||
/* Forward the ref */ | ||
useImperativeHandle(ref, () => sceneObject.current) | ||
|
||
return <object3D ref={sceneObject} {...props} /> | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,5 @@ | ||
export * from "./Emitter" | ||
export * from "./hooks/particles" | ||
export * from "./makeParticles" | ||
export * from "./Particle" | ||
export * from "./Particles" |