Hard. Render to Texture. 200 objects = 1 sprite x 7 copies. How to?

Not favoritedFavorited Favorited 0 favourites
  • 10 posts
From the Asset Store
Set of 200 hand drawn skill icons. All icons are of a high quality.
  • How to render a complex group of sprites (with blend modes) into a single flat image/texture?

    Hey everyone! I’m facing a really tough problem that seems easy to solve in other engines, but I’ve hit a massive wall in Construct 3.

    I'm developing a mobile game and struggling with UI optimization. I have a complex modular 2D car built from ~30 separate sprites with different Z-orders: body, interior, wheels, headlights, glass highlights, reflections, tires, rims, brakes, suspension, shadows, etc. Crucially, some of these layers (like drop shadows or window tints) use Blend Modes (Multiply, Add, etc.).

    In the main menu, I need to display 6-7 of these cars simultaneously as UI cards (exact miniature thumbnail copies of the assembled cars).

    Spawning real sprites for each card (30 parts × 7 cars = 200+ objects just for the UI) is completely out of the question—mobile devices will instantly drop frames. I need a way to "bake" (Render to Texture) the assembled car into a single flat image with a transparent background so I can just display it as a single sprite in the UI.

    Here is what makes it so difficult:

    Drawing Canvas issues: The Canvas refuses to handle this properly. Also, using Paste Object for 30+ individual parts per car is an absolute nightmare and leads to messy, unmanageable code.

    Dynamic generation: These 6-7 cars are not identical. They all have different colors, wheels, headlights, and interiors, reading data from an array.

    Coordinate math: The parts are attached to each other using specific offset coordinates from an array. Since the UI thumbnails are scaled down, all these offset coordinates have to be mathematically scaled down as well, which is extremely painful.

    Hierarchies don't work: Please don't suggest using Hierarchies. They don't help because cars might lack certain parts (e.g., no interior or missing spoilers), and checking every part inside a hierarchy loop causes even more issues.

    I've written massive formulas with loops to spawn cars, assign variables, and distribute parts, but it always breaks somewhere. Even AI assistants couldn't crack this task.

    How do you guys handle the "Render to Texture" problem for complex composite objects with transparent backgrounds in your projects? How can I properly merge a bunch of sprites with blend modes into one lightweight image without killing performance or breaking the alpha channel?

    I’d appreciate any ideas, workarounds, or plugins. By the way, I own the full Chadori plugin suite—is there anything in there that could help with this?

    Thanks in advance!

  • Oh it ate my message…

    Anyways, the two ways I know of to render to a texture is with a drawing canvas or with the snapshot canvas action.

    For the drawing canvas way and the amount of parts it would simplify things a lot to add all the part sprites to a family (say partFamily). Then to paste them by zorder it would be something like:

    for each partFamily ordered by partFamily.zorder ascending
    — drawingCanvas: paste partFamily

    That would use the blend modes just fine and the background would be transparent as long as the canvas started transparent before pasting.

    The second way would be to make the background transparent, snapshot the canvas, then wait till that finishes before changing anything back. That would capture things exactly as it’s rendered. To make the background transparent you’d basically have to make a transparent hole all the way down through the bottom layer. Easy way to do that could be to have all the parts on a transparent layer and make all the other layers invisible before snapshotting the canvas. Main con with that method is it will make a flicker since it has to render like that for at least a frame to snapshot.

    As to the other scaling stuff, it could be a non issue if you just render the cars at normal scale and then just scaling the image after. Or when placing parts just multiply the offsets and sizes by a scale when placing stuff. Third way would be to place everything at normal scale, then picking all the parts and scaling that. The part family would help with that. Scaling would just take a center position to scale around, a scale factor, and a few actions:

    Set x to (self.x-centerX)*scale+centerX
    Set y to (self.y-centerY)*scale+centerY
    Set size to (self.width*scale, self.height*scale)
  • Let's say I managed to save the entire car in the canvas, even though some layers are overlapping in the wrong order—but I think that's because I have the interior, parts, wheels, and so on on different layers.

    Another question is how can I load canvases of DIFFERENT cars from an array? For example, I have an array called `cars` that stores images from snapshots.

    1. How does it store them? More specifically, how do I save a canvas to an array?

    2. How do I load them from the array in a different order so that the car images appear in a row? (Like in the screenshot in the post.)

    I did `paste`, then `save snapshot`, and then used `load image from url Cars.At(0,26)`, where 26 is the row number for the image. But that didn’t work.

    And I can’t even load the snapshot back into the canvas. There’s a problem here. I have 6 cells where 6 cars should fit.

    Cars.At(0,26), Cars.At(1,26), Cars.At(2,26), and so on.

  • I don't think you can save the canvas directly to an array. IIRC, each canvas can only "hold" one image in its URL, so you probably need to save them to local storage then reference them in your array.

    EDIT - or load them straight into sprites - but that could cause memory issues if there’s many

  • Bear in mind that pasting and snapshotting are asynchronous so you have to wait for them to finish before you can get the result. So if using expressions to get a canvases imageurl or the imageurl of a snapshot are returning empty strings then those things weren’t done yet.

    If you wanted to store them in an array you’d save the imageUrls which are text. There is an expression for that, but in canvas I think you have to request it first. Snapshotting gives you that when it finishes by default. I’d suggest just loading them as frames in a sprite though. You can add frames to a sprite at runtime.

    I just assumed all the parts were on the same layer, but having multiple are no worries. Change the “for each” expression from “partFamily.zorder” to “partFamily.layerNumber*10000+partFamily.zorder”. Read that as order by layers and then zorder per layer. Although if you’re using sublayers with force own texture, and effects and blend modes on the layers then the pasting mode could be trickier.

    I can make an example later

  • Ok, I made an example for both snapshotting an area and pasting to the drawing canvas. I don't think I like either now, but they do both work.

    First this example just snapshots a section of the game canvas. Needed to use device coordinates, so had to convert layout coordinates to that. Had to erase a hole into the layout behind the objects before snapshotting to make it transparent. However, what I like the least about this is the resulting image is bigger. Oh well.

    dropbox.com/scl/fi/7e8itd97brskrcyujro1k/snapshot_to_image.c3p

    Second is drawing canvas method. Requires all pasted objects to be the same type or in a family. Pastes them in order of layer then zindex. It can also control the image size with the fixed resolution property of the canvas, which is useful.

    dropbox.com/scl/fi/jbhgyrodyy6oxhzvbs7at/drawingcanvas_to_image.c3p

    Pasting different types in order would need more work, probably inserting the layer,zindex and uid of everything into an array, sorting it, them looping over that. Pasting layers with blend modes or effects would need even more work, but I don't think that's really worth it.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • i think you can just creat one car at out of screen and creat 6 canvas. change car part sprite paste each canvas.so you only need set canvas position ti ui!!!!

  • idon.t know why c3 haven.t rendertexture tool. if c3 have this tool .you just need add a sprite and render each car part to sprite point pistion

  • if we want make blood on char body spirit it.s easy on other engine you just need render blood texture on char body sprite.but on c3 you may need creat a blood sprite and pin to char body .i think it.s a fool way to do it

  • How to render a complex group of sprites (with blend modes) into a single flat image/texture?

    The easy answer to this is to put them all on a layer with 'Force own texture' enabled.

    Spawning real sprites for each card (30 parts × 7 cars = 200+ objects just for the UI) is completely out of the question—mobile devices will instantly drop frames.

    Have you actually tested this? A few hundred objects is not actually a lot even for low-end mobile devices. Modern software and hardware is often a lot more powerful than people assume. For example this blog post from a few years ago references an Android device which is by now nearly 10 years old, and it could still manage thousands of on-screen sprites.

Jump to:
Active Users
There are 0 visitors browsing this topic (0 users and 0 guests)