Логарифмическая глубина буфера линеаризации
Как линеаризовать логарифмический буфер глубины?
визуализация буфера линейной глубины во фрагментном шейдере
float n = 1.0; // camera z near
float f = 27000000.0; // camera z far
float z = texture( DepthTex, TexCoord ).x;
float d = (2.0 * n) / (f + n - z * (f - n));
FragColor=vec4(d,d,d,1);
сферический вершинный шейдер
vec4 ClipCoords(vec3 position,mat4 matrix)
{
vec4 clip = matrix * vec4(position,1.0f);
clip.z =((2.0f * log(1.0f * clip.z + 1.0f) / log(1.0f * 27000000.0f + 1.0f)) - 1.0f) * clip.w;
return clip;
}
gl_Position = ClipCoords(position,matrix);
Левая часть показывает линеаризацию буфера логарифмической глубины или, скорее, ее недостатки, а правая показывает линеаризацию без log
просто gl_Position = matrix * vec4(position,1.0f);
1 ответ
При использовании логарифмического буфера глубины отображение глубины сцены (пространства камеры) на значения, которые в конечном итоге оказываются в буфере глубины (0..1):
depth_value = log(C*z + 1) / log(C*Far + 1)
где z - положительная глубина в сцене, которую можно получить из компонента w в пространстве клипа после проекции (в своем коде вы можете использовать..log(clip.w + 1.0)..).
Чтобы получить глубину пространства камеры в фрагментном шейдере, уравнение необходимо инвертировать:
z = (exp(depth_value*log(C*far+1)) - 1)/C
или эквивалентно
z = (pow(C*far+1,depth_value)-1)/C
Чтобы получить линейное отображение от 0..far до 0..1, просто разделите его на дальнее значение.