# DirectXMath conditional assignment

This topic is 391 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I am using Frostbite's sRGB <-> linear color space conversion on the CPU with DirectXMath which does not have a conditional assignment (? : construct)

Any way to improve this:

const XMVECTOR comp = XMVectorLessOrEqual(srgb, XMVectorReplicate(0.04045f));

return XMVectorSet(
XMVectorGetX(comp) ? XMVectorGetX(low) : XMVectorGetX(high),
XMVectorGetY(comp) ? XMVectorGetY(low) : XMVectorGetY(high),
XMVectorGetZ(comp) ? XMVectorGetZ(low) : XMVectorGetZ(high),
XMVectorGetW(srgb)
);

Full code:

/**
Converts the given spectrum from linear to sRGB space.

@param[in]   linear
The spectrum in linear space.
@return      The spectrum in sRGB space.
@note        The alpha channel of the given spectrum is preserved.
*/
inline const XMVECTOR XM_CALLCONV LinearToSRGB(FXMVECTOR linear) noexcept {
// Frostbite's conversion
static const float exp = 1.0f / 2.4f;

const XMVECTOR low  = linear * 12.92f;
const XMVECTOR high = 1.055f * XMVectorPow(linear, XMVectorReplicate(exp))
- XMVectorReplicate(0.055f);
const XMVECTOR comp = XMVectorLessOrEqual(linear, XMVectorReplicate(0.0031308f));

return XMVectorSet(
XMVectorGetX(comp) ? XMVectorGetX(low) : XMVectorGetX(high),
XMVectorGetY(comp) ? XMVectorGetY(low) : XMVectorGetY(high),
XMVectorGetZ(comp) ? XMVectorGetZ(low) : XMVectorGetZ(high),
XMVectorGetW(linear)
);
}

/**
Converts the given spectrum from sRGB to linear space.

@param[in]     srgb
The spectrum in sRGB space.
@return        The spectrum in linear space.
@note          The alpha channel of the given spectrum is preserved.
*/
inline const XMVECTOR XM_CALLCONV SRGBToLinear(FXMVECTOR srgb) noexcept {
// Frostbite's conversion
static const float mlow  = 1.0f / 12.92f;
static const float mhigh = 1.0f / 1.055f;

const XMVECTOR low  = srgb * mlow;
const XMVECTOR high = XMVectorPow(
mhigh * (srgb + XMVectorReplicate(0.055f)),
XMVectorReplicate(2.4f)
);
const XMVECTOR comp = XMVectorLessOrEqual(srgb, XMVectorReplicate(0.04045f));

return XMVectorSet(
XMVectorGetX(comp) ? XMVectorGetX(low) : XMVectorGetX(high),
XMVectorGetY(comp) ? XMVectorGetY(low) : XMVectorGetY(high),
XMVectorGetZ(comp) ? XMVectorGetZ(low) : XMVectorGetZ(high),
XMVectorGetW(srgb)
);
}

Edited by matt77hias

##### Share on other sites

XMVectorLessOrEqual returns 0xFFFFFFFF on true and 0x00000000 on false, therefore you can play with bitwise operations:

Quote

const XMVECTOR lowhigh = XMVectorOrInt(XMVectorAndInt(low, comp), XMVectorAndCInt(high, comp));

// set W component

Edit: ajmiles suggestion is better - XMVectorSelect does exactly same thing as I suggested above.

Edited by Zaoshi Kaba

##### Share on other sites

XMVectorSelect is what you're looking for. It takes the masks output by functions such as LessOrEqual and each bit in the mask is used to select between A or B.

##### Share on other sites
2 hours ago, ajmiles said:

XMVectorSelect is what you're looking for. It takes the masks output by functions such as LessOrEqual and each bit in the mask is used to select between A or B.

Thanks that is exactly the functionality I was looking for

1. 1
Rutin
67
2. 2
3. 3
4. 4
5. 5

• 21
• 10
• 33
• 20
• 9
• ### Forum Statistics

• Total Topics
633417
• Total Posts
3011781
• ### Who's Online (See full list)

There are no registered users currently online

×