ngl: Shader error when upgrading to Three.js r112 (WebXR)
I wrote a custom minimal Viewer to embed NGL Representations into existing projects based on Three.js. Full control over the scene is maintained by the parent project, only the geometries are exported into a THREE.Group that can be freely manipulated. It was some effort but works quite well (see demo, branch ThreeJSViewer in my fork, glitch to play around with the API).
Besides needing this for another project I wanted to update @KJStrand A-Frame component and create some vanilla Three.js WebXR demo. WebXR is a first class citizen in Three.js now and it is really awesome even with a mobile headset like the Oculus Quest, but projects need to follow a few conventions (no forced camera movement, units are meters, floor plane for walking around an object etc.), so it would make sense to include NGL objects in a template like this. In the long run this should be done properly by enabling renderer.xr in NGL.Stage, but it will be some effort to make everything compatible (e.g. labels). Also, NGLs rendering pipeline is fairly advanced with its special treatment of still frames and the different cameras, so it might make sense to keep it completely separate (related issue).
Unfortunately, WebXR was included into Three.js with version 112, while we are on 111.
I made a branch to make NGL compile up to 115, but between 111 and 112 something changed so that the shaders don’t work anymore. Stuff is rendered but stays invisible, and WebGL warnings like “GL ERROR :GL_INVALID_OPERATION : glDrawElements: Source and destination textures of the draw are the same.
” are thrown (in Chrome, Firefox has slightly different warnings).
I did some research but have actually no idea what could cause this. Three.js changelogs and commits look unsuspicious to me. Maybe https://bugs.chromium.org/p/chromium/issues/detail?id=421695 is related, but it certainly happens on the version change, while this bug would probably be a deeper issue.
You can see the effect here: https://jussty.github.io/ngl-r112/examples/embedded.html or in the other examples.
A big disadvantage of including NGL into other projects is that Three.js version needs to match exactly. I don’t mind maintaining releases of ThreeJSViewer for different versions if you don’t want to have that burden in the main repo. A-Frame even ships with their own fork, but the 1.0.0 releases are also based off some WebXR enabled r111.5 which has the same problems.
Also I am certain the API could be even simpler, without needing references to renderer, camera AND scene, but since some of the low level shader utils need these objects for their magic I kept it in for now.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 25 (4 by maintainers)
Your IDE may well know more about this than I do…
I’ve just submitted an issue to nglview and if that doesn’t raise any flags hopefully we can merge this soon.
@giagitom: How are you building your app at the moment - is it a javascript project with a package.json? If so you would be able to add ngl (and possibly three*) as deps and either use
require('ngl')
orimport { Something } from 'ngl'
depending on whether you’re using node-style or ES6 imports.*My change would mean that adding ngl as a dep automatically brings in a compatible version of three - you could be explicit about which version of three you want by adding it as a dep and I think npm will try to use the same copy if versions are compatible, so your code would then be:
and they’d share a three instance (unless you specify an incompatible version)
You could test by replacing/adding the ngl dependency in your project as “fredludlow/ngl#pr-737”
@garyo - looking forward to hear if it works or not 😃
We’d also need to coordinate with nglview (cc’ing @hainm). It looks like nglview uses ES6 imports and webpack, the end result should be the same but when developing nglview npm would install three separately and webpack should bundle it in (if I understand it right) - this is definitely something that would need to work in order to proceed.
I guess our current situation stems from the fact that back in the day JS build tools were a lot less mature and not all the big libraries played nicely with npm/yarn
There are a few ways you might want to deploy NGL but I think it comes down to:
Proposal:
We move Three.js to a dependency (not a devDependency) with an appropriately specified version range. This means that when you npm install ngl, three will get installed alongside (and if versions are compatible your other code that uses Three will use the same instance).
We create three build targets:
import { Stage } from 'ngl'
in an ES6 projectI made a quick attempt at this here: https://github.com/fredludlow/ngl/tree/pr-737
You can add this in npm as a git dependency if you want to try it:
npm install -D fredludlow/ngl#pr-737
ORnpm install -D fredludlow/ngl#82feda5
(the exact commit at time of writing)Very minimal usage example here: https://github.com/fredludlow/ngl-module-test
If people are in favour of this approach there are a few TODOs
(If people aren’t in favour please speak up - I’m by no means an expert on this)
Indeed – you have to add three.js to your project (npm or yarn) and probably
import Three from 'three'
yourself. NGL just has Three set as a global dependency, so it doesn’t try to import it itself. If you look at the generated Javascript in (e.g.)build/js/ngl.esm.js
you’ll see import lines likeso you have to provide three in your
node_modules
so it can be imported.If I get some time I’ll try to put together a small webpack/three/NGL project but I’m pretty busy right now.