3D图形渲染技术

2023-11-18

如何用2D平面展现3D图形

2D图形

在一个平面中有了两个点,知道了他们的XY坐标,就可以把它们链接起来画成一条线

通过控制A和B点的XY坐标可以控制一条线

在3D图像中,点的坐标多了一个Z轴的坐标系

但是在2D的屏幕坐标上不可能有XYZ立体的坐标轴

所以需要图形算法负责把3D坐标“拍平”显示到2D屏幕上,这个叫做3D投影

将3D的点转换为2D的点之后,再用之前链接2D点的方法去连接这些点,这个叫做线框渲染

投射的灵感:两种投影方法

推荐文章:

zhuanlan.zhihu.com/p/473031788

总的来说就是把一个3D图形移动到2D的坐标系上,中心对应的坐标系的原点,然后就可以得到这个3D的2D坐标了

如果用光去找一个3D的物体的时候,用一个平面去展示投影,当转动3D物体的时候,投影会看起来像3D物体,尽管投影面是平面。

电脑也是这样去做的将3D转成2D。首先屏幕就是一个2D的投影平面,根据投射的算法就可以将3D转成2D的坐标

正交投影

立方体的各个边在投影中互相平行,可以说利用数学将3D转换成了2D的坐标系

正交投影是一种平行投影,类似用一束平行光把物体的影像垂直地投射到地面上。

透视投射

透视投影可以产生近大远小的效果,就和人类观察世界的方式类似

在真实的3D世界中,平行线段会在远处收敛与一点

为什么复杂图形的绘制要使用三角形

在3D图形学中,我们叫三角形“多边形”

一堆多边形的集合叫做“网格”

网格越密,表面越光滑,细节越多

首先来讲为什么用三角形,而不是正方形

在一个空间中,三个点定义一个平面

如果给定3个3D点,就能画出一个平面。但是四个点就不一定了、

如果是两个点那么不够定义平面,只能够定义线段;如果是四个点那么可能定义的就不仅仅只有一个平面了,所以3是个完美的数字

填充图形算法

扫面线渲染

线框渲染虽然很酷,但是3D图像需要填充

步骤:
  1. 铺上一层像素网络

  1. 扫描线算法,先会去读取多边形的三个点,找出最大和最小的Y值,然后只在这两个点之间进行工作

  1. 然后算法从上往下,一次处理一行,计算每一行和多边形相交的两个点。扫描线算法会填满两个相交点之间的像素 因为是三角形,如果相交一条边,必然相交另外一条边

抗锯齿

这样的三角形比较丑,因为边缘满是锯齿

一种减轻锯齿的方法叫做抗锯齿

抗锯齿:与其每一个像素都涂成一样的像素,可以判断多边形切过像素的程度来调整颜色。

如果像素在多边形内部直接填充颜色;如果多边形划过像素,那么颜色就会浅一些

遮挡的渲染算法

在3D场景中有很多的多边形,但是只有一部分能看见,因为其他的被遮挡住了。

排序算法(画家算法)

最简单的处理方法

从远到近排列,从远到近渲染,这叫画家算法,因为画家也是先画背景再画更近的
东西

步骤
  1. 第一步,就是从远到近进行排序(A黄色,B蓝色,C绿色 三个三角形的距离)

  1. 有序之后,利用扫描线算法进行填充多个多边形,一次填一个。(顺序是从远到近进行填色)

深度缓冲

这个算法和画家算法的思路一样,但是方法不一样

而且深度缓冲算法不需要进行排序,所以它的速度会更快

Z-buffering算法会记录场景中每个像素和摄像机的距离,在内存里存一个数字矩阵

步骤
  1. 首先,每个像素的距离被初始化为“无限大”,然后Z-buffering从列表里第一个多边形开始处理,也就是A

