Tiled EXR / texture caching support?

Agree, this is a very interesting feature to save memory :slight_smile:

2 Likes

Hi folks! Any news? 2.93??

UDIM support is already there. Adding this is the final piece we need

2 Likes

Hello everyone !
I add my voice for this feature, which is very much needed.

2 Likes

The CYCLES_TEXTURE_CACHE branch seems to be alive. Some commits by Stefan Werner during the last few days.

I just compiled from source and I really like the results. For me a working texture cache really is a feature that could catapult Cycles to the next level.

At the moment it’s not working with GPU rendering but it’s very easy to use (the textures are auto-converted to tiled and mipmapped tx files if they don’t already exist) and renders with super low memory requirements. I just quickly tested a simple plane with some 8k textures on it and the difference in memory usage is from 1.5GB (vanilla Cycles) down to under 70MB (texture cache on with default settings like in the screenshot below).

This way you can build scenes with literally thousands of hires textures without having to worry about memory consumption or manually downsizing textures to make the scene fit the memory. The mipmapping also prefilters the textures and cleans up a lot of noise coming from too dense textures (yes that is a thing!).

I hope to see this in Cycles-X or whatever in the not so far future :+1:

P.S.: I tried it with a scene containing many more objects with 8k maps and the memory consumption went from this:
image

to this:
image

The tx-conversion is running in parallel and is using all available cores. Very nice!

39 Likes

Yep that’ll be a godsend.
Did you also experiment any speed improvement? (As far as I have experienced using lower res textures give some speedups too.)

Honestly I didn’t experiment too much since I compiled it yesterday. Just some simple scenes where I kept adding Quixel assets with 8k textures.
In my case there was no speedup, in the simplest case the rendering took 2x longer than without texture cache even after the textures were pre-converted to tx.

But the difference in speed got less extreme the more complex the scene was.

The most important factor for me is the memory reduction which can really make the difference between “we need 256GB RAM to render this scene” and “I can render it on my 5 year old laptop with 8GB RAM easily”.

Another important factor is the improved filtering of the textures which can also play a big role when it comes to render times. With the texture cache’s mipmapping Cycles automagically selects the “right” resolution of the texture and this can reduce texture flickering and noise a lot with the same amount of samples.
Just imagine a simple plane that covers just a 128px square area of your full HD rendered image. If you naively texture this with an 8k texture you would have to fire thousands of samples per pixel to kind of “see” all the pixels of the texture that are contained in this pixel and to average and filter them for a clean result (especially necessary when rendering animations so that the texture isn’t too noisy or showing moirĂ© patterns).
With a texture cache and a mipmapped texture your renderer can use the mip level (i.e. the downscaled resolution) of the texture that is appropriate for the current situation. If the textured grid is far away and covers only a tiny part of the final frame a much smaller version of the texture is used, when you zoom in on the grid closely the full 8k version will be used.

This way you can render a clean result with much fewer samples (and thus faster) than when you just spam your scene with too many high res textures (which happens a lot because today people tend to think “more is better”).

14 Likes

Does it works already with GPU, or it’s just CPU for the time being?

P.S.: Forget it, you already said that it only works on CPU right now :slight_smile:

1 Like

Oh man, texture caching are one of the thing i missed from my old days with 3ds. Really hoping that this will get merged to master in the future with GPU support.

5 Likes

This was a highly awaited feature, amazing!

Hello,

Can someone with some free time and knowledge build the branch History · rB for windows and upload it to graphicall please ?

1 Like

I am bumping this thread as I believe texture caching is definitely needed in Cycles X at some point, even if it is CPU only for now.

@SteffenD I saw you kept updating your texture_cache_branch, any news as a possible merge at some point into the master ?

4 Likes

Yep, I agree with this, this is super important to be as efficient as possible with memory.

One solution for GPU’s could be to generate and cache the .tx files in the same folder as the textures and then use those based on distance from camera, size on render and occlussion.

Not sure if it could be possible without a pre-process per frame.

4 Likes

It is already what OIIO is doing. Except this part of OIIO doesn’t support gpu properly ? The texture lookup is CPU based I believe. Steffen will be more trustworthy than me to explain why the current solution is not very GPU friendly hehe.

Sorry, but I’m not the maintainer of the branch. Similar name but the guy who does this is @StefanW :wink:

Hooo damn, sorry for mixing up your names on the forum haha, and thanks for tagging the right one :wink:

Yep, @StefanW already explained the problem in a previous post.
The current difference with what I’m saying is that the GPU cannot dynamically load the different textures (more or less) so it cannot leverage the current implementation, this is an approximate explanation of what I understand what the problem with this is :slight_smile:
That’s why I proposed what I proposed, is some kind of pre-processing because it cannot be done at render time :slight_smile:

1 Like

The Cycles_Texture_Cache branch uses a rather sophisticated method for texture caching just like the commercial renderers I’ve been using so far. They convert the textures from all sorts of formats (8-bit, 16-bit, JPEGs, PNGs, TGAs, TIFFs, EXRs, 
 you name it) to an image format that supports mip-mapping and tiling.

One of the readily available open source tools for this is e.g. maketx from the OIIO library.

Mip-mapping means that after the conversion the image file contains a sequence of scaled down versions of itself. In case of a 2k square texture this means that it also contains these mip-map levels:

2048x2048 1024x1024 512x512 256x256 128x128 64x64 32x32 16x16 8x8 4x4 2x2 1x1

These are accessible without having to load the whole image file. The smaller the texture is in the rendered result (e.g. because it’s farther away from the camera) the smaller the mip-map level that’s actually loaded can be. This way an 8k texture might only weigh in like a 512px texture and consume a lot less memory.

Tiled images have another advantage: During conversion they’re split into square “tiles” that can also be separately accessed by the loader. In the default case of maketx these tiles are 64x64 pixels in size.
If e.g. only a part of a texture is visible in the rendered image, only these tiles need to be loaded and stored in memory.

Mip-mapping and tiling in combination can allow you to render scenes with terabytes of textures on a machine with a lot less RAM. Depending on the implementation of the texture cache, the parts of the textures that are currently in use can be swapped in and out of memory dynamically.

I’m not a software developer myself but all of this doesn’t only sound complicated, it for sure is not a trivial task to build into a renderer properly.

Luxcore or rather its Blender integration BlendLuxCore have added a very clever and neat method for texture scaling that’s not quite as elaborate as the one just described: It’s also pre-converting the textures to mip-mapped versions and only loads the needed sizes. It doesn’t support tiling or dynamic swapping as far as I know, but it can help a lot in scenes with many and/or big textures.

Here’s a thread in their forums about this Scene texture maps resize policy - LuxCoreRender Forums
It’s already ready to test in the latest Alpha builds and works quite well, without the need for the renderer to support all that complex mip-map / tiling stuff.
If I get it right no special changes had to be made to LuxCore (the renderer itself) to support this. Maybe this could be a (preliminary?) solution for Cycles as well.

12 Likes

This is the way. This method is production proven by the industry in a certain renderer that is named after Schwarzenegger.
I used it a lot in the past and the difference in render times and also memory efficiency using many big sized textures was amazing.

1 Like

In a perfect world this would be the best solution, yes. Stefan’s texture cache implementation already works very very well. but its main hurdle is GPU support which is not that easy to solve AFAIK.

The solution BlendLuxCore has implemented has the big advantage that it doesn’t need any changes from the renderer’s side but only in the way the textures are prepared before being sent to the renderer. It works with CPU and GPU out of the box.

Is this solution being considered by the branch developer?