1
\$\begingroup\$

I'm taking a texture from a shared texture handle and rendering it on the screen. I do this by creating a simple mesh that covers screen space, and then sampling the texture like so

float4 main(PixelInput pixelInput) : SV_TARGET
{
    return sourceTexture.Sample(textureSamplerState, pixelInput.uv);        
}

However, the texture on the screen appears significantly darker than the source texture. I suspect this is because the type of the texture from which I am sampling is DXGI_FORMAT_R8G8B8A8_UNORM_SRGB but my back buffer is DXGI_FORMAT_B8G8R8A8_UNORM. For technical reasons, I am unable to change the format of either.

I tried the following conversion to linear color space

    float4 sRGBA = sourceTexture.Sample(textureSamplerState, pixelInput.uv);
    float3 sRGB = float3(sRGBA.x, sRGBA.y, sRGBA.z);
    float3 RGB = sRGB * (sRGB * (sRGB * 0.305306011 + 0.682171111) + 0.012522878);
    return float4(RGB, sRGBA.w);

But this seemed to make no difference at all (which I found surprising in and of itself).

There are no other shader effects or interesting pieces being applied.

What here might cause the effect of the darker rendering?

Thanks in advanced, let me know if there is any additional interesting information!

\$\endgroup\$
  • \$\begingroup\$ why cant you have your back buffer as a SRGB target? \$\endgroup\$ – Justin William Stanley Bryant Mar 12 '17 at 0:09
  • \$\begingroup\$ The technology into which I am plugging creates the back buffer for me and does not offer the option P.S. I have tried rendering known colors in my pixel shader (red, blue, green, white) and verified they are not darkened in this way \$\endgroup\$ – Ben Mar 12 '17 at 0:10
  • \$\begingroup\$ The colors are not darkened because they are in the correct space to start with. Some HLSL to try // Converts from linear RGB space to gamma. float3 LinearToGamma(float3 color) { return sqrt(color); } // Converts from gamma space to linear RGB. float3 GammaToLinear(float3 color) { return color * color; } \$\endgroup\$ – Justin William Stanley Bryant Mar 12 '17 at 0:17
  • \$\begingroup\$ Seems like LinearToGamma was the fix. I ended up researching it more and did pow(color,1/2.2). Thanks so much! I'm not quite sure I understand why the adjustment needs to be done manually as opposed to some intelligence from the graphics system, but that is quite another question. If you want to post as an answer, I will be glad to accept. \$\endgroup\$ – Ben Mar 12 '17 at 5:30
1
\$\begingroup\$

I'm thinking you got your targets mixed up in your question because now you are converting linear to gamma so I'm thinking the targets are around the other way.

When sampling from an none SRGB texture if your back buffer is an SRGB format then you need to do the conversion by hand.

Like this:

 // Converts from linear RGB space to gamma.
 float3 LinearToGamma(float3 color)
 { 
 return pow(color,1/2.2);
 }

If your targets are the way you say they are then I would expect the conversion to be

// Converts from gamma space to linear RGB. 
float3 GammaToLinear(float3 color)
{ 
return color * color;
} 

because you are reading from an SRGB texture and outputting to a none SRGB target.

\$\endgroup\$
  • \$\begingroup\$ I'm quite certain the direction I gave was right. I just re-verified by calling GetDesc on the backbuffer resource texture and on the opened shared texture handle. However nonetheless the LinearToGamma solution has worked like a charm. Thank you much! \$\endgroup\$ – Ben Mar 13 '17 at 3:01
  • \$\begingroup\$ Happy to be of help, I'm going to go and setup a test rig to actually test this for my self. \$\endgroup\$ – Justin William Stanley Bryant Mar 13 '17 at 3:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.