Search Unity

Best way to zero out all channels except the greatest

Discussion in 'General Graphics' started by DouglasPotesta, Mar 15, 2020.

  1. DouglasPotesta

    DouglasPotesta

    Joined:
    Nov 6, 2014
    Posts:
    109
    Is there a better way to do this. I am just hoping I am not doing something grossly inefficient. Criticism is welcome.
    Code (CSharp):
    1.             // Return a float4 where each channel is zero except the channel with the greatest value.
    2.             float4 SingleOut(float4 col)
    3.             {
    4.                 float4 colTemp = col;
    5.                 colTemp.r = col.r >= col.b? col.r>=col.g ? col.r >= col.a?col.r + col.g+col.b+col.a:0:0:0;
    6.                 colTemp.g = col.g >= col.a? col.g>col.r ? col.g >= col.b?col.r + col.g+col.b+col.a:0:0:0;
    7.                 colTemp.b = col.b > col.g? col.b>=col.a ? col.b > col.r?col.r + col.g+col.b+col.a:0:0:0;
    8.                 colTemp.a = col.a > col.r? col.a>col.b ? col.a > col.g?col.r + col.g+col.b+col.a:0:0:0;
    9.                 return colTemp;
    10.             }
     
  2. DouglasPotesta

    DouglasPotesta

    Joined:
    Nov 6, 2014
    Posts:
    109
    Guess it’s perfect. I am shader god.
     
  3. BattleAngelAlita

    BattleAngelAlita

    Joined:
    Nov 20, 2016
    Posts:
    400
    Code (CSharp):
    1. greatest = max(max(col.r, col.g), max(col.b, col.a));
    2. col.r = col.r >= greatest ? col.r : 0.0;
    3. col.g = col.g >= greatest ? col.g : 0.0;
    4. col.b = col.b >= greatest ? col.b : 0.0;
    5. col.a = col.a >= greatest ? col.a : 0.0;

    or even simpler
    Code (CSharp):
    1. greatest = max(max(col.r, col.g), max(col.b, col.a));
    2. mask = saturate((col - greatest + 0.0001) * 100000.0);
    3. col *= mask;
     
    DouglasPotesta likes this.
  4. DouglasPotesta

    DouglasPotesta

    Joined:
    Nov 6, 2014
    Posts:
    109
    upload_2020-3-19_15-30-46.jpeg
     
  5. DouglasPotesta

    DouglasPotesta

    Joined:
    Nov 6, 2014
    Posts:
    109
    I would like to note. The provided solution doesn’t provide 1:1 results where multiple channels have the max value. For example, with the input float4(1,1,0,0) will return float4(1,1,0,0), where as the original provides foat4(1,0,0,0).
    I didn’t specify that in the comment so it is understandable.
    The solution provided can be reworked to return the same results so it is not a big deal. Thank you!