1
$\begingroup$

Say I have a mesh with two sets of uvs. And I have a texture made for the first set of uvs. I would like to create a second texture that has the same relationship between its pixels and the second set of uvs, as the first texture does with the first set of uvs. Such that if we change between the two different sets of uvs and apply the corresponding texture we see identical texturing on the model. And the only difference would be the texture density in different regions because of the differences in distortion and the area of the uv faces between the two uv sets.

What technique can we use do this? Can it be done on the GPU?

Would we possibly need to transform each uv face of the first uv set into the corresponding face of second uvs set? Not sure where we would go from there.

$\endgroup$
0

1 Answer 1

2
$\begingroup$

Are the two sets well correlated? This would boil down to having a good set of vertex attributes for each set of uv's. If each set of uv's in mapping 1 has a know set of mappings in set 2 then it should be relatively straight forward to read from the first set of uv's and write to the second set.

If this is as simple as vertex 1 has a mapping in uv set 1 and a different mapping for uv set 2 then read from set one then resample the texture for set 2.

On the other hand if the two sets are completely uncorrelated then it gets more complex: A fully generic brute force solution would be to read 1 of the vertex attributes of the known mapping. Then search the entire set of uv's for set 2 filtering out those vertex positions that overlap with the current uv under consideration. Then use that list to read, resample and write the new texture.

The first case is easier to implement on the gpu. The second case is more difficult and may be better to implement on the cpu for debugging then move to the gpu as performance requirements dictate.

Edit for the first case: This is the easy case, Use the uv coords from set 1 on the gpu just like you would normally to read the texture. Then use the second set as actual vertex positions adding a z value that is some constant. Don't use a MVP matrix just go straight to clip space. The gpu will worry about the resampling. In the end you will have a fullscreen quad with the final mappings. Then just read the image back from the gpu.

More detail:

The vertex attributes for this would be:

Vertex Position = vec2{u_set2, v_set2}
uv coords = vec2{u_set1, v_set1}

The vertex shader:

vec2 remapping = vertex_position * 2.0 - 1.0; // remap x,y to -1 to 1
gl_position = vec4( remapping, 0.5, 1 ); 
out texcoord = uv_coords_in;

The fragment shader:

gl_color = texture( image_sampler, tex_coords);
$\endgroup$
5
  • $\begingroup$ Yes in fact the two sets are well correlated. "read from set one then resample the texture for set 2" -- could you describe this process in more detail? This is what I was wondering about. $\endgroup$ Jul 23, 2020 at 11:59
  • $\begingroup$ I added an edit to the answer. $\endgroup$
    – pmw1234
    Jul 23, 2020 at 12:30
  • $\begingroup$ Didn't think it was this easy, makes a lot of sense, thanks a lot! In the case where the uvs in the first set are outside the 0-1 range I guess I could just use GL_CLAMP_TO_BORDER with the desired background color to fill in the parts of the image that shouldn't have any texture. $\endgroup$ Jul 23, 2020 at 14:29
  • 1
    $\begingroup$ You could draw a fullscreen quad behind this with a blurred image to help with sampling errors to. This trick essentially turns opengl into a layered image editor! $\endgroup$
    – pmw1234
    Jul 23, 2020 at 15:08
  • $\begingroup$ Sorry I don't have that much experience with OpenGL, why a blurred image to help with the sampling? Yeah that's what I was just thinking! Just use quads for each layer with alpha and different depths. We could also do different image processing operations like translation, rotation and scaling. I haven't seen GPU used for image processing and the like though. Are there limitations I'm not aware of? $\endgroup$ Jul 24, 2020 at 12:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.