22

I'm trying to make a game using SVG images for scalability and for procedurally making physical objects from them (see matter.js for how).

The problem I'm having is if I load 2 different SVG textures and then render them, the second has the first layered underneath it.

This doesn't happen with raster images and doesn't happen with the canvas options, only with WebGL.

Is there a way to stop this or am I doing the SVGs wrong?

var renderer = PIXI.autoDetectRenderer(
    window.innerWidth, 
    window.innerHeight, 
    {
        backgroundColor : 0xffffff,
        resolution:2
    }
);

// add viewport and fix resolution doubling
document.body.appendChild(renderer.view);
renderer.view.style.width = "100%";
renderer.view.style.height = "100%";

var stage = new PIXI.Container();

//load gear svg
var texture = PIXI.Texture.fromImage('https://upload.wikimedia.org/wikipedia/commons/thumb/0/0b/Gear_icon_svg.svg/2000px-Gear_icon_svg.svg.png');
var gear = new PIXI.Sprite(texture);

//position and scale
gear.scale = {x:0.1,y:0.1};
gear.position = {x:window.innerWidth / 2,y:window.innerHeight / 2};
gear.anchor = {x:0.5,y:0.5};

//load heart svg
var texture2 = PIXI.Texture.fromImage('https://upload.wikimedia.org/wikipedia/commons/thumb/4/42/Love_Heart_SVG.svg/2000px-Love_Heart_SVG.svg.png');
var heart = new PIXI.Sprite(texture2);

//position and scale
heart.scale = {x:0.1,y:0.1};
heart.position = {x:window.innerWidth/4,y:window.innerHeight / 2};
heart.anchor = {x:0.5,y:0.5};

//add to stage
stage.addChild(gear);
stage.addChild(heart);

// start animating
animate();
function animate() {
    gear.rotation += 0.05;

    // render the container
    renderer.render(stage);
    requestAnimationFrame(animate);

}
<script src="https://github.com/pixijs/pixi.js/releases/download/v4.8.2/pixi.min.js"></script>
Neuron
  • 5,141
  • 5
  • 38
  • 59
Dakun Skye
  • 580
  • 1
  • 4
  • 14
  • This sounds like a browser and/or pixi.js bug. Are you still seeing this behavior? – nnyby Aug 29 '18 at 12:21
  • It's not clear what you mean by "The problem I'm having is if I load 2 different SVG textures and then render them, the second has the first layered underneath it." is it that you can see through your svg? is it a transparent svg? can you add a screenshot highlighting the problem? – lucascaro Oct 31 '18 at 02:47
  • I dont understand why do you want to use an SVG as a texture. why don't you just import the .png that is inside that SVG directly? In WebGL there's no concept of vector images. – andrevenancio Nov 08 '18 at 23:45
  • I believe the example provided by the question is using PNGs, not SVGs. Look at the URLs passed to `PIXI.Texture.fromImage()`. The URLs end in `2000px-Gear_icon_svg.svg.png` and `2000px-Love_Heart_SVG.svg.png`. These are PNG files, not SVG files. So... whatever behavior is going on here, I suspect it has nothing to do with SVGs vs PNGs. Nor do I understand why the behavior is incorrect. – mpb Jun 04 '20 at 23:17

2 Answers2

17

Well, this example seems to work pretty well!

var beeSvg = "https://s3-us-west-2.amazonaws.com/s.cdpn.io/106114/bee.svg";
beeTexture = new PIXI.Texture.fromImage(beeSvg, undefined, undefined, 1.0);
var bee = new PIXI.Sprite(beeTexture)

See more at: https://codepen.io/osublake/pen/ORJjGj

Neuron
  • 5,141
  • 5
  • 38
  • 59
sparkyspider
  • 13,195
  • 10
  • 89
  • 133
10

So I think you're mixing concepts a bit.

SVG is one thing and WebGL is another. SVG's are rendered by the browser and you can scale them up or down without losing quality/resolution or whatever you want to call it.

This characteristic however is not possible in WebGL because WebGL rasterises images. A bit like taking a screenshot and putting it in a layer on Photoshop. You can manipulate that image, but u can't scale it without starting to see the pixels.

So short answer is, you can't use SVG's in a WebGL hoping to make your graphics "scale".

In regards to your example above, the result is the expected.

You are loading 2 png textures and overlaying them.

andrevenancio
  • 494
  • 4
  • 19
  • You can convert an SVG to a texture, but when you provide to WebGL you still are providing an image. jpg, png not svg. if that is you're point, yeah you can convert an svg to a jpg and feed that jpg back. but you can't provide an svg where an image is expected. nor a string or other data types and expect it to work – andrevenancio May 14 '20 at 08:43
  • 1
    PIXI can do that, but for example three.js can't. So behind the scenes they convert an SVG to a image. But the GPU doesn't accept svgs, that was my only point. This is an issue where the adding the feature was discussed. https://github.com/pixijs/pixi.js/issues/4128 – andrevenancio May 14 '20 at 08:45