Search Unity

Lerping Three Textures Without Distorted Colors

Discussion in 'General Discussion' started by HonoraryBob, Aug 9, 2019.

  1. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,077
    If I lerp three textures using two successive lerp operations, colors are often distorted. I've tried clamping the results after both lerps, but that doesn't solve the issue. It seems like it should be simple to solve, but I can't figure out how.
     
  2. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    5,762
    It would help if you showed the distortions.
     
  3. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,077

    Here's a deliberately exaggerated version to make the issue clear: on the left is the shader using parameters that are set to high polarization values to try to make the division between textures more crisp, but with three textures the colors end up having an "overexposed" effect even with clamping. On the right is the same shader with parameters set to more moderate levels, which works fine except the textures are blended to the point that they become mushy and less distinct.

    Here's the code, which is just a very basic pair of lerps plus clamping (which has no effect and might as well be taken out). C.rgb starts with one of the textures, which is then lerped with MottlingC, then the result is lerped with Mottling2C:

    Code (CSharp):
    1.             c.rgb =   lerp(c.rgb, MottlingC, Mottling) ;
    2.             c.rgb = float3 ( clamp(c.rgb.r,0,1), clamp(c.rgb.g,0,1), clamp(c.rgb.b,0,1));  
    3.             o.Albedo =  lerp(c.rgb, Mottling2C, Mottling2) ;  
    4.             o.Albedo = float3 ( clamp(o.Albedo.r,0,1), clamp(o.Albedo.g,0,1), clamp(o.Albedo.b,0,1));    
     

    Attached Files:

  4. chingwa

    chingwa

    Joined:
    Dec 4, 2009
    Posts:
    3,311
    I think you're better off clamping "Mottling" and "Mottling2" values at the end of each lerp function. You can have values outside of 0-1 in that position that will blow out each color.

    Also you can use saturate(x) instead to get the same effect as clamp(x, 0, 1), and this can be done on a float3 as a whole, so...

    o.Albedo = saturate(o.Albedo);

    would replace the last line (just as an example).
     
    HonoraryBob and frosted like this.
  5. Billy4184

    Billy4184

    Joined:
    Jul 7, 2014
    Posts:
    4,569
    It's not a good idea to clamp individual values in a color, because it will wipe out the color with white. Let's say you have a color that's mostly red (1, 0.2, 0.2) and you for some reason multiply it by 5 so that it ends up as (5, 1, 1), then if you clamp it you just get white (1,1,1).

    Instead, you need to normalize it while retaining the relative differences between rgb, by dividing with the max value. For example:

    Code (CSharp):
    1. float4 color = float4(5,1,1,1);
    2. float maxValue= max(color.r, max(color.g, color.b));
    3. color *= 1 / maxValue;
    4.  
    The result is float4(1, 0.2, 0.2, 0.2), which retains the right color properties.

    Another point is that I would favor lerping between float values, normalizing these float values, and applying the colors at the end, because it prevents the color from getting messed up along the way.
     
    HonoraryBob and frosted like this.
  6. steego

    steego

    Joined:
    Jul 15, 2010
    Posts:
    903
  7. frosted

    frosted

    Joined:
    Jan 17, 2014
    Posts:
    3,501
    I think @Billy4184 is on the right path here. You may want to normalize not clamp. And definitely follow @chingwa's suggestion of preferring saturate to the individual clamps just to reduce the amount of code.

    But looking at the code, I have to wonder - what exactly are you trying to do here and why do you think tthe result is wrong?
     
    HonoraryBob likes this.
  8. Tzan

    Tzan

    Joined:
    Apr 5, 2009
    Posts:
    702
    This is a problem that effects Photoshop artists when they have 2 images and use the Clone tool with opacity less than 100%. The textures show thru each other and make a blurry mess. If your goal is to make these blended areas at 50%, you will always get that blur. The contrast that creates the sharpness in each image is destroyed.

    Dark areas become lighter, light areas become darker. Making pixels look too similar, less contrast.
     
    HonoraryBob likes this.
  9. HonoraryBob

    HonoraryBob

    Joined:
    May 26, 2011
    Posts:
    1,077

    Thank you. I can try that.