12
$\begingroup$

Where is a proper way to get back UV map after Realize Instances?

So let's say I have a distribution of the instances:

enter image description here

When I enable "Realize Instances" I completely lost my UV data, while it is presented in a spreadsheet:

enter image description here

So it's looks a bit weird, maybe 3.0 is not quite ready yet, maybe I should use "Transfer Attribute" in some way.

$\endgroup$
0

3 Answers 3

18
$\begingroup$

I was looking into this myself a week ago and thought that it's a bug or lack of functionality or something.

But yesterday I received an answer to a different geometry nodes question, that actually includes an answer to your question as well. Essentially the UV map is still there and you can still access it.

enter image description here

Just add an Attribute node into your material and write UVMap into it.

Original post (with a blend file) is here.

$\endgroup$
2
  • $\begingroup$ I see, it works with attribute. But still want to have a solution to pass UV into regular texture coordinate. $\endgroup$
    – Crantisz
    Jan 14, 2022 at 14:01
  • 2
    $\begingroup$ aphatetic_artist's answer is technically correct, but if you need to export the model, you will need to run the script written by totegamma. If anyone is curious, this is because the UVMap attribute from instanced geometry is stored as an array of UV data for each of the instances, and to use as UV mapping data this all has to be combined under a single mesh's UVmap. Both answers are viable solutions for different application. When using the script be sure the modifier is applied and has a slot for UV data called 'UVMap' $\endgroup$ Mar 14, 2022 at 21:13
8
$\begingroup$

I wrote a small script that transfers attributes to actual UV. This works if the geometry node modifier has already been applied. This is a temporary workaround but may be useful for someone who encounters this question, so I'll share.

import bpy

target = bpy.context.active_object

attrUV = target.data.attributes["UVMap"].data
targetUV = target.data.uv_layers[0].data

for i, elem in enumerate(targetUV):
    elem.uv = attrUV[i].vector

Just paste to the "Scripting" tab. Select an object which you want to apply and run it. (You need to press the "+" button on the UVMap menu before if the object has no UVMap yet.)

$\endgroup$
1
  • $\begingroup$ is there no way to automate the process ? or apply it to multiple objects ? the idea of doing this with dozens or hundreds of objects is nightmare fuel. the script also gives an error and doesnt work 9/10 and then suddenly it does for no reason that i can determin $\endgroup$
    – Fall
    Apr 1, 2022 at 19:59
4
$\begingroup$

Expanding on totegamma's solution of using a script to copy the actual UV data from the attributes, here's a tweaked script that creates the UV map and works on multiple selected objects.

import bpy

for target in bpy.context.selected_objects:
    if target.type == 'MESH' and len(target.data.uv_layers) == 0:
        targetUVO = target.data.uv_layers.new(name="UVMap")

for target in bpy.context.selected_objects:
    attrUV = target.data.attributes["UVMap"].data
    targetUV = target.data.uv_layers[0].data 
    for i, elem in enumerate(targetUV):
        elem.uv = attrUV[i].vector
````
$\endgroup$
2
  • $\begingroup$ Using this script, I got the following error, if run on one specific object (idk why): ValueError: bpy_struct: item.attr = val: sequences of dimension 0 should contain 2 items, not 3. This occured on line 11 of the script (last line). Any fix? $\endgroup$
    – lajawi
    Jun 11, 2023 at 11:28
  • $\begingroup$ When uploading a .blend file with UVMaps made with this script, Sketchfab doesn't recognize it. Any way around it? $\endgroup$
    – lajawi
    Jun 11, 2023 at 11:55

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