Home Technical Talk

Vertex-Blending - Transitonal Masking

polycounter lvl 12
Offline / Send Message
Ace-Angel polycounter lvl 12
Heya peeps, quick question!

How can one go about 'fixing' the issue of a Vertex-Blend material, so that you can blend all 3 material together at the same time if one wants to when using a Mask?

Example of what I mean;

I have Dirt material in my Red Channel, Grass in Green and Water in Blue.

Each of my Vertex Color is Multiplied by a Mask before being fed into the Lerp.

I paint each color on the each end of a planes vertice.

I then paint YMC at the between sections (to Blend each texture together nicely with the Mask, or else you get harsh cuts).

Now here is the problem, if I want so that all the texture 'blend' with each other, I should use the color White, around the area where all the colors more or else meet, right? When I do that, in my case, they all run away from each other and only the Blue Color remains.

Here is my setup: 6Ghoh.jpg

Replies

  • Kurt Russell Fan Club
    Options
    Offline / Send Message
    Kurt Russell Fan Club polycounter lvl 9
    Your lerps are basically like if statements here. So your blue remains because your shader is basically saying:

    If blue is over 0, use more blue
    else if green is over 0, use more green,
    else if red is over 0, use more red,
    else use pure white (?? that 10 at the top seems to be the default colour)

    (I don't know how much programming you've done, but hopefully this makes sense :))

    So blue will be the overriding colour any time that your vertex blue colour is greater than zero. That's because blue is the last thing that's added in -- no matter what the colour is before the blue lerp, if there's meant to be any blue at all, it'll override the previous colour.


    There are a number of ways you can fix it, but here's one that I'd do (sorry, no UDK installed here or a stylus so in all its glory:

    cNzXt.png
  • Ace-Angel
    Options
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Nice! Thanks, will give this a try ASAP, and no, I never dabbled in programming, but I can sort-off-hand understand what you're saying.

    I don't need to clamp any value from the vertex in 1-0 range, do I?
  • Kurt Russell Fan Club
    Options
    Offline / Send Message
    Kurt Russell Fan Club polycounter lvl 9
    Nope, you shouldn't need to -- that's going to happen with the normalise.

    It makes sure your RGB values all give a length of one. So if you paint 20% red and 20% blue, it'll be the same as painting 100% red and 100% blue -- a 50:50 colour mix between the red and blue textures. If you paint white, it'll split the colours up evenly.

    Oh wait, though - you will have to multiply the output of the normalise by itself. Otherwise it'll be too bright. So if you put in rgb values of (1,1,1), the normalise will set them to ~(.57,.57,.57) and when you square them, you'll get (.33,.33,.33), which works for the final multiply/addition.
  • LoTekK
    Options
    Offline / Send Message
    LoTekK polycounter lvl 17
    This is arguably a bit anal, but if you want to optimise that, instead of normalising each color, which involves an expensive square root (which gets canceled out anyway, when you square the final result), you can do:
    VertexColor.rgb / r*r + b*b + g*g
    

    Or for a more compact node tree:
    dot(VertexColor.rgb, VertexColor.rgb)
    

    which essentially gives you the Squared Magnitude of the VertexColor vector.

    normalizeVs.jpg

    Again, though, this is arguably a bit anal, but handy if you need/want to optimise things.
  • Kurt Russell Fan Club
    Options
    Offline / Send Message
    Kurt Russell Fan Club polycounter lvl 9
    That's pretty interesting Lotekk - nothing wrong with being anal for performance.

    One thing, though - your maths needs to square your vertex colour first before you do the dot product, since what's being square rooted for the normalise is (r^2+g^2+b^2), but before I squared it I divided the red channel by that length. So the red channel value was being squared as well as the length, and you still have to do that sometime (I hope that makes sense). Otherwise it's spot-on.

    But there's something else really stupid about the normalise way anyway -- the way I said doesn't balance the RGB weights correctly because of the normalise! :)

    If your RGB is (1,0.5,0.5), you'd expect the outputs to be (0.5,0.25,0.25). My code up there makes the weights (0.6667,0.1667,0.1667).

    The better way (much faster) I think would be to add up the RGB channels and divide them by the total. So 1+0.5+0.5 is 2.0 - then divide them by 2 and you have the right weights of (0.5,0.25,0.25)

    I have no idea why I overcomplicated it.
  • Ace-Angel
    Options
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    That's soooooooooooooooooooooooOOOOOOOOOoooooooo awesome guys! Much appreciated for all the interesting stuff, cheers!
  • LoTekK
    Options
    Offline / Send Message
    LoTekK polycounter lvl 17
    Lol, you're right about the dot product bit; I made the mistake of only using enough test cases to show that it worked, and not properly checking the results.

    As for your new conclusion, you're totally right, haha. Good show to us for taking a simple problem and completely overthinking it :p
  • Ace-Angel
    Options
    Offline / Send Message
    Ace-Angel polycounter lvl 12
    Thanks again guys, much appreciate for all the information, just on question however, I tried all the different setup's and it seems like the Instruction counts (at least in UDK) doesn't change, is there any other performance 'hints' I should be looking out for?

    Now, forward! Also, new issues, kinda...
    When I use a mask (using the previous method) I still get weird results. An example of what I mean is this setup here:
    6ky99.jpg

    Pretty much, my blend doesn't 'respect' the mask of the other colors or transition correctly, I end up with a half-breed kinda deal which doesn't make sense (EI: If I color one vertice ALL green, I still can see my RG textures).

    So I racked my brains, did some searching on google, poked some colleagues and this is what I got so far:

    Ju5z2.jpg

    Material this time Mask the Vertex Color through a Subtract before being Divided by the other two colors (G+B) in the case of R. Same for all others.

    This way the mask and color blending will be respected, or so I thought until I got to this!

    PXbMv.jpg

    As you can see, my Green color, when painted near or on Red will actually darken near the borders. Blue will outright start fading to black when put near Red.

    Green and Blue work fine, even Cyan works fine, jut not anything near Red for some odd reason?

    No matter what I try, it feels like I'm running in circles at this point.
Sign In or Register to comment.