gs_ortho正交投影矩阵
2024-12-13
8
0
在DirectX 11中,正交投影矩阵用于将3D场景投影到2D屏幕上,而不会产生透视效果。正交投影矩阵通常用于2D渲染、UI元素、或需要保持对象相对大小不变的场景。
说人话就是对空间区域进行裁剪投影到2D平现。
https://www.vaczh.com/article/detail-148.html
在Direct3D 11(D3D11)中,默认的投影区间(也称为规范化设备坐标,Normalized Device Coordinates, NDC)通常是 [-1, 1] 范围内的值。
这意味着:
- X 轴:从 -1 到 1,其中 -1 表示屏幕的最左边,1 表示屏幕的最右边。
- Y 轴:从 -1 到 1,其中 -1 表示屏幕的最底部,1 表示屏幕的最顶部。
- Z 轴:从 0 到 1,其中 0 表示最近的裁剪面(近平面),1 表示最远的裁剪面(远平面)。
但实际的坐标不可能为规范化坐标,故需要进行正交投影。
在OBS中,正交投影矩阵使用参数curProjMatrix来表示。其生成方式如下:
void device_ortho(gs_device_t *device, float left, float right, float top, float bottom, float zNear, float zFar)
{
matrix4 *dst = &device->curProjMatrix;
float rml = right - left; // 计算视口宽度
float bmt = bottom - top; // 计算视口高度
float fmn = zFar - zNear; // 计算近远平面距离差
// 初始化矩阵为零矩阵
vec4_zero(&dst->x);
vec4_zero(&dst->y);
vec4_zero(&dst->z);
vec4_zero(&dst->t);
// 设置矩阵的对角线元素
dst->x.x = 2.0f / rml; // X轴缩放因子
dst->t.x = (left + right) / -rml; // X轴平移因子
dst->y.y = 2.0f / -bmt; // Y轴缩放因子(注意这里是负值)
dst->t.y = (bottom + top) / bmt; // Y轴平移因子
dst->z.z = 1.0f / fmn; // Z轴缩放因子
dst->t.z = zNear / -fmn; // Z轴平移因子
dst->t.w = 1.0f; // 设置w分量为1
}
将{r,l}映射到{-1,1}区间,求{r,l}上位一值在{-1,1}区间的值
设三维物体在观察空间中的坐标为Pview,投影矩阵为Mproj,则顶点在投影空间中的坐标为:
Pproj = Pview * Mproj
void gs_device::UpdateViewProjMatrix()
{
gs_matrix_get(&curViewMatrix);
/* negate Z col of the view matrix for right-handed coordinate system */
curViewMatrix.x.z = -curViewMatrix.x.z;
curViewMatrix.y.z = -curViewMatrix.y.z;
curViewMatrix.z.z = -curViewMatrix.z.z;
curViewMatrix.t.z = -curViewMatrix.t.z;
//相乘
matrix4_mul(&curViewProjMatrix, &curViewMatrix, &curProjMatrix);
//因数据存储的问题,需要转置
matrix4_transpose(&curViewProjMatrix, &curViewProjMatrix);
if (curVertexShader->viewProj)
gs_shader_set_matrix4(curVertexShader->viewProj, &curViewProjMatrix);
}
curViewMatrix这里给出单位矩阵即可。故在着色器中
uniform float4x4 ViewProj;
VertInOut VSDefault(VertInOut vert_in)
{
VertInOut vert_out;
vert_out.pos = mul(float4(vert_in.pos.xyz, 1.0), ViewProj);
vert_out.uv = vert_in.uv;
return vert_out;
}
即可将坐标归一下到规范化设备坐标中会坐标显示。