Tresjs / tres

Declarative ThreeJS using Vue Components

Home Page:https://tresjs.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

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

andretchen0 opened this issue · comments

Describe the bug

Problem

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

When onLoop is initially called, e.g.:

  • camera.aspect has its default value of 1, regardless of screen aspect
  • renderer.domElement.width has a value of 0
  • sizes.width has a value of 0

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

Solution

  • useRenderLoop() should be dependent on the context's renderer.
  • The system shouldn't tick onLoop until the renderer is ready.

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

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.

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

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

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.

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

if (camera.value && render.frames.value > 0) {
renderer.value.render(scene, camera.value)
emit('render', ctx.renderer.value)
}

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:

  • starting the loop
  • calling any loop callbacks

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

I'm working on a fix.