I am creating an editor using babylon.js and I’m having issues with multi-views. Basically, when I click objects in my scene I want to be able to preview that object in a separate panel. I therefore register a view with the engine when my panel component is mounted (vue js component wrapping an html canvas), and de-register that view before the component is destroyed.
I followed the instructions in the official docs but the issue I am facing is that the view flickers. It seems to me that it is initialized with garbage information (as I sometimes can even see parts of my desktop rendered in that view). The effect is more apparent using firefox but it also happens on chrome. (see the attached image: the green colour is the background colour of the canvas element, the pink colour and glitches are the issue I mentioned → should be transparent).
Any help would be greatly appreciated! Thanks in advance!
So, after a lot of head scratching I managed to isolate the issue to the clear colour. Somehow setting a transparent clear colour to the scene does not work when using multi canvases/views.
Is that behaviour known/expected? I tried to search for similar cases online but didn’t find anything relevant.
We are simply copying the content of the engine canvas to the view canvas by doing:
context.drawImage(parent, 0, 0);
So, maybe there are some limitations when alpha is involved and the parent canvas is a webgl canvas?
I checked that the parent canvas is ok even in multi view mode (meaning, the content of the canvas is ok with no flickering if you display it in the page). So, the problem really occurs at copy time.
I tried to test something like this for the copy:
const data = parent.getContext("2d").getImageData(0, 0, parent.width, parent.height);
context.putImageData(data, 0, 0);
but it fails because you are not allowed to get a 2d context on parent because there’s already a webgl context that has been retrieved for it.
Could it maybe be an issue of uninitialized memory where the desktop or other glitches showing up in the canvas would be caused by random/old data in the buffer? Because the cube itself looks alright when drawn in the view, just the background looks random/glitchy.
I’ll have a look if I can find clues in the source code, taking into account the info you provided @Evgeni_Popov. If it’s a bug I’ll report like you suggested @sebavan
The left half of the image where the bounds of the clearRect end now looks better (although the edge of the cube looks pink and green, but could that be an unrelated issue altogether?)
The other half which has not been cleared is still flickering (as expected).
I don’t know enough about the internals of babylon or the browser to know whether a clear is the right way to go here, but what’s your input @sebavan, @Evgeni_Popov ?
It seems to work (in all the PGs below I have set (through css) the background color of the canvas displayed to green (“lime”) - also, all the “non multi view” PGs are ok, obviously):
alpha value of scene clear color set to 0.2. The final background color should be a blend between the green and the gray clear color:
the background is gray without rendering artifacts in prod and still ok with the clearRect call
So, if it’s ok for @Deltakosh / @sebavan I think we can add a context.clearRect(0, 0, parent.width, parent.height); call just before context.drawImage(parent, 0, 0);: wanna do a PR?
Hey @Evgeni_Popov, thanks!
Yeah I could give it a shot this weekend. Would be a good occasion to try and contribute something back (although very small)
I read a bit about the performance impact of clearRect however and it seems that it could be expensive on some devices. Maybe I can add a check for alpha (or add a flag?) in order to do the clearRect only when absolutely necessary. Then in the multi view docs page, we could warn that there might be a performance dip if using a transparent scene with a multi view setup. What do you think?
Let’s wait for the PR, as I don’t really know where this flag should be added (maybe we can add it as a parameter to the registerView call and store it in the EngineView class?).