相机如何从剪辑空间转换为屏幕空间?

egu*_*eys 2 javascript webgl

我想在没有 webgl 的情况下将一堆 3d 点渲染到 2d 画布中。我认为剪辑空间和屏幕空间是同一件事,相机用于从 3d 世界空间转换为 2d 屏幕空间,但显然它们不是。

所以在webgl上,设置时gl_Position,它是在剪辑空间中,后来这个位置被webgl转换为屏幕空间,并被gl_FragCoord设置。这个计算是如何进行的以及在哪里进行?

相机矩阵和视图投影矩阵与将剪辑空间转换为屏幕空间无关。我可以拥有一个适合剪辑空间的 3D 世界空间,而且我不需要使用相机,对吗?

如果我的所有假设都是正确的,我需要学习如何从剪辑空间转换为屏幕空间。这是我的代码:

const uMatrix = mvpMatrix(modelMatrix(transform));

 // transform each vertex into 2d screen space
vertices = vertices.map(vertex => {
  let res = mat4.multiplyVector(uMatrix, [...vertex, 1.0]);
  // res is vec4 element, in clip space,
  // how to transform this into screen space?
  return [res[0], res[1]];
});


// viewProjectionMatrix calculation
const mvpMatrix = modelMatrix => {
  const { pos: camPos, target, up } = camera;
  const { fov, aspect, near, far } = camera;

  let camMatrix = mat4.lookAt(camPos, target, up);
  let viewMatrix = mat4.inverse(camMatrix);

  let projectionMatrix = mat4.perspective(fov, aspect, near, far);

  let viewProjectionMatrix = mat4.multiply(projectionMatrix, viewMatrix);

  return mat4.multiply(viewProjectionMatrix, modelMatrix);
};
Run Code Online (Sandbox Code Playgroud)

本文提到的相机将剪辑空间转换为屏幕空间,如果是这样的话,它不应该被命名为相机,对吗?

Rab*_*d76 6

首先,根据裁剪空间坐标 ( gl_Position) 裁剪几何体。剪辑空间坐标是齐次坐标。齐次坐标位于裁剪空间的条件是:

-w <=  x, y, z  <= w.
Run Code Online (Sandbox Code Playgroud)

通过Perspective div将剪辑空间坐标转换为标准化设备空间中的笛卡尔坐标

ndc_position = gl_Position.xyz / gl_Position.w
Run Code Online (Sandbox Code Playgroud)

标准化设备空间是一个立方体,左下前部为(-1,-1,-1),右上后部为(1,1,1)。

标准化设备空间坐标的 x 和 y 分量线性映射到视口,其设置为gl.viewport(请参阅WebGL Viewport)。视口是一个具有原点 ( x, y) 以及 awidth和 a 的矩形height

ndc_position = gl_Position.xyz / gl_Position.w
Run Code Online (Sandbox Code Playgroud)

xw并可以在片段着色器中yw访问。gl_FragCoord.xy

标准化设备空间坐标的 z 分量线性映射到深度范围,默认为 [0.0, 1.0],但可以通过 设置gl.depthRange。请参阅视口深度范围。深度范围由一个near值和一个far值组成。far必须大于near并且两个值都必须在 [0.0, 1.0] 范围内:

xw = (ndc_position.x + 1) * (width / 2) + x
yw = (ndc_position.y + 1) * (height / 2 ) + y 
Run Code Online (Sandbox Code Playgroud)

可以在片段着色器中depth访问。gl_FragCoord.z

所有这些操作都是在渲染管道中自动完成的,并且是顶点后处理的一部分。