barrard Posted July 27, 2021 Share Posted July 27, 2021 (edited) Hello all, thanks for taking time to read my post. I have an app where users draw shapes in an SVG editor to create objects. Then the shapes are rendered in Pixi to create an animation. We used to do the animation in SVG land but Pixi has better performance. The main issue I'm having right now is my rounded rect corners are not coming out smooth when I try to display in Pixi via the Graphics object, and we have also tried to rasterize the SVG to an image. This is the SVG editor where users create shapes and place them to create objects And this is what Pixi is rendering via the Graphics object. Here is how I init the Pixi App. ``` this.app = new PIXI.Application({ resolution: window.devicePixelRatio, antialias: true, autoDensity: true, width: this.elRef.current.clientWidth, height: this.elRef.current.clientHeight, backgroundColor: 0x666666, })``` and to draw each shape shapes.forEach(shape => { let { color, opacity, width, length, borderRadius, borderThickness, borderColor, x, y } = shape color = PIXI.utils.string2hex(color) x = centerX + x - width / 2 y = centerY + y - length / 2 Gfx.beginFill(color, opacity) Gfx.lineStyle(borderThickness, borderColor) Gfx.drawRoundedRect(x, y, width, length, borderRadius) Gfx.endFill() }) let texture = this.app.renderer.generateTexture(Gfx) Thanks again for any help! EDIT: Originally I was using a raterize approach, where I would render the SVG element into an `<img/>` tag, but it was also giving blurry results. SVG RASTERIZE VERSION Here is example code for this let svg = ( <svg width={totalWidth} height={totalLength} // x={isPerson ? 35 : 0} // y={isPerson ? -35 : 0} viewBox={isPerson ? `0 0 ${172} ${172}` : null} xmlns='http://www.w3.org/2000/svg' > <defs>{patterns}</defs> <rect className='rect single-resizer' width={width} height={length} x={leftAdj} // strokeWidth / 2 y={topAdj} // strokeWidth / 2 opacity={__typename === 'Zone' ? '0.5' : '1'} fill={color} style={{ strokeWidth: __typename === 'Structure' ? 0 : borderThickness, // borderThickness, stroke: '#000000', }} /> let svgRender = ReactDOMServer.renderToStaticMarkup(svg) let blob = new Blob([svgRender], { type: 'image/svg+xml' }) let url = URL.createObjectURL(blob) var img = new Image() img.src = url //nd then making my texxture const base = new PIXI.BaseTexture(img) let texture = new PIXI.Texture(base) Edited July 27, 2021 by barrard ivan.popelyshev 1 Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted July 27, 2021 Share Posted July 27, 2021 (edited) Do you know about https://github.com/pixijs/graphics-smooth ? you can use it without antialias. Edited July 27, 2021 by ivan.popelyshev Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted July 27, 2021 Share Posted July 27, 2021 The problem with Graphics inside a renderTexture is that it doesnt have antialias, you have to use tricks with new MSAA support (only in webGL2!) , like here for the circle: https://pixijs.io/examples/#/plugin-picture/blend-modes.js graphics-smooth is alternative - it uses mega-shader, its faster than antialias, but it has some problems on fills. Quote Link to comment Share on other sites More sharing options...
barrard Posted July 27, 2021 Author Share Posted July 27, 2021 Thanks for the response Ivan. This helped a bit as you can see. Is there some kind of resolution option I can adjust? Or other trick, like maybe generate the Graphic as very large then reduce to normal size to get a crisper render? Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted July 27, 2021 Share Posted July 27, 2021 I see the upscale. Something is definitely wrong with your case. Remove the upscale problem and it should work fine. Please post minimal reproduction if you dont understand what is upscale Quote Link to comment Share on other sites More sharing options...
barrard Posted July 27, 2021 Author Share Posted July 27, 2021 Upscale? I would love to try and trow together a minimal demo, but I think I found some more clues that may help. I found that when i do render.generateTexture(Gfx) I can also add some scale and resolution params, so I got a much better render now with this.app.renderer.generateTexture( Gfx, PIXI.SCALE_MODES.LINEAR, 10 ) The shapes I'm drawing are coming from SVG properties. Our SVG editor can only do squares (currently), so to make circles we just add border radius. Do you know if the borderRadius of an SVG maps well to a Graphics.drawRoundedRect? Looks like the border radius is not playing well maybe? Thanks again for your help Ivan! Quote Link to comment Share on other sites More sharing options...
ivan.popelyshev Posted July 27, 2021 Share Posted July 27, 2021 if you use that texture in a sprite that will be scaled 10 times, then yes, you need resolution 10 SVG is always pain when you work with it in canvas2d or webgl. So far no one made universal solution, there are always problems with scaling. As for border-radius, i think you can make minimal example of what you want for it? 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.