他和扫描线算法逻辑相同,但是他不是给像素进行填充颜色,而是吧多边形的距离和Z-buffing里面的距离进行对比,他总是记录更低的值

  1. Z缓冲区完成后,会和“扫描线”算法的改进高级版配合使用,不仅可以勘测到线的交叉点还可以知道某像素是否在最终场景中可见。如果不可见,扫描线算法会跳过那个部分

但是会有一个问题,如果距离相同的话,那么哪个画到上面?

多边形在内存中移来移去,访问顺序会不断变化,所以哪一个花在上面,往往是不可预测的

3D游戏的一个优化:背面剔除

三角形有两面,正面和背面。

游戏角色的头部或地面,只能看到朝外的一面,所以为了节省处理时间,会忽略多边形的背面,减少了一般多边形面数。

但是也有个bug就是从模型外面看的话其实头部和地面会消失

3D场景明暗处理

在3D场景中,物体表面应该有明暗变化。

这次还是拿茶壶来做实验,和之前的例子不一样。这次要考虑的是多边形面对的方向,他们不平行与屏幕,而是面对不同方向。面对的方向叫做“表面法线“

用一个垂直与表面的小箭头来显示这个方向

加一个光源,因为不同多边形面对光源的角度不同,因此会导致箭头的方向和光源照亮的方向重叠越多,代表这个多边形越亮

纹理Textures

纹理在图形学中是指外观,而不是手感。

纹理也有多种算法

纹理映射

最简单的用法

之前我们通过扫描线算法进行填充颜色时,可以看看内存中的纹理图像,决定填充该像素区域时用什么颜色

做到这点,需要将多边形坐标和纹理坐标进行对应

  1. 多边形坐标和纹理坐标进行对应
  2. 当决定填充当前像素选择什么颜色时,纹理算法进行查询纹理,从相应的区域取平均颜色,并填充到多边形

GPU:图形处理器

我们可以为这种特定运算进行做专门的硬件来加快速度

其次,我们可以吧3D场景分解成多个小部分,然后进行并行渲染,而不是按顺序渲染。

cpu不是为此设计的,因此图形运算不快,所以计算机工程师为图形做了专门的处理器,叫做GPU"图形处理单元"

GPU在显卡上,周围有专用的RAM,所有网格和纹理都在里面,让GPU的多个核心可以高速访问

参考链接

www.bilibili.com/video/av213…

原文链接:3D图形渲染技术 - 掘金 (juejin.cn)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

