GAMES101(2~3作业)

news2024/9/21 23:04:25

 作业2

基础题目:

栅格化:在屏幕绘制一个实心三角形,函数 rasterize_triangle(const Triangle& t),需要找出当前三角形的边界框,然后遍历像素,查找当前像素是否在三角形内static bool insideTriangle(),

深度测试:如果在三角形内,代码已经自动计算z值(插值得到)存储在z_interpolated中,如果当前点更靠近相机,需要请设置像素颜色(使用 set_pixel 函数)并更新深度缓冲区

解:

首先创建三角形边界,分别为3个顶点的,xy坐标的最大最小值

 auto v = t.toVector4();
 float alpha, beta, gamma, lmin=INT_MAX, rmax=INT_MIN, tmax=INT_MIN, bmin=INT_MAX;
for(auto &k:v){
    lmin = int(std::min(lmin,k.x()));
    rmax = std::max(rmax,k.x());rmax = rmax == int(rmax) ? int(rmax)-1 : rmax;
    tmax = std::max(tmax,k.y());tmax = tmax == int(tmax) ? int(tmax)-1 : tmax;
    bmin = int(std::min(bmin,k.y()));
}

 接着遍历每个像素,如果像素中心在三角形内,用插值计算深度,如果深度值 < 屏幕坐标的深度值,就更新颜色值和深度缓冲,总体来说使用了作业框架的API

for(float i = lmin; i <= rmax; i++){
    for(float j = bmin; j <= tmax; j++){
        if(insideTriangle(i, j, t.v)){
            /* 计算z深度 */
            std::tie(alpha, beta, gamma) = computeBarycentric2D(i+0.5, j+0.5, t.v);
            float w_reciprocal = 1.0/(alpha / v[0].w() + beta / v[1].w() + gamma / v[2].w());
            float z_interpolated = alpha * v[0].z() / v[0].w() + beta * v[1].z() / v[1].w() + gamma * v[2].z() / v[2].w();
            z_interpolated *= w_reciprocal;

            if(-z_interpolated < depth_buf[get_index(i,j)]){/* 当前深度 < 深度缓冲中的深度值 */
                set_pixel({i,j,1},t.getColor());/* 设置当前像素颜色值 */
                depth_buf[get_index(i,j)] = -z_interpolated;/* 更新深度缓冲 */
            }
        }
    }
}

下一步判断坐标是否在三角形内部,根据老师课上讲的叉积判断,如果一个点在三角形所有边的同一侧,就为内部 。ver存储的是三个线框的向量(需要同一的顺时针或逆时针),ver2存储的是从xy坐标为终点到三个点的向量。循环比较每个边和xy向量的叉积,

比如顺时针绘制三角形,需要判断z值是否为负

static bool insideTriangle(int x, int y, const Vector3f* _v)
{   
    std::vector<Vector3f> ver, ver2;

    ver.push_back({_v[1].x()-_v[0].x(),_v[1].y()-_v[0].y(),0}); ver2.push_back({x-_v[0].x(),y-_v[0].y(),0});    
    ver.push_back({_v[2].x()-_v[1].x(),_v[2].y()-_v[1].y(),0}); ver2.push_back({x-_v[1].x(),y-_v[1].y(),0});
    ver.push_back({_v[0].x()-_v[2].x(),_v[0].y()-_v[2].y(),0}); ver2.push_back({x-_v[2].x(),y-_v[2].y(),0});

    for(int i=0;i<3;i++){
        if(ver[i].cross(ver2[i]).z() < 0)
            return false;
    }
    return true;
}

图像颠倒和镜像翻转问题:

发现绘制的三角形是上下颠倒的,错误原因其实是opencv原点在左上角,而代码框架用的是左下,

注意opegl规范化设备坐标NDC是右手坐标系而非左手:direct和opencv采用的都是左手,因为定义opencv原点为左上,需要将左手坐标系翻转,导致+y向下的坐标系

