Есть такой расчет матрицы проекции у меня в софт.ренд. проект.
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. Или почему? Заранее спасибо.
-Q*fZNear -> при fZNear = 0 сам равен 0
Из-за этого в W вектора после умножения тоже становится 0. А во время perspective divide, все координаты вектора делятся на W (который в этом случае 0), что ломает всё
Спасибо за ответ, я еще не очень понял как значения заносятся в 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; На всякий случай замечу, что при желании без отсечения по передней и задней плоскости (да и без самих плоскостей) можно обойтись. В софтрендере это может быть вполне с тему.
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 она больше про буфер глубины и его точность, а не про что-то фундаментально-геометрическое.
Спасибо!
Тема в архиве.