luminance
-------------------------------
// Approximates the brightness of a RGB value. float luminance( vec3 color ) { return dot(lum, color); }
---------------------------
int size = width * height; std::vector<GLfloat> texData(size*3); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, hdrTex); glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_FLOAT, texData.data()); float sum = 0.0f; for( int i = 0; i < size; i++ ) { float lum = computeLum(texData[i*3+0], texData[i*3+1], texData[i*3+2]); sum += logf( lum + 0.00001f ); } float logAve = expf( sum / size );
-----------------------------
// Retrieve high-res color from texture vec4 color = texture( HdrTex, TexCoord ); // Convert to XYZ vec3 xyzCol = rgb2xyz * vec3(color); // Convert to xyY float xyzSum = xyzCol.x + xyzCol.y + xyzCol.z; vec3 xyYCol = vec3(0.0); if( xyzSum > 0.0 ) // Avoid divide by zero xyYCol = vec3( xyzCol.x / xyzSum, xyzCol.y / xyzSum, xyzCol.y); // Apply the tone mapping operation to the luminance // (xyYCol.z or xyzCol.y) float L = (Exposure * xyYCol.z) / AveLum; L = (L * ( 1 + L / (White * White) )) / ( 1 + L ); // Using the new luminance, convert back to XYZ if( xyYCol.y > 0.0 ) { xyzCol.x = (L * xyYCol.x) / (xyYCol.y); xyzCol.y = L; xyzCol.z = (L * (1 - xyYCol.x - xyYCol.y))/xyYCol.y; } // Convert back to RGB and send to output buffer FragColor = vec4( xyz2rgb * xyzCol, 1.0);