Search Unity

Resolved Use vertex colors to mask/swap parts of a UV texture

Discussion in 'General Graphics' started by Ne0mega, Mar 20, 2021.

  1. Ne0mega

    Ne0mega

    Joined:
    Feb 18, 2018
    Posts:
    755
    I have a model with white and black vertices.
    The white ones I want to use as a mask, so that those vertices will swap out the UV texture with the sample of another, with an identical UVMap layout.

    I could do this with alpha mask textures, but those are rectangular/square, and I am hoping to do a more dynamic customization system.

    I need to keep soft shading.
    I know that vertices are assigned triangles.
    So I am thinking one way would be to ask if all three vertices of a triangle are white, then mask out that triangle on the UV Image, but that seems kind of hacky and complicated, and I can see it leaving lots of lines and/or pixelated seams.

    I know I can ask Unity what the UV coordinate of a vertex is.

    but getting that last step down, to tell the UV texture which triangles mask... ..I am hoping there is an API interface command to do such things.

    I mean, my big trip up is I know 1 or 2 vertices would not be enough, it would need at least three, but how would Unity know those three have an enclosed triangle that can be masked out

    Anybody ever do anything like this before? And ideas?

    EDIT:
    So, I've done some reading, and there seems to be a bit of a way to do it with an orthographic camera. I could transfer the vertices from their 3d space and remap them to their UV Coords in 2d space. Normals could be flipped this way, and another mystery of UV Maps to me has been how vertices could exist in two or even more spaces at once, via seams, as a vertex can have multiple UV values if it is a seam vertex.

    EDIT II:
    1) Go through every vertex in stream
    2) check if it is white. if no, next vertex
    3) find the triangle it is in, and check the other two vertices, if either are black, next vertex.
    4) check UV's vPos against other two vertices, if not lowest vPos, next vertex. if all equal,next vertex, if two equal, choose lowest uPos of the two.
    5) I now have all white triangles, so add to white triangles list.
    6)start overwriting pixels with the other UV map with an iterator that varies in U length across V heights per triangle:
    a) I know my lowest vPos, so find highest vPos, last vertex will be uPos "marker".
    b) three loop iterator
    i) for each triangle
    ii) for int v = 0, until v < (highest vPos - lowest vPos)
    iii) this is the trickiest part, I have to increment and decrement, based on triangle's local vPos....


    7) dilate, viola.

    Edit III:
    edit II was close to the flat side triangle method. I ended up using barycentric for now:

    https://stackoverflow.com/a/20861130

    Edit IV:
    you still reading this? OK, turns out, that you can calculate the area of a triangle by using the lengths of its sides. So find the area of the triangle being checked by using the lengths of its sides.

    if there is a point inside a triangle, you can use that point to break up the triangle into three smaller triangles.

    Find the area of the three smaller triangles, just like you did for the main triangle.

    add up the areas of the three smaller triangles. Does it equal exactly the area of the main triangle? If yes, the point is inside the triangle, if no, it isnt. This is working great for me. (it may look spotty, data loss means you have to add a small check for error, so if it is off by 0.000001 it will still count as "equal").
     
    Last edited: Mar 24, 2021