Jump to content
  • Advertisement
Sign in to follow this  
matt77hias

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.

If you intended to correct an error in the post then please contact us.

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 this post


Link to post
Share on other sites
Advertisement

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 this post


Link to post
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 this post


Link to post
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 :)

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!