marmeladze
marmeladze

Reputation: 6564

issue when real time updating a-sky src

I have simple python based websocket server which passes video frames as base64 string to client.

My client code

var ws = new WebSocket("ws://127.0.0.1:5678/")
ws.onmessage = function (event) {
  console.log("Event received: ", event.data.length)
  let data = event.data.slice(0, -1);
  document.getElementById('sky').setAttribute('src', "data:image/jpg;base64," + data);
};


When I use

//html
<img id="sky" src="" >

as image container, a "video" is produced.

But when I swtich to

<a-scene>
  <a-assets>
    <img id="sky" src="sky.png">
  </a-assets>
  <a-sky src="#sky"></a-sky>
</a-scene>

the image container get stuck at first frame, and although the src attribute of img element is updated, the image on web page doesn't change.

I've looked documentation and weren't able to find anything. What should I give attention?

Upvotes: 2

Views: 333

Answers (1)

Piotr Adam Milewski
Piotr Adam Milewski

Reputation: 14645

You should access the <a-sky>'s material and texture and set the needsUpdate flag. For example in a custom component:

AFRAME.registerComponent('foo', {
  init: function() {
    // wait until the object is loaded
    this.el.addEventListener("loaded", e => {
       // grab the mesh
       var mesh = this.el.getObject3D("mesh")
       // expose the material
       this.material = mesh.material
    })
  },
  tick: function() {
    // when the material is exposed - set the update flag on each tick
    if (!this.material) return;
    this.material.map.needsUpdate = true
  }
}

Canvas texture example here.


Or you can do this with a more direct approach, by accessing the material component:

// Providing the a-sky entity is loaded and ready
a_sky.components.material.material.map.needsUpdate = true

// Untangling it from the left to right:
// entity -> component list -> material component ->
// THREE.js Material object -> texture -> needsUpdate flag

Upvotes: 1

Related Questions