Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support manual render mode / advancing the render loop by 1 tick #624

Open
4 tasks done
verekia opened this issue Apr 8, 2024 · 6 comments
Open
4 tasks done

Support manual render mode / advancing the render loop by 1 tick #624

verekia opened this issue Apr 8, 2024 · 6 comments

Comments

@verekia
Copy link
Collaborator

verekia commented Apr 8, 2024

Description

Supporting a manual render mode allows developers to manage their rendering loop externally with more control. It is useful for games to use a single rAF loop and have all their systems executed in a predictable order. For example their main loop can execute:

  • Inputs
  • AI logic
  • Physics
  • Rendering <= They would put the Tres advance() call here in their loop.
  • UI
  • Cleanup

Suggested solution

The feature should add an option to TresCanvas to render "manually" or to "never" loop, and then offer a function to call to advance the rendering by 1 tick.

Additional context

R3F's implementation (<Canvas frameloop="never"> + advance()): https://github.com/pmndrs/react-three-fiber/blob/fac9424a12e6068f1c8e1062240d2a3373cd2e23/packages/fiber/src/core/loop.ts#L166

Threlte uses <Canvas renderMode="manual"> + advance().
Some old Threlte commit that implemented the feature: threlte/threlte@272d17c

Validations

@alvarosabu
Copy link
Member

alvarosabu commented Apr 8, 2024

@verekia I think we should rephrase this ticket to Allow overriding the renderLoop fn since the render-mode functionality you describe is "Conditional Rendering" which is going to be available on #541 only stops the renderLoop from rendering but doesn't overwrite it or allow the end user to add its own render loop which correct me if I'm wrong that was the usecase you were mentioning right?

@dghez
Copy link

dghez commented Apr 8, 2024

+1 on this!

Have the control over how / when to render and render-priority is deffo something REALLY useful, with r3f you can can do

useFrame(() => {}, proprity)

that is super helpful, you can use the priority = 0 to override the internal render loop, you can use negative values and positives too. This is very helpful when you want some stuff happens after others :)

EDIT:
My two cents is that is something REALLY important when you start to get your hands dirty with advanced techniques, like using render targets, render different layers at different order, use a custom pipeline, stuff that at sooner or later you'll need :)

@andretchen0
Copy link
Contributor

+1

I also like R3F's approach. It's simple and flexible and lets users roll their own loop order.

Related

Issue: #607
Discussion: #578

Obstacles

It seems to me that what's holding the current codebase back is the simple, practical current implementation of useRenderLoop. It has lots of good parts, but some downsides.

useRenderLoop is global, so something like this works:

<script>
import { useRenderLoop } from '@tresjs/core'

// NOTE: TresCanvas hasn't been created yet, but you can already ...
useRenderLoop().onLoop(() => {...})
</script>

<template>
  <TresCanvas>
  </TresCanvas>
</template>

Users seem to like that. Me too.

But the current implementation isn't linked to any particular <TresCanvas />, which has implications for update/render loops:

It'd be really handy if we could both:

  • tie useRenderLoop to a particular <TresCanvas />
  • continue to useRenderLoop in <script>, before <template><TresCanvas /></template>, without having to e.g., use refs and wait for onMounted

So ... 👇

Feedback please

Here's a proposal for creating an unbound context in <script>, before <TresCanvas />.

Feedback on this proposal is very appreciated.

Other proposals are also welcome.

Status

However, for me anyway, big changes like in the discussion I linked to are on hold until after v4 is rolled out, unless @alvarosabu and the rest of the team decides otherwise.

@verekia
Copy link
Collaborator Author

verekia commented Apr 9, 2024

@alvarosabu It seems like the upcoming manual mode + invalidate method is exactly what I am after, yes :) I didn't realize conditional rendering included that mode. With this mode, people who need more control over their game loop will be able to advance rendering exactly when they want it without relying on Tres' render loop.

This ticket was not about making an equivalent of R3F's renderPriority, although it's a nice feature to have for people who don't want to roll out their own game loop but still want to organize some logic around Tres' loop.

Feel free to rename the ticket as you please or make a new one about allow overriding the renderLoop fn :)

@alvarosabu
Copy link
Member

Hey there!

As @andretchen0 perfectly explained, we need to work on having the render loop tied to the specific canvas and not global, which would be a significant change that would open a world of possibilities to users.

This together with Andre's proposal of unbound context and plugins is on top of my list for next 4.x releases. I'm worried that the render loop one will create another breaking change that would postpone it to a future 5.x.

@andretchen0 do you think we could do it without a breaking change or it would be better to delay the release and add this to v4?

@andretchen0
Copy link
Contributor

Hey @alvarosabu

@andretchen0 do you think we could do it without a breaking change or it would be better to delay the release and add this to v4?

I responded over here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants