ПрограммированиеФорумГрафика

Ближняя плоскость отсечения

#0
16:25, 9 авг 2021

Есть такой расчет матрицы проекции у меня в софт.ренд. проект.

typedef float matrix4x4[4][4];

  float fFov = 3.14f/2.0f; // FOV 90 degree
    float fAspect = 640.0f/480.0f;
    float fZFar = 100.0f;
    float fZNear = 1.0f;
 
    float    h, w, Q;
    w = (float)(1/tan(fFov*0.5f))/fAspect;
    h = (float)1/tan(fFov*0.5f);
    Q = fZFar/(fZFar - fZNear);
 
        matrix4x4 mProj={
    w, 0, 0, 0,
    0, h, 0, 0,
    0, 0, Q, 1,
    0, 0, -Q*fZNear, 0      };

Код работает все отлично. Но у меня вопрос- почему при расчете матрицы проекции (перспективной матрицы) ближняя плоскость отсечения не может быть равна нулю, а принимается где то 0.1 или возле 1.0? Там как то связано с тем что если ближняя плоскость отсечения будет ноль то в результате Z будет равно нулю а на ноль делить нельзя в плане x/z и y/z. Или почему? Заранее спасибо.

#1
17:03, 9 авг 2021

-Q*fZNear -> при fZNear = 0 сам равен 0

Из-за этого в W вектора после умножения тоже становится 0. А во время perspective divide, все координаты вектора делятся на W (который в этом случае 0), что ломает всё

#2
18:43, 9 авг 2021

Спасибо за ответ, я еще не очень понял как значения заносятся в  ZBuffer. Например есть код:

         struct vec3
         {
         float x,y,z;
         };

        //объявляем вектор глубина z = 10.0
        vec3 v = { 10.0f, 10.0f, 10.0f };

  //умножаем этот вектор на матрицу выше
  vec3 ret = Vec3_Mat4x4_Mul(v, mProj);

  //zBuff будет равно 0.9090
  float zBuff = ret.z / v.z; 

Тут мне не очень ясно что z буфер будет заполнен значением 0.9090 в то время как надо делить на zFar (дальняя плоскость отсечения), т.е.

  float zBuff = ret.z / fZFar; 
#3
19:15, 9 авг 2021

На всякий случай замечу, что при желании без отсечения по передней и задней плоскости (да и без самих плоскостей) можно обойтись. В софтрендере это может быть вполне с тему.
OpenGL умеет обходиться так:
http://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_depth_clamp.txt
Т. к. отсечение по боковым плоскостям (-w<x<+w, -w<y<+w) происходит, то точки за камерой (w<0) гарантировано отсекаются.

Матрица из #0 выглядит чуть странно.
Матрица из http://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPerspective.xml при переходе zNear->0, zFar->inf переходит в

 f/a   0   0   0
   0   f   0   0
   0   0  -1   0
   0   0  -1   0

где f=ctg(FOVy/2), a=width/height.
Если в буфер глубины при этом писать прямо w или 1/w - так оно вполне применимо.

Вот здесь ещё
https://computergraphics.stackexchange.com/questions/5116/how-am-… -a-near-plane
звучит мысль, что near plane она больше про буфер глубины и его точность, а не про что-то фундаментально-геометрическое.

#4
19:18, 9 авг 2021

Спасибо!

ПрограммированиеФорумГрафика

Тема в архиве.