3D图形渲染技术 的相关文章

  • 如何使用opengl函数在c中制作用于绘制3D点的3D窗口?

    我可以制作 2D 窗口并绘制点 线等 我想制作 3D 窗口 以便可以通过绘制 3D 点 线来绘制 3D 对象 例如 glVertex3d x y z 如 2D glVertex2d x y 但我无法制作 3D 窗口 我只想制作一个 3D 窗
  • R:如何:使用 gplot 和 geom_密度绘制 3d 密度图

    I m trying to combine multiple density plots with overlay ggplot and geom density do the job but the densities are stack
  • 在python opengl中使用图像中的2d点获取空间中的3d点

    我正在尝试模拟房间中的深度相机 我的相机能够在世界中移动和旋转 并且房间被模拟为围绕 0 0 0 的 3d 立方体 单击按钮时 我想对图像中的 N 个随机点进行采样 并获取这些点与相机的距离 现实世界 中的距离 到目前为止 我已经成功创建了
  • 生成球体的顶点

    在 DirectX 移动照明示例中 圆柱体是按以下方式生成的 for DWORD i 0 i lt 50 i FLOAT theta 2 D3DMX PI i 50 1 pVertices 2 i 0 position D3DMXVECTO
  • 使用 Scenform 将 SceneView 加载到片段中后出现黑屏

    我正在开发一个项目 该项目将在一个片段中包含 3D 模型查看器 为了做到这一点 我决定使用 sceneform 在尝试在我的选项卡片段中显示 SceneView 后 我遇到了 SceneView 的问题 一切都是根据示例和 scenefor
  • Python在3D散点图中用线连接相邻点

    我有两组 x y z 坐标 我用 Matplotlib 将它们绘制在 3D 散点图中 现在 我想将每个生成的四边形与平面连接起来 我已经了解了如何在 3D 空间中绘制 2D 多边形在 python matplotlib 中绘制 3D 多边形
  • 在运行时更改 AR core 中对象的纹理

    我正在创建一个应用程序 我需要在其中更改 3d 对象的纹理 图案 我正在使用 AR Core SDK 和 android 我已经使用了下面的代码 但它不起作用 Texture builder setSource this R drawabl
  • 如何使用 OpenCV Viz 和 ARUCO 转换增强现实应用的 3D 模型

    我正在开发一个简单的基于标记的增强现实应用程序OpenCV 可视化 and ARUCO 我只想在标记上可视化 3D 对象 PLY 格式 我可以使用 ARUCO 毫无问题地运行标记检测和姿态估计 返回旋转和平移向量 我可以在 Viz 窗口中可
  • 从绘图 3d 图中抓取相机位置

    我正在绘制 3D 图形并想要调整相机位置 对我来说最好的方法是使用查看器 根据需要缩放和旋转场景 然后以 JSON 形式获取相机位置并将其放入我的脚本中 该脚本生成图片以默认实现相同的位置 根据这条推文 https twitter com
  • 受约束景观的程序生成

    我想实现地形的程序生成 经过彻底的研究后 我得出的结论是 应该使用梯度 相干 噪声生成算法之一来实现 例如 Perlin 噪声算法 然而 我不希望生成是完全随机的 我想应用一些限制 例如哪里应该是山脉 或者哪里应该是低地等 问题 例如 我有
  • 使用相机将 3D 透视投影到 2D 屏幕上的基本渲染(无需 opengl)

    假设我有一个如下的数据结构 Camera double x y z ideally the camera angle is positioned to aim at the 0 0 0 point double angleX angleY
  • 如何在 OpenGL 中创建廉价的阴影? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有两个模型 A 和 B 以及一个灯 L 我希望模型 A 在模型 B 上投射阴影 我暂时不想考虑阴影体
  • 3D 哪个更快? Perlin 噪声还是 Simplex 噪声?

    好吧 网上有很多 Perlin 噪声和 Simplex 噪声之间的比较 但我真的找不到一个对三个维度进行简单处理时间比较的地方 这是我最感兴趣的 我读过那个流行的PDF http webstaff itn liu se stegu simp
  • Python 中的标量场可视化

    我需要在 Python 中可视化几个重叠的标量场 我发现mayavi图书馆做这种情节 问题是我不明白如何为标量字段自定义颜色图 我的想法是为每个字段设置一种颜色的阴影 我尝试采用一个例子 http docs enthought com ma
  • 基于 Q3DScatter 的自定义图表,QCustom3DItem 运行缓慢

    我想制作一个带条形的 3D 图表 条形颜色取决于其大小 两个都Qt 条形图和散点图类型 https doc qt io qt 5 qtdatavisualization overview html接近我正在寻找的东西 我最终创建了一个基于的
  • 如何在SceneKit中实现逼真的景深效果?

    我正在尝试渲染具有真实景深效果的帧 我已经尝试过景深属性camera节点 但它不会产生可用的结果 是否可以切换到景深效果的最大渲染质量 性能不是一个因素 我只需要渲染一帧 用户可以等待它 SceneKit 中逼真的景深效果 在SceneKi
  • 在 Three.js 中将贝塞尔曲线转换为平面道路

    我试图根据之前计算得到的一些贝塞尔曲线在 Three js 中绘制一条弯曲的道路 问题是我找不到转换曲线序列的方法 一条从上一条曲线的末尾开始 到一个曲面 我有一个 3D 场景 其中有一些汽车 一条用飞机创建的道路 并且绘制了即将到来的道路
  • 使用 ThreeJS 获取球体纹理上的点击位置

    目前 我有一个带有纹理的球体 它绕 y 轴旋转 我还有在 3D 空间中单击的位置 以及球体上的旋转位置 我认为 目标 获取纹理上的位置 例如 我想获取我点击的图像的哪个方块 参见示例球体和下图 在实践中 我不会使用此图像 但我觉得这将是一个
  • 颜色重新映射 - 使用 3D 网格匹配目标调色板?

    假设我有颜色 FOO 它以 RGB 格式存储 我需要重新着色 FOO 以便它与颜色列表中最接近的颜色匹配 即时执行此操作 我是否无法将每种颜色的 RGB 值视为 3D 网格上的点 r x g y b z 并计算点 FOO 与每个颜色点之间的
  • OpenGL z轴指向哪里?

    我正在尝试了解 OpenGL 坐标系 我到处都看到它被描述为右撇子 但这与我的经验不符 我尝试绘制一些形状和 3 d 对象 我发现 z 轴显然指向 屏幕 而 x 指向右侧 y 指向上方 这是左手坐标系的描述 我缺少什么 编辑 例如 http

