Войти
ПрограммированиеПодсказкиГрафика

Равномерное распределение глубины в z буфере.

Автор:

Как известно, при применении обычной перспективной матрицы проекций мы получаем следующие выражения для экранных координат...

(экранные координаты указаны с суффиксом s, координаты в view space указаны с суффиксом v)

Xs =  2*Xv*Znear/Zv/ScreenWidth              (1)
Ys =  2*Yv*Znear/Zv/ScreenHeight              (2)
Zs =  (Zv–Znear)*Zfar/Zv/(Zfar–Znear)        (3)

где ScreenWidth и ScreenHeight — размеры плоскости, на которую происходит проекция в мировых координатах. В формулах уже учтено деление всех компонент вектора на червертую (W)

Из формулы (3) видно, что преобразование z нелинейно. Это может приводить к неприятным последстиям (о них ниже). Для того, чтобы преобразование было линейным, было бы разумно применить следующую формулу для z:

Zs =  (Zv–Znear)/(Zfar–Znear)                      (4)

В этом случае мы получим равномерное распределение глубины. При этом соглашения о величинах z не нарушаются:

Вот так примерно это можно реализовать в шейдере (используя (1),(2),(4)):

matrix WorldView;
float Zfar;
float Znear;
float ScreenWidth;
float ScreemHeight;

float4 VertexShader (float4 inPos : POSITION)    :POSITION
{
  float4 vec;
  vec=mul(inPos,WorldView);
  vec=float4(vec.x/vec.z*Znear/ScreenWidth,vec.y/vec.z*Znear/ScreenHeight,(vec.z-Znear)/(Zfar-Znear),vec.w);  
  return vec;
}

Плюсы этой методики:

Минусы этой методики:

#буферы, #z-fighting, #глубина

10 ноября 2009 (Обновление: 11 ноя. 2009)

Комментарии [42]

Военная ипотека вариант от сбербанка www.molodostroy24.ru.