question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug in r119 attributes?

See original GitHub issue
Description of the problem

I’m not 100% sure this is a bug vs my bad code but r115 shows a yellow square (which is what I expect) and r119 shows a black square, same code

https://jsfiddle.net/greggman/42gm165d/ (r119) https://jsfiddle.net/greggman/74w5tzub/ (r115)

First let me explain my code. I’m trying to use morph targets with both positions and vertex colors. three.js doesn’t support vertex color morphing so I’m hacking those in.

Three.js, can be given a bunch of morph targets (say 100 targets), and then based on the influences of those 100 targets it will choose up to 4 of them to actually pass to the shader (I think that’s how it works).

In order for me to know which color data to pass to the shader I need to know which position data three.js decided to pass to the shader so I iterate over the morphTarget0-3 attributes and check which BufferAttribute (which data) is being used

for (i = 0; i < maxLiveTargets; ++i) {

  // check if three is using a certain position morph target
  const bufferAttribute = geometry.getAttribute(`morphTarget${i}`);

  if (bufferAttribute) {

    // figure out which position data is assigned to this morphTarget
    // assume the names are like position0, position1, position23, etc..
    const positionTargetNdx = parseInt(bufferAttribute.name.substr(8));  

    // add in the corresponding color target
    geometry.setAttribute(`morphColor${i}`, arrayOfColorBufferAttributes[positionTargetNdx]);
  }

}

I execute the above code in onBeforeRender and it turns out which morph targets will be used is not up to date until render 3 times in r115 but it does actually get there by the 3rd render.

On r119 it never gets there.

In the example there are cube morph targets (red, yellow, green, cyan). I set the influences to 0, 1, 0, 0 so I should see a yellow cube). I added some WebGL logging. On r115 I see this

first render

-[ render ]---------------------------------------
bindBuffer: 0target (position)
bindBuffer: normal
bindBuffer: uv
bindBuffer: color0 (color)
bindBuffer: 1target (position)
bindBuffer: 2target (position)
bindBuffer: 3target (position)

---[ on before render ]---
  check attribute: morphTarget0 attributeName: (N/A) influence: 0 does NOT exist
---[end on before render]---

bindBuffer: 0target (position)
vertexAttribPointer:  position 3 FLOAT false 0 0 0target (position)
bindBuffer: 1target (position)
vertexAttribPointer:  morphTarget0 3 FLOAT false 0 0 1target (position)

First we see all these bindBuffer calls. Those are the ones used when uploading the vertex data. Then you can see at onBeforeRender there was no info about which morph targets are used so no color is set. Three then sets up 2 attributes, ‘position’ to the cube 0 (red) and morphTarget0 to cube 1 (yellow). With no color set it will be black

2nd render

-[ render ]---------------------------------------

---[ on before render ]---
  check attribute: morphTarget0 attributeName: 1morph-target-position influence: 0 exists:
  set: attrib(morphColor0) to bufferAttrib(morph-color-data1)
  check attribute: morphTarget1 attributeName: (N/A) influence: 1 does NOT exist
---[end on before render]---

bindBuffer: 0target (position)
vertexAttribPointer:  position 3 FLOAT false 0 0 0target (position)
bindBuffer: 1target (position)
vertexAttribPointer:  morphTarget0 3 FLOAT false 0 0 1target (position)

This time we see on onBeforeRender that my code saw 1morph-target-position (the yellow cube’s positions) was assigned to morphTarget0 so it assigns the corresponding color morph-color-data1 to morphColor0

But then we see three.js ignores that when actually setting up th attributes even though it sets up the attributes after onBeforeRender

3rd render

-[ render ]---------------------------------------
bindBuffer: color1 (morphColor1)

---[ on before render ]---
  check attribute: morphTarget0 attributeName: 1morph-target-position influence: 0 exists:
  set: attrib(morphColor0) to bufferAttrib(morph-color-data1)
  check attribute: morphTarget1 attributeName: (N/A) influence: 1 does NOT exist
---[end on before render]---

bindBuffer: 0target (position)
vertexAttribPointer:  position 3 FLOAT false 0 0 0target (position)
bindBuffer: color1 (morphColor1)
vertexAttribPointer:  morphColor0 3 UNSIGNED_BYTE true 0 0 color1 (morphColor1)
bindBuffer: 1target (position)
vertexAttribPointer:  morphTarget0 3 FLOAT false 0 0 1target (position)

This time we see the same onBeforeRender behavior (the color data for cube1(yellow) is assigned to morphColor0) and then three.js actually uses it and we get a yellow cube.

Switching to r119

the first and second render are exactly the same as above so no need to repeat them but the 3rd render does not set up the color attribute

-[ render ]---------------------------------------
bindBuffer: color1 (morphColor1)

---[ on before render ]---
  check attribute: morphTarget0 attributeName: 1morph-target-position influence: 0 exists:
  set: attrib(morphColor0) to bufferAttrib(morph-color-data1)
  check attribute: morphTarget1 attributeName: (N/A) influence: 1 does NOT exist
---[end on before render]---

In fact no attributes are setup. My guess is the caching that was added thinks nothing needs to happen so it just binds the existing VAO and so nothing changes, the cube stays black.

Maybe I’m using three wrong so sorry if this really belongs on S.O but I have 2 question

  1. Is this bug in three?
  2. Is there a correct way to find out what morph targets are being used in the same frame (so my code isn’t 3 frames late)
Three.js version
  • Dev
  • r119
Browser
  • All of them
  • Chrome
  • Firefox
  • Internet Explorer
OS
  • All of them
  • Windows
  • macOS
  • Linux
  • Android
  • iOS
Hardware Requirements (graphics card, VR Device, …)

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:19 (11 by maintainers)

github_iconTop GitHub Comments

2reactions
mrdoobcommented, Aug 24, 2020

@greggman Wouldn’t it be better for that use case to use InstancedMesh? Specially now that it supports color per instance.

2reactions
Mugen87commented, Aug 15, 2020

I also think that VAO usage is a must for a WebGL engine. We should clearly state to not support specific use cases (like adding/removing attributes in onBeforeRender()) rather than revert VAO.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Modifying Bugs Attributes
Select the bug in the table and click the Edit Bug button on the Bug Toolbar (press F4) or right-click the bug and...
Read more >
How to Identify the Brown Marmorated Stink Bug
Report a Sighting of the Brown Marmorated Stink Bug. The Brown Marmorated Stink Bug has a "shield" shaped body that is characteristic of...
Read more >
Bug Attributes (in BTS) - TestMatick
Writing and formatting a bug one should add: bug ID, its type, summary, priority, severity, description, attachment, assigned to, assigned by,
Read more >
Bug Attributes description | Download Table - ResearchGate
A bug is characterized by many attributes shown in table 1 [8] . Some of the important bug attributes are severity, priority and...
Read more >
Bed Bugs Appearance and Life Cycle | US EPA
a “true bug” (characteristics of true bugs include a beak with three segments; antenna that have four parts; wings that are not used...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found