Monday, 31 January 2011

RGB/HSV in HLSL 2

Petr Kobalíček has spurred me on to look more closely at the the HLSL conversion between RGB and HSV colour spaces. With a bit of refactoring, I've managed to shave a few more GPU cycles off:

float3 RGBtoHSV(in float3 RGB)
{
  float3 HSV = 0;
#if NO_ASM
  HSV.z = max(RGB.r, max(RGB.g, RGB.b));
  float M = min(RGB.r, min(RGB.g, RGB.b));
  float C = HSV.z - M;
#else
  float4 RGB4 = RGB.rgbr;
  asm { max4 HSV.z, RGB4 };
  asm { max4 RGB4.w, -RGB4 };
  float C = HSV.z + RGB4.w;
#endif
  if (C != 0)
  {
    float RGB0 = float4(RGB, 0);
    float4 Delta = (HSV.z - RGB0) / C;
    Delta.rgb -= Delta.brg;
    Delta.rgb += float3(2,4,6);
    Delta.rgb *= step(HSV.z, RGB.gbr);
#if NO_ASM
    HSV.x = max(Delta.r, max(Delta.g, Delta.b));
#else
    float4 Delta4 = Delta.rgbr;
    asm { max4 HSV.x, Delta4 };
#endif
    HSV.x = frac(HSV.x / 6);
    HSV.y = 1 / Delta.w;
  }
  return HSV;
}

No comments:

Post a Comment