On https://lume.io, the textures load fine in Chrome, Edge, and Safari, but Firefox does not load textures.
Chrome:
Firefox:
Have you experienced something like this before? Any ideas what to look into?
On https://lume.io, the textures load fine in Chrome, Edge, and Safari, but Firefox does not load textures.
Chrome:
Firefox:
Have you experienced something like this before? Any ideas what to look into?
Lots of WebGL warnings there, ending with “After reporting 32, no further warnings will be reported for this WebGL context.” – looks pretty likely to be related. Are the images power-of-two dimensions?
Looks like the textures loaded over the network are SVGs.
As far as I know THREE.js doesn’t support SVG textures, since it’s not a format that works in WebGL. There must be some kind of conversion going on in your app, I would imagine the SVG is drawn onto a canvas.
If that’s the case, as donmccurdy said, check what size these canvases are, they should be 256x256 or 512x512 or 1024x1024 etc.
Or you could even ditch the SVGs and use shader instead, looks like they’re fairly simple gradients so it shouldn’t take too much effort, and will save a tiny bit of bandwidth.
If that’s the case (I will check soon), does this mean one browser is handling things differently at some point in the pipeline? The code is the same regardless of browser.
There are differences in ImageBitmap and WebGL APIs, yes. A small/reproducible example would probably be necessary to identify what’s going on here.
I circled back to this. What I’m doing which is not working in firefox is passing the SVG URL directly to new TextureLoader().load(svgURL)
, and the rest is Three.js.
The viewBox on the SVG is 500 by 500 (not power of two).
The workaround so it works in all browsers is to render the SVG to a <canvas
> 2d, and then using a CanvasTexture
instead of TextureLoader().load(svgURL)
.
Note, regardless of the dimensions I set on the <canvas>
(even non power-of-two), the CanvasTexture
method works in all browsers.
The question for Three.js is, is there something we can do to fix new TextureLoader().load(svgURL)
in Three.js so the workaround is not needed in Firefox?
I might be wrong, but if it’s an SVG, the width
and height
must be defined. Chrome can render SVGs without these attributes, but Firefox requires them.
I just tried loading the SVG with <img>
(without specifying width
/height
attributes) in all browsers, and naturalWidth
/Height
is
The viewbox of the <svg>
in the .svg
files are set (f.e. 0 0 500 500
) so I’m not sure why browsers pick arbitrary other numbers. That seems odd.
Looking in WebGLTextures, we can see that it relies on the naturalWidth
/Height
of the Texture.image
(which for SVGs is inconsistent across browsers, 0 in FF) and falls back to the width
/height
(same values):
Looks like a solution to this is probably also (untested):
const tex = new THREE.ImageLoader().load(svgUrl, img => {
img.width = width
img.height = height
})
The issue isn’t with the texture loader but with how the browser interprets the SVG, and You may need a custom loader. First, load the SVG as a string and parse it. Then, compute and set the width
and height
attributes from the viewbox
, before loading the image.
Based on what you’re saying, I just tested in FF, and this did the trick, which is easier than the drawing to a canvas and using a CanvasTexture
:
const tex = new THREE.ImageLoader().load(svgUrl, img => {
img.width = 500
img.height = 500
})
Note, when drawing to canvas, I do not set the width/height of the image yet all browsers seem to draw to the canvas the same way! Huh?!
I only gave the canvas a width/height but not the image, so this indicates there’s some common way that all browsers are getting the image dimensions when drawing to canvas, however they do not share the same logic when using a standalone Image
(Firefox being able to draw to canvas despite the zero dimensions).
Some more browser bugs need filing to make the behavior consistent.