From 284a3431aeee3e6a922d26415afcb50d0bf30b66 Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Fri, 3 Jun 2022 12:52:09 +0200 Subject: Cycles: Fix rendering of packed UDIM tiles with different sizes The packed image loader was not aware of the fact that UDIM tiles can be of a different size. Exposed Python API required to access this information. It has the same complexity as the "regular" packed files: in both cases the ImBuf will be acquired and released to access the information. While the current workflow of packing UDIMs is not very streamlined, it is still possible and is something what the studio is using here. Test file: {F13130516} Expected behavior achieved with this patch: a bigger checker board pattern in viewport render Actual behavior prior to this patch: either memory corruption, or wrong/black render result on the plane Differential Revision: https://developer.blender.org/D15111 --- intern/cycles/blender/image.cpp | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'intern') diff --git a/intern/cycles/blender/image.cpp b/intern/cycles/blender/image.cpp index 98ca16fe678..058fe3d46ac 100644 --- a/intern/cycles/blender/image.cpp +++ b/intern/cycles/blender/image.cpp @@ -28,10 +28,33 @@ BlenderImageLoader::BlenderImageLoader(BL::Image b_image, bool BlenderImageLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaData &metadata) { - metadata.width = b_image.size()[0]; - metadata.height = b_image.size()[1]; + if (b_image.source() != BL::Image::source_TILED) { + /* Image sequence might have different dimensions, and hence needs to be handled in a special + * manner. + * NOTE: Currently the sequences are not handled by this image laoder. */ + assert(b_image.source() != BL::Image::source_SEQUENCE); + + metadata.width = b_image.size()[0]; + metadata.height = b_image.size()[1]; + metadata.channels = b_image.channels(); + } + else { + /* Different UDIM tiles might have different resolutions, so get resolution from the actual + * tile. */ + BL::UDIMTile b_udim_tile = b_image.tiles.get(tile_number); + if (b_udim_tile) { + metadata.width = b_udim_tile.size()[0]; + metadata.height = b_udim_tile.size()[1]; + metadata.channels = b_udim_tile.channels(); + } + else { + metadata.width = 0; + metadata.height = 0; + metadata.channels = 0; + } + } + metadata.depth = 1; - metadata.channels = b_image.channels(); if (b_image.is_float()) { if (metadata.channels == 1) { -- cgit v1.2.3