I'm implementing an adaptive tonemapper based on the standard "scale down the luminance map to a 1x1 texture" approach.

This is my code following the rendering of the luminance map:

 //Average the luminance map by creating a 1x1 mipmap.

    m_pImmediateContext->CopyResource(m_cpuLumTex, m_lumTexture);

    float* lumMap;
    m_pImmediateContext->Map(m_cpuLumTex, 0, D3D11_MAP_READ, 0, &texture);
    lumMap = (float*) texture.pData;
    m_avgLuminance = lumMap[0]; // Should work? ^^;
    m_pImmediateContext->Unmap(m_cpuLumTex, 0);

    float lastLum = m_timedAvgLuminance;
    float currentLum = exp(m_avgLuminance);
    float adaptedLum = lastLum + (currentLum - lastLum) * (1 - exp(-.1 * 0.5));

    m_timedAvgLuminance = adaptedLum;

I'd like to read back the calculated average luminance to the CPU for reasons, but what I'm finding is that when I set m_avgLuminance to the mapped-back texture, it's grabbing the pixel at 0,0. If the map were a 1x1 texture, this wouldn't be an issue, but it seems I'm not getting the 1x1 texture, but instead the full-sized luminance texture (screen-sized), so what I wind up with is an image tonemapped by the 0,0 pixel instead of the overall average luminance of the scene.

What am I doing wrong here? How can I read the 1x1 generated mip map texture instead of the full-sized texture?


You need to map the sub-resource that corresponds to the mipmap level you want.



m_pImmediateContext->Map(m_cpuLumTex, (mipmap number here), D3D11_MAP_READ, 0, &texture);

if your texture is 256x256 that'd be resource 7.

(256 = 1 << 8, substract 1 for the last 1x1 mipmap => #7)


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.