Hi,
I seem to be having a problem with Firefox 76 using a texture from an SVG that is already loaded in the browser (I’m on macOS Catalina, haven’t tried Windows / Linux).
In Chrome (v84) and Safari (v13.1), the code works perfectly, and I see both the SVG and a three.js scene containing a cube with the SVG texture on it.
In Firefox, I see just the SVG, and an empty three.js scene (although it’s probably a scene with a cube that has no texture).
Here’s the code of the SVG file, firefoxSvgTest.svg
:
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 400">
<defs>
<radialGradient id="A" cx="2350.96" cy="-538.75" r="121.43" gradientTransform="matrix(-2.1, -1.56, 1.99, -1.58, 6244.43, 2993.03)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ff0000"/>
<stop offset=".2" stop-color="#00ff00"/>
<stop offset=".4" stop-color="#0000ff"/>
<stop offset=".6" stop-color="#ffff00"/>
<stop offset=".8" stop-color="#00ffff"/>
</radialGradient>
</defs>
<path d="M0 0h400v400H0z" fill="url(#A)"/>
<path d="M100 100.7h200v200h-200v-200z" fill="#fff"/>
</svg>
And here’s my test harness:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Firefox texture bug</title>
<script type="text/javascript" src="three.116.master.js"></script>
<script>
window.addEventListener('load', () => {
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 0.1, 1000 );
const renderer = new THREE.WebGLRenderer();
renderer.setSize( 400, 400 );
document.body.appendChild( renderer.domElement );
const ambientLight = new THREE.AmbientLight( 0xffffff );
scene.add( ambientLight );
const cubeTexture = new THREE.Texture(
document.getElementById('svgTexture'),
THREE.UVMapping,
THREE.RepeatWrapping,
THREE.RepeatWrapping
);
cubeTexture.needsUpdate = true;
const cubeMaterial = new THREE.MeshPhongMaterial( { map: cubeTexture, side: THREE.DoubleSide } );
const cubeGeometry = new THREE.BoxBufferGeometry( 2, 2, 2 );
const cubeMesh = new THREE.Mesh( cubeGeometry, cubeMaterial );
cubeMesh.rotation.x = 0.5;
cubeMesh.rotation.y = 0.5;
scene.add( cubeMesh );
camera.position.z = 5;
renderer.render( scene, camera );
}, false);
</script>
</head>
<body>
<img id="svgTexture" src="firefoxSvgTest.svg" style="width:400px; height:400px;">
</body>
</html>
I’m running this through a web server with the HTML file, SVG file, and three.js files all in the same folder - so there are no file://
or CORS issues at play here.
The only thing showing in the Firefox console is the same as in Chrome and Safari: a warning that the texture has been resized from 400x400 down to 256x256, so I’ve got no errors to give me a hint as to why this isn’t working.
This doesn’t seem to be an issue with the radial gradient, as I can replace the SVG code with that containing just a single path filled with a solid colour, and the outcome is the same.
Can anyone see where I’m going wrong, or is this a bug with Firefox?
Incidentally, I’m only using this method as I couldn’t figure out how to get a radial gradient in three.js (the square shape drawn on top of the gradient is irrelevant, I just wanted to prove it wasn’t the lack of a solidly-filled path causing the problem)… so if anyone knows of a way to get a radial gradient texture, I can stop using the SVG altogether. However, it would be nice to get to the bottom of this issue!
Here’s how the code looks in Chrome and Firefox when run:
Chrome
Firefox
Thanks,
Dan