Tresjs / tres

Declarative ThreeJS using Vue Components
https://tresjs.org
MIT License
2.16k stars 102 forks source link

`useRenderLoop().onLoop` ticks before the renderer can meaningfully render #595

Closed andretchen0 closed 3 months ago

andretchen0 commented 6 months ago

Describe the bug

Problem

useRenderLoop().onLoop ticks before the renderer can meaningfully render.

When onLoop is initially called, e.g.:

These values change on the subsequent frame, making coding/debugging more difficult than necessary.

Solution

Context

Reproduction

https://stackblitz.com/edit/tresjs-basic-t6zfd2?file=src%2Fcomponents%2FUseRenderer.vue

Steps to reproduce

See StackBlitz.

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 10.2.3 - /usr/local/bin/npm
    pnpm: 8.15.3 - /usr/local/bin/pnpm
  npmPackages:
    @tresjs/cientos: ^3.5.1 => 3.5.1 
    @tresjs/core: ^3.4.1 => 3.4.1 
    @tresjs/eslint-config-vue: ^0.2.1 => 0.2.1 
    vite: ^4.5.0 => 4.5.0

Used Package Manager

npm

Code of Conduct

andretchen0 commented 6 months ago

Hey @alvarosabu !

I saw that you labelled this as PR welcome. Great! I'll be happy to submit a PR eventually.

For now, I'm trying to submit issues highlighting rough spots encountered while building things with Tres.

My hope is that in assembling the issues, we'll be able to knock all (or most) of them out at once.

andretchen0 commented 5 months ago

Related?

This issue maybe pops up with custom shaders and HMR.

When doing off-screen rendering using a custom shader, this error is thrown on HMR:

Screenshot 2024-04-04 at 15 13 25
alvarosabu commented 4 months ago

This usecase is covered by the new useLoop composable available on v4 https://docs.tresjs.org/api/composables.html#useloop

andretchen0 commented 4 months ago

Hey @alvarosabu ,

This is still an issue with useLoop in the latest v4, as far as I can see. If you modify the code from the docs like this:

let logged = false
const { off } = render(({ renderer, scene, camera }) => {
  if (!logged) {
    logged = true
    console.log("canvas width/height:", renderer.domElement.width, renderer.domElement.height)
    console.log(`camera.aspect: ${camera.aspect}`);
  }
  renderer.render(scene, camera)
})

It will log this:

canvas width/height: 0 0
camera.aspect: 1

As with v3 these initial values will be changed on the next tick.

alvarosabu commented 3 months ago

OHHHH ok I see @andretchen0 we could add a check that if the size is !=0 it does render here:

https://github.com/Tresjs/tres/blob/8d53bbae37d858ddf775f0574647e86979473ac4/src/composables/useTresContextProvider/index.ts#L196-L199

andretchen0 commented 3 months ago

Hey @alvarosabu ,

The approach you mention would work for the render phase. But ideally here, this needs to keep a few other things from happening too early.

We should avoid at least one of these until the system is ready:

If we do either of those, there's no need to modify the render phase specifically.

I'm working on a fix.