sallf Posted August 30, 2021 Share Posted August 30, 2021 I'm trying to create multiple textures, with different resourceOptions, based on a single svg. Here's what I've tried so far: 1. Using `fromUrl` (& `from`) const texture1 = PIXI.Texture.fromURL('./some.svg', { resourceOptions: { width: 10, height: 10, }, }); const texture2 = PIXI.Texture.fromURL('./some.svg', { resourceOptions: { width: 100, height: 100, }, }); In this case, texture2 just returns the texture1 from TextureCache. 2. Using the loader let resources; loader .add('texture1', './some.svg', { metadata: { resourceOptions: { width: 10, height: 10, }, }, }) .add('texture2', './some.svg', { metadata: { resourceOptions: { width: 100, height: 100, }, }, }) .load((_, resources) => { resources = resources; }); This works but gives the warnings "BaseTexture added to the cache with an id that already had an entry" and "Texture added to the cache with an id that already had an entry". This also adds 3 entities to the TextureCache: `http:.../some.svg`, `texture1` and `texture2` which seems strange. Should I just ignore this warning, or is there a way to provide a unique id? Ultimately, what I want to be able to do is cache an svg file from the server, create a single texture from it (so I can grab the original width/height of the svg - so I know the aspect ratio), and use that to create multiple textures that are proportionally sized, as the app determines they are needed. Maybe there's another way to approach this? Any help appreciated! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted August 31, 2021 Share Posted August 31, 2021 pixi "texture cache" is an easy things - it adds texture to the map. Just look where its done in source code. There's no docs, no articles, ande every time someone stumbles across it the answer is only one - look in the source code. I usually dont use cache at all and empty it every time with "utils.clearTextureCache" and basetexturecache too. This thing is not needed. As for multiple levels - you can try upload those to different mip levels in webgl texture, in that case you can make Texture Resource (look example with gradient, but add bot texImage2d's on different levels). You can also do it manually, just specify different resolutions (i mean dpr) in baseTexture, again, no articles or demos, you have to be the one who'll make it and share with other people previous guys failed to do that. Usually resolution goes 1,2,4,8, e.t.c. by powers of 2. Quote Link to comment Share on other sites More sharing options...
sallf Posted September 3, 2021 Author Share Posted September 3, 2021 @ivan.popelyshevthanks for sharing some thoughts! I had seen a few instances where people used url params to beat Pixi returning a cached version, and I think was talking more about "network" caching. The below code works fine, but I think it makes 2 requests to the server for the same asset. Obviously this is not Pixi related, except that I might have expected to be able to pass an `id` or other argument to return a different texture from the same URL. const texture1 = PIXI.Texture.fromURL('./some.svg?width=10&height=10', { resourceOptions: { width: 10, height: 10, }, }); const texture2 = PIXI.Texture.fromURL('./some.svg?width=100&height=100', { resourceOptions: { width: 100, height: 100, }, }); I believe this is the gradient example you referenced? Mipmaps were an interesting suggestion, but after exploring it for a while, I think I'm looking more for 'on demand' sizing as opposed to 'responsive'... Though, maybe they are the same thing and I just couldn't figure out how to do that with BaseTextures. Ultimately what seems to be working best for me is creating an `SVGResource` and using its `load` method to get the resource and create a texture out of it. I'm building in react, so I implemented it as this hook below. You mentioned that you usually clear the texture cache every time, so I'm doing the same :). export const useSvgTexture = (url, width = null, height = null) => { const [texture, setTexture] = useState(null); useMountEffect(() => { const params = {}; // Typically it's best to pass only width or height and the resource // will scale proportionally if (width) params.width = width; if (height) params.height = height; const resource = new PIXI.SVGResource( url, params, ); resource.load().then((res) => { const txt = PIXI.Texture.from(res); PIXI.utils.clearTextureCache(); setTexture(txt); }); }); return texture; }; I need to close some open tabs, so here are some related discussions for anyone else looking for related help ... most of which are Ivan providing the best answers Scaling SVG before rasterizing Mazilla WebGL best practices - Mipmaps Learning Pixi - A little more about loading things Pixi - Manually setting texture mipmap levels Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.