Closed leweaver closed 7 years ago
To expand on what @leweaver said: We've also determined that the next revision of WebVR (which should be the one that sticks around) will have forced context loss as a core concept of using WebGL with a VR device. Pull request here.
The TL;DR version is that contexts used with WebVR devices will need to have a compatibility bit set on them. You can do this two ways. First, with a context creation arg, like so:
let gl = glCanvas.getContext("webgl", { compatibleVrDevice: vrDevice });
This won't cause context loss, but may not be appropriate if you don't know ahead of time that the user will be using a specific VRDevice
. The second method is a bit more disruptive:
let gl = glCanvas.getContext("webgl");
// Some time later...
gl.setCompatibleVrDevice(vrDevice).then(() => {
// If the VRDevice is connected to a different GPU than the one
// the WebGL context was created with this would have forced
// a context loss. The promise only resolves when the context
// has been restored. If the page doesn't handle it the promise
// is rejected.
});
Obviously the context loss case won't be triggered every single time, and many devices (such as mobile) may never see a context loss. But devices with multiple GPUs (even laptops with an integrated/discreet pair) could hit this path frequently.
Ideally Three.js can provide some mechanisms for dealing with context loss and promote it as something that developers need to pay attention to, otherwise you'll get a lot of devs who test their content on a single-GPU system and say "It Works!" and then wonder why things fail on some systems when their content is released in the wild.
Okay. Basic support added. Works in most of the cases but a few things break when restored (sprites, lensflares, etc). I'll be fixing them over the next days.
This is great news!
Ok, after b317394ef3ebee642cec0e5e38badcc9137ea266, 5e661c2b3022ba7d9313cd2ae2d0976ab3d6cf4d, 79c14c8fd0f01a123306fac15742871636305124 and f6392b404c19e560cff3f04a0f9c70d7df012fe3 this should now be working.
@mrdoob let's say I have a cube map that is rendered once and then used somewhere; now if I subscribe to 'webglcontextrestored' on canvas - will I have all the resources ready in order to re-render the cube map? do I also need to render() the scene to handle needUpdate=true stuff 1st? give us tutorial :D
Good question. If you setup a jsfiddle I'll adapt it to make it work 😊
@makc
Basically, the user will have to take care of some things:
renderer.domElement.addEventListener( 'webglcontextrestored', function () {
cubeCamera.updateCubeMap( renderer, scene );
} );
Thanks @mrdoob - just tested this out and it is working great!
@leweaver 🙌
@mrdoob I tried to upgrade the fiddle https://jsfiddle.net/023byLzq/ but it does not seem to work any more 😭
Is this better? https://jsfiddle.net/jfnvaxy7/
@Mugen87 not for me, it just freezes on loss and never starts moving again
I get this in the console, maybe it is relevant:
What system are you using?
On my Windows 10 notebook with Chrome 92.0.4515.159 I see no console warnings at all.
@Mugen87 it used to work 4 years ago on the same system 😭 it is macosx + firefox
it used to work 4 years ago
actually... I just tried with r94 that should have been used on July 19-th, 2017, and it also fails, so it must be a browser issue
edit: wrong year 😅 but again does not work any more, so I have to blame ff
@Mugen87 I just tried this on win10 machine (specifically, your fiddle fork) and it does work without warnings for me as well (aside from restore handler taking too many ms) BUT, in most of the button clicks results the cube map comes out half-black. This is the same as what I see here in my "broken" firefox if I switch to another tab and then go back to jsfiddle :(
I have tested again and indeed after a few tries it seems only parts of the cubemap are getting rendered. Sometimes the cubemap is completely black. Sometimes it works. 🤔 .
@Mugen87 this tweak will probably completely fix it on windows. my mac chrome is happy too.
That is of course the right fix! And it explains the different outcomes of the previous version. Depending on the torus knot's transformation, certain renderings of the cube camera were occluded by the mesh.
Description of the problem
The updated WebVR 1.1 specification has provisions for multi-GPU systems, which rely on correct usage of the webglcontextlost and webglcontextrestored events, or, the page not handling the events at all.
Currently three.js handles the event webglcontextlost, calling
event.preventDefault
to inform the browser that it intends to handle the webglcontextrestored event, yet makes no attempt to rebuild the resources (nor handle that event). Further,resetGLState()
,setDefaultGLState()
etc should actually occur in a webglcontextrestored.Until such a time as three.js can confidently handle the webglcontextrestored event (such as building on the method proposed in issue #5507) handling of context lost should be removed entirely - or at the very least, not make a call to
event.preventDefault()
in the event handler.From three.js WebGLRenderer.js:538
Three.js version
Browser
OS
Hardware Requirements (graphics card, VR Device, ...)
Multi GPU system (such as a laptop, or a machine with motherboard integrated graphics and a discrete adapter) VR Headset plugged in to discrete GPU Monitor plugged in to integrated motherboard graphics