addition of two HDR (RGBE) values?

Pardon me if this question might be more appropriate in the shading language discussion forum.

How do I add two RGBE values together (in a fragment shader)?

I’m sure you all know this better than I do but the true component intensities for an RGBE value is something like
r’ = r * 2^e
g’ = g * 2^e
b’ = b * 2^e

Is there any fast method for adding two such colours together, and get a new RGBE value back? Is there any faster way other than to calculate the true intensities before I calculate the sum and then convert it back to the RGBE components?

I don’t know how much the following information is helpful to addition two RGBE.

In this web page I found that:


Encoding and decoding using the RGBE format is easy. To encode a pixel using the RGBE format the following HLSL pixel shader 2.0 code can be used:

float4 EncodeRGBE8( in float3 rgb )
{
  float4 vEncoded;
  float maxComponent = max(max(rgb.r, rgb.g), rgb.b );
  float fExp = ceil( log2(maxComponent) );
  vEncoded.rgb = rgb / exp2(fExp);
  vEncoded.a = (fExp + 128) / 255;
  return vEncoded;
}

To decode a pixel using the RGBE format the following HLSL pixel shader 2.0 code can be used:

float3 DecodeRGBE8( in float4 rgbe )
{
  float3 vDecoded;
  float fExp = rgbe.a * 255 - 128;
  vDecoded = rgbe.rgb * exp2(fExp);
  return vDecoded;
}


Keep in mind that this is for RGBE8 not RGB9_E5. In this file at section 3.9.1 there is a general formula for encoding RGBE format.

Thanks for the link. It does not really describe how to add two rgbe values effectively, but it has other interesting information of course.

As a quick solution right now I just add together the colour components from the two rgbe values. As for the exponent I simply keep the biggest. It is not right of course and I haven’t really tested how it looks either, so I’m still looking for a solution here.

Another question is how I can control various aspects when decoding a colour (from RGBE to RGB). Does anyone have any idea how I can change the decoding so that brighter values are toned down a bit, perhaps linearly?