1
\$\begingroup\$

I want to achieve a system where I can use render textures as portraits/icons. So when I select something I want to show it in my UI, currently I do:

  1. Spawn my prefab with the model (I have one of these prefabs for each model), in my case this prefab has a camera (for render texture), a model, and a spotlight.
  2. Show this render texture in my UI

This is fairly straight forward when I only need one render texture at a time. But say I select a house and want to see all residents, now I need 6-10 render textures all showing different models.

Should I create/destroy render texture assets at runtime for this type of feature, since each camera would need its own render texture? Im worried its an expensive feature that costs more than its worth perhaps.

Or do I need to create one render texture asset for each model in my game, and simply point to it in the prefab mentioned above?

Is there a smarter way?

\$\endgroup\$
5
  • 1
    \$\begingroup\$ It sounds like you could have 10 render textures reserved for this purpose, and deal them out from a pool on demand. Or a single render texture that you render multiple images into, like a sprite sheet, then display just the portion of it you want for each icon. \$\endgroup\$
    – DMGregory
    Commented Oct 13, 2020 at 16:29
  • \$\begingroup\$ The smarter way is to have a pool of render textures. Whenever you invoke this feature, you find an available render texture from the pool and use it. When you are done, you release it back to the pool. A little heavier on the management side, but saves the constant instantiation and destroying of the render textures. E: Got beaten by a minute ;P \$\endgroup\$
    – sirreldar
    Commented Oct 13, 2020 at 16:30
  • \$\begingroup\$ How do you pool an asset? And how would you determine if its in use? \$\endgroup\$
    – Majs
    Commented Oct 13, 2020 at 16:31
  • \$\begingroup\$ I guess I could create a Component like "PoolableRenderTexture" with a reference to a render texture for the pool. And just use the inactive ones. \$\endgroup\$
    – Majs
    Commented Oct 13, 2020 at 16:38
  • 1
    \$\begingroup\$ Note that Unity maintains its own pool you can access with RenderTexture.GetTemporary() — I'm just not sure if there are any restrictions on how long you can hold a "temporary" render texture. \$\endgroup\$
    – DMGregory
    Commented Oct 14, 2020 at 11:16

1 Answer 1

1
\$\begingroup\$

This likely comes down to a design choice. Given the system you described, it sounds like you are using pretty small render textures, maybe 256x256 or 512x512 at the worst, and you currently expect 6-10 textures at a time (lets say 20 in case you need some for the future). Personally I would consider one of the following options:

1.) Creating and destroying render textures as needed is technically okay (you may run into a small frame drops depending on resolution and number for render textures). So you can probably keep going as is so long as you are not using HDRP (cameras get expensive fast in HDRP).

2.) Use render texture pools to avoid the frame drop in creating up to 20 render textures. This doesn't solve the HDRP camera issue but should be okay in URP so long as you don't get too crazy with additional cameras (think I tested up to 50 or with a 1080 on Windows). There should be many examples of how to do object pooling online, combine this with a singleton pattern so you can grab them from anywhere in your game as needed.

3.) Create one dedicated camera that renders only game objects on the portraits layer and have a script that moves special character portrait prefabs into position so you can render out a single render texture Atlas of all portraits needed at the moment. This should eliminate all costs associated with creating new render textures, new cameras, and most camera render time (you still need one). This is the approach I normally take for HDRP projects when I need to do stuff like rendering text in Visual Effect graphs. It's tricky to setup but should work in most cases. Just make sure your render texture is the size of "portraitResolution.X x textureAtlasColumnCount, portraintResolution.Y x textureAtlasRowCount". So for 20 rendertextures at 256x256 that would be roughly 1280x1024 or 2560x2048 at 512x512 with 5 images per row and 4 rows. To use these images you can adjust the UV offset on any materials that take the texture atlas as a texture.

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .