ShaderResourceView sRGB format having no effect on sampler reads

Started by
3 comments, last by SmellyIrishMan 9 years, 1 month ago

Hey guys,

So I'm looking into gamma/linear correctness and all of that goodness but hit a bit of a hurdle tonight. I'm specifically using SharpDX at the moment but that shouldn't have much of an impact on what I'm trying to accomplish.


SharpDX.Direct3D11.ImageLoadInformation imageLoadInfo = new SharpDX.Direct3D11.ImageLoadInformation();

imageLoadInfo.BindFlags = SharpDX.Direct3D11.BindFlags.ShaderResource;
imageLoadInfo.Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb;

SharpDX.Direct3D11.Resource sRGBTexture = SharpDX.Direct3D11.Texture2D.FromFile(device, filepath, imageLoadInfo);

textureView = new SharpDX.Direct3D11.ShaderResourceView(device, sRGBTexture);

The problem is that no matter if I use R8G8B8A8_UNorm or R8G8B8A8_UNorm_SRgb, the sampler in the shader is still reading the same values. If I manually adjust the values in the shader to account for gamma with pow(sampler.sample(), 2.2) then things are back on track again. Perhaps I'm misunderstanding things but I thought that if I changed the format of the ResourceView then it should automatically apply or not apply gamma correction in the texture read.

For instance; https://msdn.microsoft.com/en-us/library/windows/desktop/hh972627(v=vs.85).aspx

Am I mistaken?

Advertisement

I'm not a user of SharpDX, but the documentation indicates that Texture2D.FromFile is just a wrapper around D3DX11CreateTextureFromFile. One of the quirks of that function is that if you specify an SRGB format, it will assume that the image file is in linear space (not sRGB!), and will thus perform a linear->sRGB conversion on the image data before creating the texture. So basically your texture gets an sRGB->Linear transformation applied to it, and then the texture unit performs Linear->sRGB conversion applied which ends up giving you a very similar to result to what you would get if you never used an sRGB format in the first place. wacko.png

To tell the loader that the image file is already in sRGB space and that it shouldn't convert anything, you need to set the "Filter" field to "FilterFlags.SRgbIn | FilterFlags.SRgbOut". Or alternatively, you can use "FilterFlags.SRgb" which is the same as using the "In" and "Out" flags together.

Thanks very much for the function explanation, it's definitely a little bit confusing biggrin.png.

I might need to look into some more details since applying just the filter didn't change things, but applying both the format and filter did.


imageLoadInfo.Format = SharpDX.DXGI.Format.R8G8B8A8_UNorm_SRgb;
imageLoadInfo.Filter = SharpDX.Direct3D11.FilterFlags.SRgb | SharpDX.Direct3D11.FilterFlags.None;

Thanks MJP!


applying just the filter didn't change things, but applying both the format and filter did

Not a SharpDX user either, but it's obvious: the Filter specifies that the loaded image data is in SRGb format (to skip the conversion from linear), and the Format specifies the format of the DirectX texture. You obviously need both to have the same format for things to work as expected.

Yeah, that'll teach me to look at answers at 2am. You're right that it makes sense to have both the format and filters in sRGB.

Thanks for the help!

This topic is closed to new replies.

Advertisement