3dmol / 3Dmol.js

WebGL accelerated JavaScript molecular graphics library
https://3dmol.org/
Other
790 stars 192 forks source link

Errors when trying to load a lot of models #538

Closed rodrigoalcarazdelaosa closed 2 years ago

rodrigoalcarazdelaosa commented 2 years ago

[:LABEL:] I'm not sure if this could be a BUG.

Description I have included a lot (62 actually) of models in my website here (source here). I have checked that all models load fine when including them one by one (testing it locally). But once they're all there, the models won't load. As you can see in the console, I'm getting a lot of these errors:

TypeError: Argument 1 ('shader') to WebGL2RenderingContext.shaderSource must be an instance of WebGLShader
45sentryWrapped — helpers.ts:111

Relevant Context I'm loading the same models in these slides (source here) and weirdly I can see some models, but most of them not.

I'm using version 1.7.0 of 3Dmol.js and I'm testing it with both Google Chrome v94 and Safari v15 on macOS 11.6.

Thank you very much in advance, Rodrigo

dkoes commented 2 years ago

Can you explain how I can build your website locally? I've installed hugo and go and when I run view.sh this is what I get and no server seems to be launched (I've never used hugo before):

$ ./view.sh 
WARN 2021/10/17 11:40:41 Module "github.com/wowchemy/wowchemy-hugo-modules/wowchemy/v5" is not compatible with this Hugo version; run "hugo mod graph" for more information.
Start building sites … 
hugo v0.88.1-5BC54738 linux/amd64 BuildDate=2021-09-04T09:39:19Z VendorInfo=gohugoio
ERROR 2021/10/17 11:40:42 render of "page" failed: execute of template failed: template: widget_page/single.html:5:3: executing "widget_page/single.html" at <partial "site_head" .>: error calling partial: "/home/dkoes/git/fisiquimicamente/layouts/partials/site_head.html:208:58": execute of template failed: template: partials/site_head.html:208:58: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css"
ERROR 2021/10/17 11:40:42 render of "page" failed: execute of template failed: template: widget_page/single.html:5:3: executing "widget_page/single.html" at <partial "site_head" .>: error calling partial: "/home/dkoes/git/fisiquimicamente/layouts/partials/site_head.html:208:58": execute of template failed: template: partials/site_head.html:208:58: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css"
ERROR 2021/10/17 11:40:42 render of "page" failed: execute of template failed: template: widget_page/single.html:5:3: executing "widget_page/single.html" at <partial "site_head" .>: error calling partial: "/home/dkoes/git/fisiquimicamente/layouts/partials/site_head.html:208:58": execute of template failed: template: partials/site_head.html:208:58: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css"
ERROR 2021/10/17 11:40:42 render of "page" failed: execute of template failed: template: widget_page/single.html:5:3: executing "widget_page/single.html" at <partial "site_head" .>: error calling partial: "/home/dkoes/git/fisiquimicamente/layouts/partials/site_head.html:208:58": execute of template failed: template: partials/site_head.html:208:58: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css"
ERROR 2021/10/17 11:40:42 failed to render pages: render of "page" failed: execute of template failed: template: widget_page/single.html:5:3: executing "widget_page/single.html" at <partial "site_head" .>: error calling partial: "/home/dkoes/git/fisiquimicamente/layouts/partials/site_head.html:208:58": execute of template failed: template: partials/site_head.html:208:58: executing "partials/site_head.html" at <resources.Concat>: error calling Concat: resources in Concat must be of the same Media Type, got "text/x-scss" and "text/css"
Error: Error building site: TOCSS: failed to transform "main_parsed.scss" (text/x-scss). Check your Hugo installation; you need the extended version to build SCSS/SASS.
Built in 2750 ms

I suspect there is either a race condition with initializing the viewers or a failure to properly account for viewers that are hidden.

rodrigoalcarazdelaosa commented 2 years ago

Can you explain how I can build your website locally? I've installed hugo and go and when I run view.sh this is what I get and no server seems to be launched (I've never used hugo before):

You'll need to install Hugo Extended. With that and go you should be able to clone my repo and execute ./view.sh as you did and it will build the website. After that you'll want to navigate to http://localhost:1315/recursos-fisica-quimica/apuntes/formulacion-nomenclatura-quimica/organica/ to see the page with the models. Alternatively, you can go to http://localhost:1315/recursos-fisica-quimica/apuntes/formulacion-nomenclatura-quimica/organica/diapositivas/ to see the slides (Diapositivas in Spanish), where the models are not hidden.

Please let me know if you have any problem and thank you very much for your time.

