My scenes really use a lot of textures, and I recently hit the 95 texture limit of cycles. Then I started thinking if it would be possible to work around this, and I think I have a solution. However, I’m not very familiar with the C-code of cycles, so I have trouble figuring out which parts of the code would be involved, and into what extent things can be solved in python and where C is needed.
I’m hoping someone more familiar with this code is willing to tell me whether this solution is feasible, and is willing to help me understand the concerned code.
Requirements for the solution
amount of textures should not be the limit, only the size of your graphics memory
typical UV tricks that are supported now (tiling textures, textures outside of [0,1] range) should be still supported
solution should be transparent (invisible) to the user
Suggested approach
before rendering starts,textures which have the same size and pixel-type are grouped together in an atlas.
The concerned image nodes are notified that they have to re-map to an area of that atlas.
When a node has to sample the texture, it will use the remapping info to sample the right area. border-cases should be handled correctly.
When rendering a movie, the same atlas can be re-used for rendering the whole movie in this way.
Areas of concern
The design of the node system will probably get more complicated: some manager needs to manage all the texture nodes
performance - the re-mapping is not a difficult calculation, but will happen a lot (every time that one of the textures is sampled) so the code needs to be written with care
limits - is there a limit to the texture sizes?
Graphics pipeline features - does the cuda code use typical graphics-hardware features like mipmapping or texture border handling, which could be messed up when playing with the sampling coordinates?
Hi Jonim8or
The limitation is actually a Cuda thing, all Cuda cards up to compute capability 2.x (Fermin Chips) are limited to 128 texture slots. Cycles divides them to 95 LDR images, 5 HDR images and 28 for internal use (I dont know for what).
Newer Nvidia chips with higer compute capability (currently 3 and 3.5) have a fixed limit of 256 that probably allows 223 LDR images
CPU is also limited in cycles with i think 512 textures. They had to raise it for the tears of steel movie project but technically there is no limit on CPU.
The limits are defined as much as i know in: intern/cycles/kernel/kernel_textures.h
The only workaround is to reduce the amount of textures by reuse textures or merge a lot of small textures into one big texture (could be done with a script maybe). It would be cool if cycles would internaly automerge textures with correct uv cordinates for gpu render.
Another point of interest is that the cuda uses tex2D (svm_image_texture uses kernel_tex_image_interp which is translated to tex2D using a macro). What kind of filtering is used by CUDA? because that might make the atlas a lot more complex and less efficient.