3
$\begingroup$

I have a question regarding how blender handles UDIMs in python.

By default, img.pixels always returns the pixels of the first UDIM. (img being bpy.data.images["NAME"].)

I've been struggling to figure out how to change which one of the UDIMs is being read/written to. The core issue is that tiled images seem to have multiple image buffers assigned to them, but only one of them is accessible with the default image commands.

To be honest I'm not quite sure, if this is even possible right now, as UDIMs are still relatively new to Blender (and their API features & documentation are scarce), but I really hope it somehow is possible, as it would otherwise break the functionality of a script.

Instead of dumping hundreds of lines of code on here I've written a little dummy snippet, that if resolved, would allow me to fix my code. If you want to know what exactly I need this for, you might want to read the backstory presented further down below.

The majority of the code just sets up the actual test and can be ignored. All it does is generate a new image data block with three white UDIMs. The last three lines are what's actually interesting.

Line 1: Gathers the pixels of the image data block. (Or in truth just those of UDIM 1001)

Line 2: Multiplies the pixels of the blue channel with black, leaving a yellow image.

Line 3: Reingests the pixels into the ImageBuffer.

The goal for this dummy script would be to generate three yellow UDIM tiles using multiplication. (Using the fill of the tiles themselves is not an option, as the dummy script represents multiplying to images together!)

import bpy
import numpy as np 

name = "test_1"
img = bpy.data.images.get(name)
if img == None:
    resolution = 32  # resolution in pixels
    bpy.ops.image.new(name=name, width=resolution, height=resolution, color=(1, 1, 1, 1), alpha=True, generated_type='BLANK', float=True, use_stereo_3d=False, tiled=True)
    img = bpy.data.images.get(name)

    bpy.context.area.ui_type = 'IMAGE_EDITOR'
    bpy.context.space_data.image = img

    udims = [1001, 1002, 1003]

    for udim in udims:
        bpy.ops.image.tile_add( number=udim, count=1, label='', fill=True, color=(1, 1, 1, 1), generated_type='BLANK', width=resolution, height=resolution, float=False, alpha=True)
    bpy.context.area.ui_type = 'TEXT_EDITOR'


rgb = np.array(img.pixels)
rgb[2::4] = np.multiply(rgb[2::4], 0)  # inject alpha into rgb
img.pixels = rgb

The issue is that it only ever modifies UDIM 1001. I've tried iterating through tiles and setting a new active one, but that didn't seem to do anything either:

img = bpy.data.images.get("test_1")
for tile in img.tiles:
    img.tiles. active = tile

    rgb = np.array(img.pixels)
    rgb[2::4] = np.multiply(rgb[2::4], 0)  # inject alpha into rgb
    img.pixels = rgb

If anyone knows a way to access the pixels of the other UDIMs that would be absolutely fantastic... otherwise I will have to keep using the version of the script that just breaks the UV layout for normal use...

Backstory:

I have a small script that adds a couple of additional settings to the Baking tools. In VFX it's reasonably common to have multiple different UVsets for one model. E.g. UDIM Sequence for rendering + 1 UV tile proxy version for rigging/animation. Or sometimes the topology + UVs change.

In both cases the textures need to be transfered from one mesh to another version of the same mesh. And for this purpose the Blender Baker still lacks some functionality. (E.g. Better control of the search radius, similar to how substance handles it, with both absolute value options, as well as relative to mesh size options.) The most important one however is alpha support. When using the Diffuse input for baking, only the RGB part of RGBA textures gets transferred. The script I wrote transfers the RGB values (diffuse input) and Alpha (roughness input) separately. These two are then recombined after the transfer using numpy multiplication and said img.pixels command.

This script as a whole isn't new. I've written it back for 2.9.3, including a rudimentary UDIM support (Assigning a shader per UDIM and moving all UVs to 1001... then importing all the textures on a per shader basis and baking these on a per shader basis too.) And that script works perfectly fine.

I thought it would be nice to update the tool, now that Blenders baking tools actually support UDIMs. I don't really want the script to modify the shaders and UVs (old version), as that makes it hard to debug if something isn't transfered as expected. (It also makes reruns of the script of more complicated.)

The issue is that the recombination of RGB + A is only done for the first UDIM, as the pixels gathered for the numpy part are only read for that first UDIM/Image Buffer.

$\endgroup$
4
  • $\begingroup$ Hello, Have you saved the images. If yes then you can use bpy.data.images['NAME'].filepath, which returns /path/to/NAME.<UDIM>.png. You can replace <UDIM> with 1002 and read file from disk, make changes, then save to disk. Then you can reload image in blender $\endgroup$ Commented Jul 25, 2022 at 16:57
  • 1
    $\begingroup$ Hey :) thanks for your reply. The combined map is eventually saved to disk, but I want to avoid saving the alpha texture, as it is only there as a temporary means.... $\endgroup$
    – ARM
    Commented Jul 25, 2022 at 17:58
  • $\begingroup$ hmm... does this addon help? blendermarket.com/products/udim-baker $\endgroup$ Commented Jul 25, 2022 at 18:05
  • $\begingroup$ Unfortunately not, I've seen it before and it seems to be more focused on baking mesh maps, rather than transferring textures from one mesh to another, so the Alpha of textures would still get lost during transfers.. $\endgroup$
    – ARM
    Commented Jul 26, 2022 at 7:16

1 Answer 1

0
$\begingroup$

Currently there does not appear to be any way of accessing the pixels data block of tiles. It's something I would really like to be able to do as well!

A pixels pointer should be added to the tile data block.. We need to bug the developers to add this, it should be fairly simple so I don't really know why it isn't there...

$\endgroup$

You must log in to answer this question.

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