How to read ECF_R5G6B5 in the HLSL shader

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

How to read ECF_R5G6B5 in the HLSL shader

Post by robmar »

I couldn't find out how Irrlicht passes the 16-bit unit to the shader for the ECF_R5G6B5 texture format.
In the shader to read the 15-bit value as a float, anyone know which is correct:-

float greyPixel = tex.r + (text.g * 256); // two 8-bit values stored in R and G

Or is the 16-bits spread across R G and B, because when it reaches the shader it seems more r and g only.
CuteAlien
Admin
Posts: 9652
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How to read ECF_R5G6B5 in the HLSL shader

Post by CuteAlien »

Sorry, never thought about that.

edit: On a very quick test the shader used in the new PostProcessing example doesn't seem to change when you force textures to 16-bit. But did have to go back to 32-bit for the rendertarget texture (hlsl can't seem to create those with 16 bit, didn't check yet why. edit2: D3D9 simply doesn't seem to support that format for rtt's on my card). So my guess would be they are simply passed as rgb (which I also would expect).
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: How to read ECF_R5G6B5 in the HLSL shader

Post by robmar »

I've just dug thro the Irrlicht code, and if users load a 16-bit height map PNG file it gets silently converted to RGB, what a surprise that was!

I tried the D3DFMT_D16 format, but my card also refused to create that type, maybe needs D3D10+ or something.

Photoshop and other apps convert the 16-bit file into greyscale rgb at 256 levels, so all the detail is lost.

Using ARGB for height textures is very inefficient, using float32 textures also, as that's 8 bytes per pixel instead of 2, well, unless there's a float16 version, but then it's inefficient in processing overhead compared to simple 16-bit uint.

What a mess!
CuteAlien
Admin
Posts: 9652
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How to read ECF_R5G6B5 in the HLSL shader

Post by CuteAlien »

Depends on how you want to use it. But for 16bit there's ECF_R16 and with float ECF_R16F - at least if you work with Irrrlicht trunk (may not be in 1.8).
I wrote recently a test which creates all formats, you can use that to check what works.
At https://bitbucket.org/mzeilfelder/irr-p ... c/default/ check texture_color_formats.cpp (just copy it over some example). And switch to the D3D9 driver in code.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: How to read ECF_R5G6B5 in the HLSL shader

Post by robmar »

Hi, its weird, in 1.7 up to 1.81 createTexture assigns D3DFMT_A1R5G5B5 and not D3DFMT_R5G6B5 when users select the ECF_R5G6B5 format.

Is there a need to maintain an alpha on the texture for some reason in D3D9?

D3D9 must look at the texture type when passing data to the shader, and pack it accordingly, using the required fetch count per pixel, so using A1R5G5B5 will fetch 4 bytes, whereas R5G6B5 would need 3.

Code below shows this: Is there any reason for this?

Code: Select all

//! creates the hardware texture
bool CD3D9Texture::createTexture(u32 flags, IImage * image)
{
    ImageSize = image->getDimension();
 
´´´´
    switch(getTextureFormatFromFlags(flags))
    {
    case ETCF_ALWAYS_16_BIT:
        format = D3DFMT_A1R5G5B5; break;
    case ETCF_ALWAYS_32_BIT:
        format = D3DFMT_A8R8G8B8; break;
    case ETCF_OPTIMIZED_FOR_QUALITY:
        {
            switch(image->getColorFormat())
            {
            case ECF_R8G8B8:
            case ECF_A8R8G8B8:
                format = D3DFMT_A8R8G8B8; break;
            case ECF_A1R5G5B5:
            case ECF_R5G6B5:
                format = D3DFMT_A1R5G5B5; break;***<-----??????
            }
        }
        break;
CuteAlien
Admin
Posts: 9652
Joined: Mon Mar 06, 2006 2:25 pm
Location: Tübingen, Germany
Contact:

Re: How to read ECF_R5G6B5 in the HLSL shader

Post by CuteAlien »

I don't know why that was done. I've changed something similar in svn trunk just 2 months ago (in r5877) as I also couldn't find a reason for it. But it was done different in svn trunk already than in 1.8 as there was another rewrite before I looked at this. I didn't experiment with 1.8 version except for comparisons. Maybe it is (or was at some point) supported by more graphic cards.
I was also worried a bit about changing it, but that test I linked above didn't find any problems ... at least on my card.
IRC: #irrlicht on irc.libera.chat
Code snippet repository: https://github.com/mzeilfelder/irr-playground-micha
Free racer made with Irrlicht: http://www.irrgheist.com/hcraftsource.htm
robmar
Posts: 1125
Joined: Sun Aug 14, 2011 11:30 pm

Re: How to read ECF_R5G6B5 in the HLSL shader

Post by robmar »

Could be an issue with DX9 and the Irrlicht driver, but I can't yet see why.
If I do I'll post back. Bye
Post Reply