Rodrigo

dkoes commented 2 years ago

The spoiler tag in your page hides the embedded content by setting its size to zero (as opposed to leaving it the right size and setting display: none). You can't create a zero sized WebGL canvas, so that was causing the initial problem. With the fix above (d3c8de41e83458d0d96f077dad58c25e4082ba40) your page works nicely in firefox.

However, it still has issues in Chrome. This is because there is a maximum number of allowed WebGL contexts (in theory it is 16 for both chrome and firefox, but firefox seems happy to display many more than that). You will see the message "WARNING: Too many active WebGL contexts. Oldest context will be lost." in the console when this happens. So you only end up with the 16 molecular viewers that were created last.

This is a hard browser limit, however, we can work around it a bit. I've pushed a change (4e72ea878b1e1351419e4317e4e0c2e42949d30c) that will regenerate a lost canvas on a resize event. This means when the spoiler tag is expanded the embedded viewer, if it has been lost, will be recreated and you'll be able to see it. However, if the user expands enough spoiler tags that >16 viewers are on the page at once then the least recently expanded ones will be deactivated (but they can reset them by toggling the spoiler).

A fancier fix is to catch the lost context event and replace the webgl context with a png image. Then when a user tries to interact with it, regenerate the 3D context. However, obviously the disabled context wouldn't be spinning. This is Issue #292

rodrigoalcarazdelaosa commented 2 years ago

Thanks a lot David! That was quick. I guess I can get access to those fixes using the latest version, i.e., loading the script with this line?

<script src="https://3Dmol.csb.pitt.edu/build/3Dmol-min.js"></script>

I tested it locally but it seems it's not working (I cleared my cache just in case). For now I think I'll be quite happy with those fixes.

Thank you very much again, Rodrigo

dkoes commented 2 years ago

I just updated the webserver version. Try again.

dkoes commented 2 years ago

BTW, really beautiful website.

rodrigoalcarazdelaosa commented 2 years ago

I just updated the webserver version. Try again.

It's working now! You're awesome! Now, if #449 could be addressed, so the molecules stretch to the size of their parent div, then I'd be golden. I've also seen that, when browsing the slides, which use reveal.js, in mobile, the div element is not centered and doesn't respect width: 100% (you can check this one for example, browsing with a phone), although I guess this doesn't have to do with 3Dmol. I'll keep investigating it.

Thank you very much again for the quick fixes and for such an awesome piece of software 3Dmol.js is.

BTW, I'm loading all models locally from my repo (downloading the sdf files) as requesting them from PubChem (using the CID) was giving me errors too (too many requests). Is there a workaround to that issue? Thanks again!

rodrigoalcarazdelaosa commented 2 years ago

BTW, really beautiful website.

So happy you like it. I'm putting a lot of effort to make it look nice and be useful and interesting. The English version is still way behind the Spanish one, but some day all the content will be translated.

rodrigoalcarazdelaosa commented 2 years ago

However, it still has issues in Chrome. This is because there is a maximum number of allowed WebGL contexts (in theory it is 16 for both chrome and firefox, but firefox seems happy to display many more than that). You will see the message "WARNING: Too many active WebGL contexts. Oldest context will be lost." in the console when this happens. So you only end up with the 16 molecular viewers that were created last.

Is the grid viewer available when embedding? Would it help with this issue?

rodrigoalcarazdelaosa commented 2 years ago

BTW, I'm loading all models locally from my repo (downloading the sdf files) as requesting them from PubChem (using the CID) was giving me errors too (too many requests). Is there a workaround to that issue? Thanks again!

BTW, the possibility of using data-cid to load models from PubChem should be documented here. I thought that only data-pdb was possible, and was loading them using data-href.

dkoes commented 2 years ago

Sorry.. this got stuck in an email backlog.

A GridViewer let's you show multiple scenes using a single WebGL canvas, so it reduces the number of canvases you need, but it only applies if you want the viewers all right next to each other (in a grid).

One way to hid the canvas limitation from your website users with your site design would be to collapse the other viewers (spoiler tags) when a new one is opened.

Or you could catch the context lost event and collapse the spoiler tag of the offending context.

I've updated the documentation with data-cid

rodrigoalcarazdelaosa commented 2 years ago

A GridViewer let's you show multiple scenes using a single WebGL canvas, so it reduces the number of canvases you need, but it only applies if you want the viewers all right next to each other (in a grid).

Is there an easy way to use the GridViewer when embedding? I don't see much documentation about it. Thank you!

dkoes commented 2 years ago

Sorry - meant to answer that. No, there's currently no support for grid viewers when embedding.