26
$\begingroup$

Using a single 6K texture at only 227kb in size, spikes the memory usage to a crazy 144mb of memory in Blender.

It was brought up in this bug report, but closed.

Why can image editors (Photoshop/Gimp/Krita) handle such large images but not Blender?

Whats going on, and more importantly, what can be done to improve it?

$\endgroup$
2
  • 26
    $\begingroup$ :O Nice to see you here! Welcome :) $\endgroup$
    – gandalf3
    Commented Mar 26, 2015 at 6:38
  • 10
    $\begingroup$ Well yeah... 6000 pixels * 6000 pixels * 4 bytes/pixel = 144MB. $\endgroup$ Commented Mar 26, 2015 at 21:29

2 Answers 2

37
$\begingroup$

3D applications often needs to have images directly accessible, that is - to be able to look up a pixels value instantly. common cases are:

  • Rendering a texture on a 3D model (applies to any render engine).
  • Load the image into OpenGL memory (where the image is sent 'complete' to the graphics-card).

Since a 3D application is a less controlled environment (than a game-engine or 2D-paint-tool for example) - an image may be used for a modifier displacement map, composite node input, a background in the view-port or be painted onto - all at once. This means we have some constraints which make it harder to optimize for any single use-case.

Even so, there are strategies for better handling texture memory.

  • Free images from memory which aren't used often.
  • Load lower resolution versions of the image into memory (mipmaps).
  • Load partial regions of the image into memory.
  • Support in-memory compression (often used for OpenGL textures).
  • Support for lower bit-depth of channel options (monochrome, greyscale, limited color palette, index-color).

Blender specifics

What Blender does now

  • Images are freed from OpenGL memory if they aren't used
    see: User Preferences -> System -> Texture Time-Out
  • Persistent images (Cycles only), disable so images are freed between renders.

How Blender could be improved

  • Avoid loading large images
    This would likely mean caching mipmaps.
  • Avoid loading the entire image
    This was implemented for 'Sintel' in the render branch, but was never included in a release.
    see: http://wiki.blender.org/index.php/Dev:2.5/Source/Render/RenderBranch/ImageTileCache
  • Better memory management, free images from memory (use a time-out similar to what we already have for OpenGL).
  • Support OpenGL texture compression.
  • Support loading textures into OpenGL memory, and freeing from system memory.
  • Implement the same 2D tile-based systems used by image image editors,
    (but only use it for 2D-painting).

Comparisons with other fields

Games

Games have the advantage that textures can be pre-processed, compressed on-disk to be sent directly to the graphics-card in formats you wouldn't necessarily be able to open for editing.

They typically don't have to operate under the assumption that any texture may be painted or edited at any time.

See: https://www.opengl.org/wiki/S3_Texture_Compression

Image Editors/Painting Tools

Don't have to load the texture into graphics-memory to display on 3D models, so they can use their own in-memory representation of images.

They also have the advantage that each image view has a single zoom-level, (unlike a texture mapped to a 3D-mesh, which may need to access multiple mip-maps at once). So they can - for example, streamline managing multiple tile-sets at different zoom levels.

See notes on krita's tile manager: http://dimula73.blogspot.com.au/2014/07/notes-from-calligra-sprint-part-2.html


Note, the on-disk size of an image isn't all that meaningful. if a 6k texture only takes ~200kb - Its likely not very detailed, a single color image or highly compressed (lossy).

You can ZIP a .txt file with your name written a million times into a few kb, but try editing this as an email :)

$\endgroup$
6
  • $\begingroup$ Wow. Now that's a thorough answer. Thanks Campbell! As good as it is to know the reasons, I'm definitely more interested in what can be done to fix it. Of your proposed solutions, are there any that you know are planned for the future? If not, do you know which option would be easiest to implement? $\endgroup$ Commented Mar 27, 2015 at 2:58
  • $\begingroup$ Neither are planned, which is most useful depends on the use-case: 1) for large textures you mostly see at a distance -- a way to only load lower resolution mip-maps into memory. 2) For large textures you only ever view a small region of (such as a high resolution 360° matte painting used as a backdrop) -- support for loading only small regions into memory (or have a more general system which can page tiles into memory and free them as needed). Other may have suggestions too, but these seem like changes we'd have to make if you simply want a single large image using less memory. $\endgroup$
    – ideasman42
    Commented Mar 27, 2015 at 3:36
  • 3
    $\begingroup$ Maybe if we hold off a year or two - the problem goes away :) bloomberg.com/news/articles/2014-06-12/… $\endgroup$
    – ideasman42
    Commented Mar 27, 2015 at 3:48
  • $\begingroup$ Some progress here (for Cycles), developer.blender.org/D1215 (Will be in 2.75, or any daily build from now on) $\endgroup$
    – ideasman42
    Commented Apr 8, 2015 at 2:37
  • $\begingroup$ Ideasman42, have a look at Mari. 30 GB per channel (500 patches of 4k) and 30 channels - for 900 GB of paintable texture loaded at one time. They can paint multiple channels at once. That is all doable on 1 GB texture memory and 2GB main memory computer. They can project 16k textures onto the model. thefoundry.s3.amazonaws.com/downloads/CaseStudy_Mari_Avatar.pdf $\endgroup$
    – Tom M
    Commented Jul 25, 2015 at 20:41
15
$\begingroup$

Blender loads the whole texture uncompressed into the RAM to have better load times for the renderer. Let's see how far off we are.
By 6k texture I think you mean a 6144 × 6144 pixel texture. That is 37748736 pixels with 4 channels (RGBA) and assuming each channel has 8 bits of information (e.g. JPG, most PNGs), it needs 37748736 × 4 × 8 = 1207959552 bits.

Now let us break it down to a readable number:
1207959552/8/1024/1024 = 144 Megabyte.

So you may have a 227kb compressed texture on your HDD, but 144 Mb raw RGBA data in your RAM.
So why does image editor maybe handle big sized textures better? Ether 2 reasons, they don't or they stream it from your HDD which should be painfully slow.

edit: To answer your question. There is not much that can be done to improve memory usage as you need the raw RGBA values to make something useful with those textures.

Best regards
Wasabi

$\endgroup$
3
  • $\begingroup$ 2D editors usually use downsampled copy of texture during editing, unpacking more when you zoom in or save. $\endgroup$ Commented Mar 26, 2015 at 17:17
  • 4
    $\begingroup$ Your math is slightly off, since the texture is probably has a length 6*1024=6144 pixels, not 6072. Once you change that, it works out to exactly 144MiB. (As a nitpicker I must note that a lowercase b is used for bits. B is for bytes.) $\endgroup$ Commented Mar 26, 2015 at 19:13
  • $\begingroup$ Edited with correct math. $\endgroup$
    – Greg Zaal
    Commented Apr 7, 2015 at 10:35

You must log in to answer this question.

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