Taking over the render-loop #1339
Replies: 2 comments 7 replies
-
https://docs.pmnd.rs/react-three-fiber/API/hooks#taking-over-the-render-loop function RenderComponent() {
useFrame((state, delta) ) => {
state.gl.render(state.scene, state.camera)
}, 1)
return null
} the
This i don't understand, these two have no relation. useFrame in that one component rotates a cube. if you want to stop that then the parent communicates that with a prop: function SpinningComponent({ dontSpin }) {
useFrame(() => {
if (dontSpin) { ...
<SpinningComponent dontSpin={condition} /> useFrame ties a component to the render-loop, or puts the render-loop into the hands of a component (by giving it an index), its that components responsibility now to render or else the screen stays blank. but it is not responsible for stopping/resuming the rendering, it renders when invalidation occurs.
import { invalidate } from '@react-three/fiber'
// Flag invalidation, this won't render immediately, it merely tells r3f that we want to ...
invalidate() There's also |
Beta Was this translation helpful? Give feedback.
-
Thanks for taking the time to write this thorough answer! I initially thought that setting a render priority on useFrame would control the global rendering. If useFrame just ties a component to the render-loop then the behavior I was observing makes much more sense. The way I'm going about it now is to remove invalidate() from all useFrame implementations except one in a controller component from which I can then turn the loop on and off. A little follow up questions though: useFrame((state, delta) => {
box.current.rotation.y += (Math.PI * 2) / (60 * duration)
}) But for some reason the final animation always turns out about 20 frames short of a full loop. Am I calculating the rotation here right? Keep in mind that I am controlling the rendering manually now. Every frame rendered (no matter how long it takes) should account for one animation step. Here is a simplified version of how I trigger the rendering: useFrame(
({ gl }) => {
if (recording) {
// Progress
if (frameCounter.current <= duration * 60) {
// Capture and send frame
const frame = gl.domElement.toDataURL()
// Advance counter
frameCounter.current += 1
send_frame_to_server(frame, sessionId).then(() => {
// Render next frame
gl.clearDepth()
gl.render(scene, camera)
invalidate()
})
} else {
// Done
frameCounter.current = 0
setRecording(false)
// Process frames
start_processing(sessionId, duration, fps).then((url) => {
downloadResource(
`http://${serverUrl}/${url}`,
"clip.mp4"
)
})
}
}
},
recording ? 1 : 0
) |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Hi,
I am still working on my canvas recorder component and I am looking for some insight.
My Canvas is set to frameloop="demand". My mesh is animated inside a useFrame hook inside of its own component. Now, from inside another component I'd like to stop the useFrame animation and continue rendering only manually. I've been trying to figure this out for a couple of days but haven't gotten anywhere. I'd be happy for any pointers.
Beta Was this translation helpful? Give feedback.
All reactions