随机推荐

  • STM32-custom usb

    如何建立一个自定义的HID工程呢 下面就来讲讲 首先先介绍下工程的架构 工程的总体架构下图所示 按照下图架构建工程 分析下工程布局 首先是APP 这个组里存放着主文件mian c 管理所有中断服务程序stm3210x it c 及其管理外设
  • PageObjects支持库-Poium使用方法

    PO模式 学过自动化的都知道PageObjects模式 将页面对象封装为类 页面元素和操作封装为类的属性和方法 在测试方法中调用页面对象进行测试 关于PO模式可见 http t csdn cn 0DBlP 在PO模式下 我们一般定义个一个基
  • 想写一本书,而这是序言

    口袋书 序言 现在的风口是什么 很多人会答人工智能 Artificial Intelligence AI 人工智能是一项伟大的发明 我们不得不承认 它已经为社会带来了翻天覆地的变化 并 将在未来卷起更大的风暴 不了解人工智能 就难以在这个
  • 前端js将扁平化数据转化为=菜单树

    let menuList id 1 pid 1 name 江西 id 2 pid 1 name 南昌 id 3 pid 1 name 九江 id 4 pid 1 name 广东 id 5 pid 4 n
  • 【考研】数据结构——线索二叉树

    CSDN话题挑战赛第2期 参赛话题 学习笔记 前言 本文内容源于对 数据结构 C语言版 第2版 王道讲解学习所得心得 笔记整理和总结 本文针对线索二叉树 在最后的练习中 以举例子说明该排序方法 配以图文 讲解详细 含408真题 可搭配以下链
  • 学校与工作(献于在校大学生及入职不久的工作者)

    学校与工作 每个人都把自己眼界的局限当成世界的局限 学校是非常不同于职业工作的 有些人在其早期职业生涯中栽跟头 就是因为未能从已经生活了近20年的学校环境过渡到软件行业的美丽新世界 学生的活动具有高度约束性 工作量都是规定好了的 虽然当你是
  • IEEE-754标准浮点数,十六进制与十进制转换方法(附C代码)

    十进制数与IEEE 754 32 位转换实例讲解 https blog csdn net qq 41629142 article details 83692106 https blog csdn net a627088424 article
  • springboot集成kafka实战项目,kafka生产者、消费者、创建topic,指定消费分区

    springboot集成kafka实战项目 kafka生产者 消费者 创建topic 指定消费分区 前言 本项目代码可直接集成到你现有的springboot项目中 功能包括 1 kafka生产者配置 2 kafka消费者配置 指定分区消费
  • eigen与opencv矩阵转换,eigen与matlab函数比照

    近期 项目需要 学习使用eigen矩阵库 链接时eigen的主页 发现相关中文资料比较少 今天写下使用心得 eigen配置 windows vs系列 eigen的配置很简单 下载解压后 在VC 目录下的包含目录中 将eigen的路径包含进去
  • java多线程使用教程

    文章目录 如何使用多线程 继承Thread类 实现Runnable接口 线程的生命周期 线程同步 线程间通信 shutdown 方法的重要性 如何使用多线程 在Java中 创建多线程的方式有两种 一种是继承Thread类 另一种是实现Run
  • docker中mysql初始化及启动失败解决办法

    在docker中有一个mysql服务 其数据文件是挂在在主机外面的文件 在docker中的root有访问该数据文件的权限 但是docker中mysql访问数据文件的时候提示权限不足 于是只有以root用户来启动mysql了 数据初始化 my
  • 从零开始Vue3+Element Plus后台管理系统(十)——自定义水印指令与全局注册

    在实际项目开发中 自定义指令用得还是比较多的 比如 复制粘贴 输入框防抖 输入框禁止特殊字符 权限校验 背景水印 拖拽等等 指令确实是个优雅的存在 Vue3中定义一个普通的自定义指令的详细说明参见官网 https cn vuejs org
  • Ubuntu 安装 anaconda

    文章目录 写在前面 一 官网下载安装包 二 安装 参考链接 写在前面 Ubuntu安装 anaconda 比较简单 去官网下载 anaconda 安装包 然后安装即可 自己的安装环境 Ubuntu18 04 anaconda3 博客撰写日期
  • MySQL-图形化界面工具 (下)

    作者 小刘在C站 个人主页 小刘主页 每天分享云计算网络运维课堂笔记 努力不一定有收获 但一定会有收获加油 一起努力 共赴美好人生 树高千尺 落叶归根人生不易 人间真情 目录 MySQL 修改数据 删除数据 DQL 基本语法 MySQL M
  • MySQL导出和导入SQL脚本

    首先 使用mysqldump命令的前提是 在Cmd中进入mysql安装目录下的bin目录下 才可以使用该命令 我的mysql安装在E 盘 所以 首先进入bin目录下 E Program Files MySQL MySQL Server 5
  • SLAM常用最小二乘最优化方法学习、分析和总结

    SLAM中二维视觉的定位问题被最终归为一个最小二乘问题 那么紧随其后的就是对最小二乘的最优化求解 对其求解析解显然是不太合适的 所以就需要一些数值的最优化方法对最小二乘问题进行求解 在SLAM中 常用的算法有 梯度下降法 牛顿法 以及牛顿法
  • 数字后端——布局

    由于I O单元和模块的布放已经在布图规划时完成 因此布局的剩余任务主要是对标准单元的布局 布局方案在布图规划时就已经做了决定 要么选择展平式布局 要么就是层次化布局 一 布局目标 布局的目标也即布局内容实施之后所要达到的预期值 可以归纳为以
  • 【网络基础】路由表,分组转发算法

    前提 IP数据报的首部中没有地方可以用来指明 下一跳路由器的 IP 地址 那么 当路由器接受到一个待转发的报文时 是如何确定将该报文的传向呢 在此 我们引入 路由表 概念 路由表如图所示 当一个IP报文传到路由器R2时 则会通过查询R2所维
  • js基础--获取浏览器当前页面的滚动条高度的兼容写法

    前言 在开发中 兼容性问题是最常见的 今天就来介绍一下关于获取滚动条高度的兼容性写法 宽度同理 我在这里就不一一解释了 各浏览器的写法 IE6 7 8 document documentElement scrollTop IE9以上 win
  • 3D图形渲染技术

    如何用2D平面展现3D图形 2D图形 在一个平面中有了两个点 知道了他们的XY坐标 就可以把它们链接起来画成一条线 通过控制A和B点的XY坐标可以控制一条线 在3D图像中 点的坐标多了一个Z轴的坐标系 但是在2D的屏幕坐标上不可能有XYZ立