LearnOpenGL 总结记录 HDR
1.
To implement high dynamic range rendering we need some way to prevent color values getting clamped after each fragment shader run. When framebuffers use a normalized fixed-point color format (like GL_RGB) as their colorbuffer’s internal format OpenGL automatically clamps the values between 0.0 and 1.0 before storing them in the framebuffer. This operation holds for most types of framebuffer formats, except for floating point formats that are used for their extended range of values.
When the internal format of a framebuffer’s colorbuffer is specified as GL_RGB16F, GL_RGBA16F,GL_RGB32F or GL_RGBA32F the framebuffer is known as a floating point framebuffer that can store floating point values outside the default range of 0.0 and 1.0. This is perfect for rendering in high dynamic range!
2.
Tone mapping is the process of transforming floating point color values to the expected [0.0, 1.0] range
known as low dynamic range without losing too much detail, often accompanied with a specific stylistic color balance.
The simplest tone mapping algorithm is known as Reinhard tone mapping and involves dividing the entire HDR color values to LDR color values evenly balancing them all out. The Reinhard tone mapping algorithm evenly spreads out all brightness values onto LDR. We include Reinhard tone mapping into the previous fragment shader and also add a gamma correction filter for good measure (including the use of SRGB textures):
uniform float exposure;
void main() {
const float gamma = 2.2;
vec3 hdrColor = texture(hdrBuffer, TexCoords).rgb;
// Exposure tone mapping
vec3 mapped = vec3(1.0) - exp(-hdrColor * exposure);
// Gamma correction
mapped = pow(mapped, vec3(1.0 / gamma));
FragColor = vec4(mapped, 1.0);
}
理解:
因为光照计算很多时候计算出来的颜色值会超过1,那么如果把超过1的颜色值 传入一个普通的,格式是RGB的frameFuffer中,这些超过1的颜色值会被clamp,所以就会涉及到 framebuffer可以保存超过1 的颜色值。
所谓的HDR,其实就是 Floating point framebuffers,framebuffers 除了保存[0, 1],还可以保存超过1的值。之后利用 Tone mapping 算法来 执行 HDR -> LDR , 并且保留更加多的细节,再进行输出到普通的RGB framebuffer上,再输出到显示器上。
上一篇: OpenGL学习笔记(十二)
下一篇: 代理传值 delegate