比如传入一下坐标点:按照右手坐标系带入这组顶点,符合作业的输出结果,但是由于OpenCV是左手坐标系,带入完全会得到相反的结果,所以应该将图像翻转

{2, 0, -2},
{0, 2, -2},
{-2, 0, -2},

{3.5, -1, -5},
{2.5, 1.5, -5},
{-1, 0.5, -5}

经过查找网上的题解,需要更改透视矩阵,在转换的时候直接应用翻转

    proj << 
        zNear, 0, 0, 0,
        0, zNear, 0, 0,
        0, 0, (zNear + zFar) / (zFar - zNear), (2 * zNear * zFar) / (zFar - zNear),
        0, 0, -1, 0;

得到结果: 

提高题目:

解决走样问题,实现MSAA:每一个像素建立4个采样点,需要维护一个 sample list,你得到的三角形不应该有不正常的黑边

解:

首先建立采样点偏移量,然后对每个像素采样4次,判断是否在三角形内,如果在就加上权重值,最后乘以平均权重值

黑边问题:黑边出现两个三角交界处,这是因为这个像素由两部分组成,假设靠前(深度值小)的仅仅覆盖了1/4的采样点,那么最终颜色会接近黑色,展现黑边

所以应该对每个像素的所有采样点中存储颜色,然后求平均值,

比如这里的颜色,由于靠后物体更新了3/4,靠前物体更新了1/4,所以求它们的平均值

通过4倍的后台深度缓冲区和颜色缓冲区,存储每个采样点的颜色和深度,

而对于正常的前台缓冲区,颜色为所有采样点的颜色平均值,深度为最小深度

