如何在顶点着色器中将坐标从NDC转换为相机空间



我正在维护一个封装在自定义材质类中的顶点着色器(从ShaderMaterial继承,但现在从MeshStandardMaterial继承(,该类可以像往常一样将3D坐标转换为NDC:

vec4 ndcPos = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
ndcPos /= ndcPos.w;
//...other transformations to ndcPos

则将一组变换应用于CCD_ 3。正如您所看到的,它们被应用于NDC领域。我需要将结果坐标带回相机(眼睛(空间,所以我想我们需要反转步骤,比如这样:

vec4 mvPos = ndcPos * ndcPos.w;
mvPos *= inverse of projectionMatrix;

预期结果:mvPos仅应用了modelView转换。

问题:

  1. 对吗
  2. 如何计算projectionMatrix的逆?将camera.projectionMatrixInverse作为统一材质传递给顶点着色器既简单又低成本,但我在three.js中找不到这样做的方法:祖先材质类和onBeforeCompile都无法访问摄影机

计算视图空间位置的逆运算是

vec4 p = inverse(projectionMatrix) * ndc;
vec4 mvPos = p / p.w;

并且计算物体位置的逆运算是

vec4 p = inverse(projectionMatrix * modelViewMatrix) * ndc;
vec4 pos = p / p.w;

(注意,在上述代码中,pos对应于属性positionmvPos对应于position * modelViewMatrix。(

注意:如果用透视投影矩阵(或逆透视投影矩阵(变换笛卡尔坐标,结果是齐次坐标。若要将齐次坐标转换为笛卡尔坐标,必须执行"透视除法"(在"透视除法之后,分量w为1(
需要注意的是,inverse函数仅在GLSL ES 3.00(WebGL 2.0(之后才存在,在GLSL ES1.00(WebGL 1.0(中不可用。因此,可能需要在Javascript中计算逆矩阵,并将其作为统一变量传递给着色器。

最新更新