返回

URasterizer实现(1):框架搭建和矩阵构造

前端

在探索游戏图形技术过程中,若对底层的实现略知一二,就会发现简单而强大的实现往往离不开一些很深奥的数学知识。软光栅化作为如今高精度光栅化的雏形,从原理上说,也不存在太大的难度,如果说有什么晦涩难懂的东西,我想就是其中所蕴含的那些数学知识。

本文将基于Unity引擎创建一个软光栅实现的项目,并分成三个系列文章进行详细阐述:

  1. 项目的框架搭建和模型视图投影矩阵的构造;
  2. 栅格化与光栅化算法;
  3. 其他功能的实现(例如Z-buffer、纹理贴图、光照等)。

本文重点关注项目的框架搭建以及模型视图投影矩阵的构造。

框架搭建

新建Unity项目,项目命名为URasterizer,创建Assets文件夹下的Scenes、Scripts、Shaders三个子文件夹,分别用于存放场景、脚本和着色器。

1. 场景搭建

新建场景main,在场景中创建一个名为Camera的主摄像机,并设置其位置和朝向。

2. 脚本编写

在Scripts文件夹下创建URasterizer脚本,用于控制光栅化的过程。URasterizer脚本主要包含以下几个函数:

  • Start() :在场景开始时调用,用于初始化相关变量。
  • Update() :在每一帧调用,用于更新光栅化的过程。
  • OnRenderImage() :在每一帧渲染图像时调用,用于执行光栅化算法。

3. 着色器编写

在Shaders文件夹下创建VertexShader和FragmentShader两个着色器文件,用于处理顶点和片元。

VertexShader着色器主要用于将顶点坐标从模型空间变换到裁剪空间,其代码如下:

#pragma vertex vert

struct appdata {
    float4 position : POSITION;
};

struct v2f {
    float4 position : SV_POSITION;
};

v2f vert(appdata v) {
    v2f o;
    o.position = mul(UNITY_MATRIX_MVP, v.position);
    return o;
}

FragmentShader着色器主要用于将片元颜色从裁剪空间变换到屏幕空间,其代码如下:

#pragma fragment frag

struct v2f {
    float4 position : SV_POSITION;
};

fixed4 frag(v2f i) : SV_TARGET {
    return fixed4(1, 0, 0, 1);
}

矩阵构造

在URasterizer脚本中,我们使用Unity提供的矩阵函数来构造模型视图投影矩阵。模型视图投影矩阵由模型矩阵、视图矩阵和投影矩阵相乘得到。

1. 模型矩阵

模型矩阵用于将模型坐标变换到世界坐标。模型矩阵的构造非常简单,只需要使用Matrix4x4.TRS(position, rotation, scale)函数即可。

// 模型矩阵
Matrix4x4 modelMatrix = Matrix4x4.TRS(modelPosition, modelRotation, modelScale);

2. 视图矩阵

视图矩阵用于将世界坐标变换到摄像机坐标。视图矩阵的构造也比较简单,只需要使用Camera.main.worldToCameraMatrix属性即可。

// 视图矩阵
Matrix4x4 viewMatrix = Camera.main.worldToCameraMatrix;

3. 投影矩阵

投影矩阵用于将摄像机坐标变换到裁剪空间。投影矩阵的构造稍微复杂一些,我们需要使用Matrix4x4.Perspective(fieldOfView, aspect, near, far)函数。

// 投影矩阵
Matrix4x4 projectionMatrix = Matrix4x4.Perspective(60, (float)Screen.width / (float)Screen.height, 0.1f, 1000f);

4. 模型视图投影矩阵

模型视图投影矩阵由模型矩阵、视图矩阵和投影矩阵相乘得到。

// 模型视图投影矩阵
Matrix4x4 mvpMatrix = projectionMatrix * viewMatrix * modelMatrix;

在URasterizer脚本中,我们将模型视图投影矩阵传递给顶点着色器,以便顶点着色器能够将顶点坐标从模型空间变换到裁剪空间。

以上就是基于Unity的软光栅实现项目框架的搭建和模型视图投影矩阵的构造过程。在下一篇博文中,我们将介绍光栅化与栅格化算法。