std::vector<float> a{0.25,0.25,0.75,0.75,0.25};
mindep = INT_MAX;//像素的深度
eid = get_index(i,j)*4;//像素的索引
……
for(int k = 0; k < 4; k++){{
    if(insideTriangle(i+a[k], j+a[k+1], t.v)){
        if (-z_interpolated < depth_sample[eid + k])
        {
          depth_sample[eid + k] = -z_interpolated;//后台深度缓冲--采样点
          frame_sample[eid + k] = t.getColor() / 4;//后台颜色缓冲--采样点
        }
        mindep = std::min(depth_sample[eid + k], mindep);
    }
}
color = frame_sample[eid] + frame_sample[eid + 1] + frame_sample[eid + 2] +frame_sample[eid + 3];//像素颜色为采样点的平均值
set_pixel({i,j,1}, color);//仅更新1次像素颜色
depth_buf[get_index(i,j)] = std::min(depth_buf[get_index(i,j)], mindep);//深度为采样点中最小值

作业三

框架

这次作业框架通过Object Loader加载一个3维模型,并提供 了Vertex Shader 与 Fragment Shader着色器

  1. main入口点
    1. active_shader通用函数绑定,表示当前绑定哪个着色器

  2. rasterizer屏幕光栅器类
    1. draw计算顶点数据
    2. rasterize_triangle插值,并设置最终颜色

  3. obj_loader第三方.obj 文件加载库
  4. global全局常量数据
  5. shader着色器类
    1. 提供了,片段和顶点shader的数据加载
  6. texture纹理类
    1. 通过opencv,从图片生成纹理
    2. getColor查找纹理颜 色的接口
  7. triangle三角形网格类

题目:

我们需要编写的代码部分:

  1. rasterize_triangle实现插值
  2. phong_fragment_shader() 实现 Blinn-Phong 模型fragment shader
  3. texture_fragment_shader()纹理fragment shader
  4. bump_fragment_shader()凹凸贴图fragment shader
  5. displacement_fragment_shader()位移贴图的fragment shader

其中在运行可执行文件时,第二个参数是生成的图片文件名,第3个参数可以是texture,normal,phong,bump,shader其中之一

解:

首先填写了rasterize_triangle和调用normal后

使用normal shader

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2135202.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ESP32开发 -- 初识

一、ESP32官网 ESP32官网 二、文档下载 用的是ESP32-S3-MINI-1&#xff0c;官网查看相关文档 相关文档 三、技术规格书 四、开发板 参看&#xff1a;ESP32-S3 系列开发板 ESP32-S3-MINI-1 相关开发板的示例代码&#xff0c;后续可以参考。 Espressif Systems esp-dev-…

9天也能养成ins账号!超详细操作指南

Instagram&#xff0c;作为全球最受欢迎的社交媒体平台之一&#xff0c;为跨境电商卖家们提供了一个展示产品、吸引潜在客户的绝佳舞台。然而&#xff0c;受限于ins的规则&#xff0c;要想在这个平台上进行产品的宣传并非易事。 这就是为什么我们需要精心培养一个ins账号&#…

Linux(4)--CentOS8虚拟机下联网

文章目录 1. 背景2. VmWare配置3. 电脑网络配置4. 配置虚拟机网络5. 重启联网 1. 背景 安装CentOS后&#xff0c;尚不能联网&#xff0c;没有网络就不好上网&#xff0c;所以先解决上网问题。 2. VmWare配置 打开VmWare&#xff0c;点击编辑-虚拟网络编辑器&#xff0c;选择…

PyCharm使用ipynb文件交互式绘图

PyCharm配置 Jupyter Notebook 这个文章很全 PyCharm配置 Jupyter Notebook plotly方法 终端安装&#xff1a; pip install plotlyimport plotly.graph_objects as go import numpy as np# 示例数据 X np.linspace(-5, 5, 100) Y np.linspace(-5, 5, 100) X, Y np.meshg…

GNSS的数据样例

武汉大学的数据地址&#xff1a; ftp://igs.gnsswhu.cn/pub/whu/phasebias obit 文件夹下存放的是卫星相关的文件 姿态&#xff1a; 、精密轨道 ERP CLK bias 文件 观测量域的偏差

RWKV作者对OpenAI 发布 o1 系列模型的看法,很深刻

知乎&#xff1a;PENG Bo 链接&#xff1a;https://www.zhihu.com/question/666991594/answer/3624168868 大家都知道长期CoT可以提升性能&#xff0c;而且很快我们会看到其它家的例子&#xff0c;这是最后的low-hanging fruit&#xff0c;因为只需合成大量训练数据&#xff0…

DDR3AXI4接口读写仿真

前文已经介绍了DDR3和AXI4总线的相关知识&#xff0c;我们知道MIG ip核除了可以生成native接口还能生成AXI4接口&#xff0c;今天就练习一下将AXI4接口的DDR3打包成FIFO。首先我们生成一个AXI4接口的MIG ip核&#xff0c;其余步骤与Native接口的ip核相同&#xff0c;如果我们勾…

力扣: 翻转字符串里的单词

文章目录 需求分析代码结尾 需求 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。 注意&#xff1a;输入字符…

03_Python数据类型_字符串

Python的基础数据类型 数值类型&#xff1a;整数、浮点数、复数、布尔字符串容器类型&#xff1a;列表、元祖、字典、集合 字符串 在Python中&#xff0c;字符串&#xff08;String&#xff09;是一种非常重要的数据类型&#xff0c;用于表示文本数据。字符串是不可变的&…

算子级血缘在金融数据环境的实践应用

在企业的数据管理领域&#xff0c;算子级血缘极大优化了脚本内部字段口径的理解与追踪。面对几十、几百乃至几千行代码的复杂脚本&#xff0c;并且有着各种函数调用、数据转换等复杂的加工逻辑&#xff0c;如果通过传统的 ETL 工作模式&#xff0c;开发人员就不得不采用“盲人摸…

SpringBoot整合WebSocket实现消息推送或聊天功能示例

最近在做一个功能&#xff0c;就是需要实时给用户推送消息&#xff0c;所以就需要用到 websocket springboot 接入 websocket 非常简单&#xff0c;只需要下面几个配置即可 pom 文件 <!-- spring-boot-web启动器 --><dependency><groupId>org.springframewo…

深度学习驱动超材料设计领域发展

深度学习在超材料设计领域的应用是一个令人兴奋的研究方向。超材料&#xff08;Metamaterials&#xff09;是一类具有自然界中不存在的特殊性质的人工材料&#xff0c;它们通过精确设计微结构来获得独特的电磁、光学或声学特性。这些特性使得超材料在各个领域都有广泛的应用前景…

大模型产品经验漫谈

前文 昨天给领导汇报了最近做的一个 txt2sql 技术路线实现的智能助手的项目&#xff0c;总算是告一段落了&#xff0c;做了半年的时间&#xff0c;作为整个项目的技术负责人从头到尾主导项目&#xff0c;肯定是有不少收获和感悟的&#xff0c;趁现在还在脑袋里面热乎着&#x…

GPS/LBS/Wi-Fi定位,全安排!—合宙Air201资产定位模组LuatOS快速入门04

经历了hello world、点灯、远程控制三期基础教程&#xff0c;小伙伴们是不是收获满满&#xff0c;期待更高阶的应用呢&#xff1f; 本期&#xff0c;我们将学习合宙Air201的核心功能之一——定位功能&#xff01; Air201定位示例教程 合宙Air201资产定位模组——是一个集成超…

SAP B1 Web Client MS Teams App集成连载一:先决条件/Prerequisites

一、先决条件/Prerequisites 在设置 SAP Business One 应用之前&#xff0c;确保您已具备以下各项&#xff1a;Before you set up the SAP Business One app, make sure you have acquired the following: 1.Microsoft Teams 管理员账户/A Microsoft Teams admin account 您需…

电力电子器件:二极管,晶闸管,GTO,GTR,MOSFET,IGBT

目录 1. 二极管 2. 晶闸管&#xff08;SCR&#xff09; 3. 门极关断晶闸管&#xff08;GTO&#xff09; 4. 门极可关断晶体管&#xff08;GTR&#xff09; 5. 金属氧化物半导体场效应晶体管&#xff08;MOSFET&#xff09; 6. 绝缘栅双极型晶体管&#xff08;IGBT&#x…

HarmonyOS开发实战( Beta5.0)使用ArkUI的FrameNode扩展实现动态布局类框架详解

鸿蒙HarmonyOS开发往期必看&#xff1a; 最新版&#xff01;“非常详细的” 鸿蒙HarmonyOS Next应用开发学习路线&#xff01;&#xff08;从零基础入门到精通&#xff09; HarmonyOS NEXT应用开发性能实践总结 简介 在特定的节假日或活动节点&#xff0c;应用通常需要推送相…

【Unity新闻】Unity的产品命名变化

快速回顾一下Unity产品命名的调整。 在2023年 Unity就宣布版本命名的变化&#xff0c;将使用Unity 6作为最新版本的命名。 具体的规则&#xff0c;在论坛里进行了说明。 以后正式的LTS版本就是Unity 6&#xff0c;将在2024年末发布。 而不管是之前的Runtime费还是今天的费用…

短视频剪辑从简单到复杂,这四款很OK!

作为一个刚刚踏入视频剪辑世界的新手&#xff0c;我最近可是忙得不亦乐乎。我尝试了四款流行的视频剪辑软件&#xff0c;今天&#xff0c;就让我来和大家分享一下我的使用感受&#xff0c;看看哪款软件更适合我们这些初学者。这里先说一句&#xff0c;选择视频剪辑软件就像挑衣…

Python Module 模块详解:模块导入与项目管理的最佳实践

Python Module 模块详解&#xff1a;模块导入与项目管理的最佳实践 文章目录 Python Module 模块详解&#xff1a;模块导入与项目管理的最佳实践一 准备示例代码二 引用 module三 大型项目的模块管理四 完整文件示例五 源码地址 本文详细介绍了 Python 中模块&#xff08;Modul…