THREEjs中的定点着色器

什么是着色器

着色器是用 GLSL 编写的程序,发送到 GPU。它们用于定位几何体的每个顶点并为几何体的每个可见像素着色。术语“像素”并不准确,因为渲染中的每个点并不一定与屏幕的每个像素相匹配,这就是为什么我们用“片段”这个词的原因。

顶点着色器

顶点着色器的目的是确定几何体的顶点位置。我们需要发送顶点位置、网格变换(如位置、旋转和缩放)、相机信息(如位置、旋转和视野)。然后,GPU 将遵循顶点着色器中的指令来处理所有这些信息,以便将顶点投影到一个 2D 空间,也就是我们的渲染器——换句话说,就是我们的屏幕。

在使用顶点着色器时,它的代码将应用于几何体的每个顶点。但是,像顶点位置这样的数据在每个顶点之间会发生变化。这种在顶点之间发生变化的数据被称为属性(attribute)。然而,有些数据在每个顶点之间并不需要改变,比如网格的位置。这种在顶点之间不发生变化的数据被称为统一变量(uniform)。

const material = new THREE.RawShaderMaterial({
  vertexShader: `
    uniform mat4 projectionMatrix;
    uniform mat4 viewMatrix;
    uniform mat4 modelMatrix;
    attribute vec3 position;
    void main()
    {
      gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);
    }
  `,
  fragmentShader: `
    precision mediump float;
    void main()
    {
      gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
  `
})

其中vertexShader就是使用到modelMatrix, viewMatrix, projectionMatrix来计算gl_Position,也就是投影位置;

  1. 模型矩阵(Model Matrix):模型矩阵表示物体在 3D 世界坐标系中的位置、旋转和缩放。模型矩阵将物体的本地坐标转换为世界坐标。
  2. 视图矩阵(View Matrix):视图矩阵定义了摄像机(或观察者)在 3D 世界中的位置和方向。视图矩阵将世界坐标转换为摄像机坐标,这个坐标系以摄像机为原点,以摄像机的方向为 Z 轴。
  3. 投影矩阵(Projection Matrix):投影矩阵定义了摄像机的投影类型(透视投影或正交投影)和视锥体的参数。投影矩阵将摄像机坐标系中的坐标投影到归一化设备坐标(NDC,Normalized Device Coordinates)空间,该空间的坐标范围为 [-1, 1],在 X、Y 和 Z 轴上。

在进行投影计算时,Three.js 首先将物体的顶点坐标乘以模型矩阵,将其从本地坐标系转换为世界坐标系。接着,乘以视图矩阵,将世界坐标转换为摄像机坐标。最后,乘以投影矩阵,将摄像机坐标投影到归一化设备坐标空间。

完成投影计算后,顶点坐标在归一化设备坐标空间中。接下来,Three.js 会将这些坐标映射到屏幕空间,这涉及到将归一化设备坐标转换为屏幕坐标。通常,这个过程包括将 X 和 Y 轴上的坐标乘以屏幕宽度和高度的一半,然后加上屏幕宽度和高度的一半,将坐标范围从 [-1, 1] 映射到屏幕像素范围。

gl_Position是一个在 OpenGL 和 WebGL 的顶点着色器(vertex shader)中使用的内置变量。它表示顶点在剪裁空间(clip space)中的位置。顶点着色器的主要任务是计算 3D 场景中每个顶点的最终位置,以便在屏幕上正确地显示 3D 图形。

在剪裁空间中,坐标值在 X、Y 和 Z 轴上都在范围 [-1, 1] 内。因此,gl_Position的范围是:

  • X 轴:-1 到 1
  • Y 轴:-1 到 1
  • Z 轴:-1 到 1
  • W 分量:通常为 1(用于齐次坐标)

这是一个四维向量,X、Y 和 Z 分量表示顶点在剪裁空间的位置,而 W 分量表示齐次坐标。在顶点着色器完成计算并输出 gl_Position 后,图形管线的下一阶段将执行剪裁和透视除法,将顶点从剪裁空间转换为归一化设备坐标(NDC)。

透视除法是通过将 gl_Position 的 X、Y 和 Z 分量分别除以 W 分量来完成的。在大多数情况下,W 分量等于 1,因此在透视除法之后,NDC 坐标的范围仍然是 [-1, 1]。不过,W 分量在某些情况下可能与 Z 分量有关,以实现透视投影的效果。在透视除法之后,顶点坐标会映射到屏幕空间,以生成最终的 2D 图像。

代码解释:

uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
attribute vec3 position;

这里的position就是顶点的坐标,它是一个三维向量,然后代码中有三个四维矩阵,每个矩阵都将执行部分转换:

modelMatrix 将应用与 Mesh 相关的所有变换。如果我们缩放、旋转或移动 Mesh,这些变换将包含在 modelMatrix 中并应用于position。

viewMatrix 将应用与相机相关的变换。如果我们向左旋转相机,顶点应该在右边。如果我们朝着 Mesh 的方向移动相机,顶点应该变大等等。

projectionMatrix 最终将我们的坐标转换成最终的裁剪空间坐标。

要应用矩阵,我们将其相乘。如果我们想要将 mat4 应用于一个变量,这个变量必须是 vec4。我们还可以将矩阵与其他矩阵相乘:

gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position, 1.0);

实际上还可以简写,其中 viewMatrix 和 modelMatrix 被合并成一个 modelViewMatrix:

gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);

在这里的公式中,* 符号表示的是矩阵乘法,而不是叉积或点积。在 3D 图形渲染中,矩阵乘法用于将顶点从一个坐标系转换到另一个坐标系。例如,将顶点从模型空间转换到世界空间、从世界空间转换到摄像机空间,以及从摄像机空间投影到剪裁空间。

矩阵乘法在数学上有一些特殊的性质,例如不满足交换律。在 3D 图形中,矩阵乘法的顺序非常重要,因为它决定了变换的执行顺序。例如,要将顶点从模型空间投影到剪裁空间,需要按照以下顺序执行矩阵乘法:

顶点(剪裁空间) = 投影矩阵 * 视图矩阵 * 模型矩阵 * 顶点(模型空间)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值