GAMES101:作业3

这篇博客详细介绍了GAMES101课程作业3的内容,包括在rasterizer.cpp中实现法向量、颜色和纹理颜色的插值算法,以及在main.cpp中实现Blinn-Phong光照模型、纹理贴图和凹凸贴图。通过修改fragment shader函数,分别实现了Texture Shading和Bump Mapping效果,并对比了环境光照放置位置对最终渲染的影响。
摘要由CSDN通过智能技术生成

GAMES101:作业3

附其他所有作业超链接如下:
Games101 作业0:作业0
Games101 作业1:作业1
Games101 作业2:作业2
Games101 作业3:作业3
Games101 作业4:作业4
Games101 作业5:作业5
Games101 作业6:作业6
Games101 作业7:作业7

完整代码获取途径:
https://github.com/liupeining/Games_101_homework

照旧把这段代码粘贴过来:

Eigen::Matrix4f get_projection_matrix(float eye_fov, float aspect_ratio, float zNear, float zFar)
{
   
    float n = zNear;
    float f = zFar;
    Eigen::Matrix4f projection = Eigen::Matrix4f::Identity();
    float t = -tan((eye_fov/360)*MY_PI)*(abs(n)); //top
    float r = t/aspect_ratio;

    Eigen::Matrix4f Mp;//透视矩阵
    Mp << 
        n, 0, 0,   0,
        0, n, 0,   0,
        0, 0, n+f, -n*f,
        0, 0, 1,   0;
    Eigen::Matrix4f Mo_tran;//平移矩阵
    Mo_tran <<
        1, 0, 0, 0,
        0, 1, 0, 0,  //b=-t;
        0, 0, 1, -(n+f)/2 ,
        0, 0, 0, 1;
    Eigen::Matrix4f Mo_scale;//缩放矩阵
    Mo_scale << 
        1/r,     0,       0,       0,
        0,       1/t,     0,       0,
        0,       0,       2/(n-f), 0,
        0,       0,       0,       1;
    projection = (Mo_scale*Mo_tran)* Mp;//投影矩阵
    //这里一定要注意顺序,先透视再正交;正交里面先平移再缩放;否则做出来会是一条直线!
    return projection;
}

修改函数 rasterize_triangle(const Triangle& t) in rasterizer.cpp: 在此 处实现与作业 2 类似的插值算法,实现法向量、颜色、纹理颜色的插值。
下面三角形的rasterizer和上次的思路完全一致,这里仍然沿用了MSAA;
大部分都和上次的代码相同,更改以及需要注意的地方均在代码中做了注释。
其实区别就在于添加了用重心坐标各种插值最终返回一个color

void rst::rasterizer::rasterize_triangle(const Triangle& t, const std::array<Eigen::Vector3f, 3>& view_pos) 
{
   
    auto v = t.toVector4(); //v[0],v[1],v[2]分别为三角形的三个顶点,是四维向量
    //比较三个顶点的横纵坐标,确定包围盒的边界并取整
    double min_x = std::min(v[0][0], std::min(v[1][0], v[2][0]));
    double max_x = std::max(v[0][0], std::max(v[1][0], v[2][0]));
    double min_y = std::min(v[0][1], std::min(v[1][1], v[2][1]));
    double max_y = std::max(v[0][1], std::max(v[1][1], v[2][1]));
    min_x = static_cast<int>(std::floor(min_x));
    min_y = static_cast<int>(std::floor(min_y));
    max_x = static_cast<int>(std::ceil(max_x));
    max_y = static_cast<int>(std::ceil(max_y));
    //此处实现的是MSAA
    std::vector<Eigen::Vector2f> pos
    {
                                  //对一个像素分割四份 当然你还可以分成4x4 8x8等等甚至你还可以为了某种特殊情况设计成不规则的图形来分割单元
        {
   0.25,0.25},                //左下
        {
   0.75,0.25},                //右下
        {
   0.25,0.75},                //左上
        {
   0.75,0.75}                 //右上
    };
    for (int i = min_x; i <= max_x; ++i)
    {
   
        for (int j = min_y; j <= max_y; ++j)
        {
   
            int count = 0; //开始遍历四个小格子,获得平均值
            for (int MSAA_4 = 0; MSAA_4 < 4; ++MSAA_4)
            {
   
                if (insideTriangle(static_cast<float>(i+pos[MSAA_4][0]), static_cast<float>(j+pos[MSAA_4][1]),t.v))
                    ++count;
            }
            if(count) //至少有一个小格子在三角形内
            {
   
                //此处是框架中代码,获得z,见原程序注释:
                //    * v[i].w() is the vertex view space depth value z.
                //    * Z is interpolated view space depth for the current pixel
                //    * zp is depth between zNear and zFar, used for z-buffer
                auto[alpha, beta, gamma] = computeBarycentric2D(i 
  • 16
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值