Unity 渲染原理

article/2025/8/12 13:20:56

1 渲染流程

渲染流程

  • 应用程序阶段(CPU):识别出潜在可视的网格实例,并把他们及其材质提交给 GPU 以供渲染。
  • 几何阶段(GPU):进行顶点变换等计算,并将三角形转换到齐次空间并进行裁剪。
  • 光栅化阶段(GPU):把三角形转换为片元,并对片元执行着色。片元经过多种测试(深度测试,Alpha 测试等)之后,最终与帧缓冲混合。

2 CPU 的工作流程

  1. 准备好需要被渲染的对象。也就是哪些物体需要被渲染,哪些物体需要被剔除(culled),剔除的常用方式包括视锥体剔除和遮挡剔除,并对需要渲染的对象进行排序。
  2. 设置每个对象的渲染状态。渲染状态包括所使用的着色器、光源、材质等。
  3. 发送 DrawCall。当给定一个 DrawCall 时,GPU 会根据渲染状态和输入的顶点数据进行计算。

3 GPU 的工作流程

GPU工作流程
顶点数据主要来自 CPU 端,然后将数据送到渲染管线中,输入的数据可以包括顶点坐标、顶点颜色、顶点法线、纹理坐标等数据。这些数据以图元的方式进行处理,常见的图元有点、线和三角面。

3.1 几何阶段

3.1.1 顶点着色器

是完全可以编程的,它的是流水线的第一个阶段,用于顶点坐标变换以及顶点颜色计算等,在这里改变顶点的位置可以模拟水面和布料等的运动。其中,顶点着色器将顶点坐标从模型空间转换到齐次裁剪空间,接着进行裁剪剔除不渲染的点后,最终得到归一化的设备坐标(NDC),Unity设备坐标范围同 OpenGL 一样在[-1,1]之间。
顶点着色器的输入来自于CPU,CPU输入的每个顶点都会执行一次顶点着色器,顶点着色器本身无法创建和销毁顶点,并且无法得到顶点与顶点之间的关系。正因为这样的独立关系,GPU可以利用自身的特性进行并行运算,所以顶点着色器的运算速度非常快。在此阶段也会进行透视投影、顶点光照、纹理计算、蒙皮。也可以通过修改顶点位置生成程序式动画(procedural animation),例如模拟风吹草动,碧波荡漾。

3.1.2 几何着色器

几何着色器因为在手机端不支持,所以Unity开发程序员也许并不熟悉。几何着色器也是完全可编程的。几何着色器处理以齐次裁剪空间表示的整个图元(三角形,线段,点)。它能够剔除和修改输入的图元,也能生成新的图元。典型应用包括阴影的体积拉伸(shadow volume extrusion)、渲染立方体贴图(cube map)的六个面、在网格的轮廓边拉伸毛发(fur fin)、从点数据生成粒子四边形、动态镶嵌、把线段以分形细分(fractal subdivision)模拟闪电效果、布料模拟等。

3.1.3 裁剪

由于我们的场景会很大,摄像机视野外的画面不需要进行渲染计算,所以裁剪的作用便是剔除视野外的图元。如下图一条线段A点在视野内,B点在视野外,将会剔除B点,取线段与视野交点处C点。注意裁剪这一步我们不可以编辑,这是硬件上的固定操作。
裁剪

3.1.4 屏幕映射

将图元的x和y坐标转换到屏幕坐标系,这与屏幕的分辨率有关,而图元的z坐标表示各物体与摄像机的远近,用于判断各图元的遮挡关系,这一阶段输出屏幕坐标系下的顶点坐标,Z深度信息,法线方向等。虽然屏幕映射是玩家不可配置和编程的,但是屏幕分辨率确实玩家可以设置的,较小的屏幕分辨率对光栅化阶段是有非常重要的优化效果的。

3.2 光栅化阶段

该阶段是将屏幕坐标系坐标转换为图像像素的过程。
光栅化

3.2.1 三角形设置

这个阶段会计算光栅化一个三角网格所需的信息。具体来说,上一个阶段输出的都是三角网格的顶点,即我们得到的是三角网格每条边的两个端点。但如果要得到整个三角网格对像素的覆盖情况,我们就必须计算每条边上的像素坐标。为了能够计算边界像素的坐标信息,我们就需要得到三角形边界的表示方式。这样一个计算三角网格表示数据的过程就叫做三角形设置。它的输出是为了给下一个阶段做准备。

3.2.2 三角形遍历

该阶段将会检查每个像素是否被三角网格覆盖,对应覆盖像素会生成一个片元,而片元的状态由三角网格三个顶点插值得到,注意片元不是像素。这些片元包含屏幕坐标、深度信息、法线、纹理坐标等。

3.2.3 片元着色器

此阶段的输入是一组片元属性,这些属性是在三角形遍历阶段通过对顶点属性插值所得。输出则是该片元的颜色信息。这一阶段可以完成很多重要的渲染技术,最重要的技术之一就是纹理采样。

3.2.4 逐片元操作

该阶段也称为合并阶段(merge stage)或混合阶段(blending stage)。此阶段不可编程,但是可以高度配置化。最常用的逐片元操作测试包括深度测试 ZTest、Alpha 测试、模板测试 Stencil test,当片元通过了所有测试以后,其颜色就会与帧缓冲原来的颜色进行混合(Blend),混合的方式是可配置的,如 Blend One One。为了避免看到正在栅格化的图元,GPU 使用双重缓冲,场景渲染是在幕后的后置缓冲区进行的,一旦场景渲染完成后会将后置缓冲区内容与前置缓冲区交换,保证图像的连续性。

3.2.4.1 裁切测试

裁切测试可以避免当视口比屏幕窗口小时造成的渲染浪费问题。

3.2.4.2 Alpha 测试

Alpha 测试可以根据片段颜色的 Alpha 值来裁剪片段。
由于 Alpha 测试本身消耗较大,性能较低,所以只有在必要的情况下才会使用 Alpha 测试。

注:片段着色器执行后再进行深度/模板测试,来确定到底哪些片段(Fragments)对屏幕显示有贡献,哪些片段需要被丢弃(Discard),只有哪些通过了深度/模板测试的片段才成为屏幕上显示的像素(Pixels),这也就是片段和像素本质的区别,也就是说片段是最终显示在屏幕上像素的候选者。
由于深度/模板测试是在片段着色器之后进行的,所以导致着色器计算资源的浪费,因为这些被遮挡的片段对我们最终的画面是没有任何贡献的,而我们还花费了大量的资源对它们进行了复杂的光照等一系列计算。
以上是 Alpha 测试效率较低的原因。

3.2.4.3 模板测试

我们可以把它理解为一个模子 mask,通过 mask 的值来控制那些片段的可见性,无法通过模板测试的片段将被丢弃。

3.2.4.4 深度测试

比较当前片段的深度值是否比深度缓冲中预设的值小(默认比较方式),如果是更新深度缓冲和颜色缓冲;否则丢弃片段不更新缓冲区的值。

3.2.4.5 Alpha 混合

当场景中既有不透明物体,又有半透明物体时,我们需要先渲染不透明物体,渲染顺序为从前往后;然后再渲染半透明物体,渲染顺序为从后往前。我们需要对不透明和半透明物体分开渲染是因为:我们可以透过半透明物体看到半透明物体背后的东西,所以对半透明物体进行渲染时需要后面图层的信息,才能够正确进行混合。


http://chatgpt.dhexx.cn/article/nMVgF13Z.shtml

相关文章

Unity标准化的场景渲染流程

笔者用的unity版本为2020.3.30f1c1,开一个HDRP模板场景,OK开始我们的操作。 第一步:删除场景中的所有东西只留下竹林玻璃房作为展示场景,将所有物体勾选Static,新增一个摄像机,如下图: 第二步&a…

Unity3D性能优化——渲染篇

大渣好,我又来了。 之前的文章中,我们了解了Profiler工具,以及在实际项目中unity的CPU优化分析及方法,本文我们主要了解在我们的项目中GPU的性能分析,以及对GPU性能进行优化的相关技术。 渲染优化 在了解优化渲染前&a…

Unity中的灯光和渲染

一:Unity中的灯光 ——Directional Light:模拟太阳光。它与位置无关,是平行光,可以调整旋转角度模拟昼夜 ——Spot Light:模拟车灯、手电筒的光、舞台灯光 ——Point Light:模拟灯泡 ——Area Light&#…

execv 函数的应用

execv函数族:系统来调用某程序模块 int execl(const char *path, const char *arg, ...); int execlp(const char *file, const char *arg, ...); int execle(const char *path, const char *arg, ..., char * const envp[]); int ex…

Linux 0.11-execve函数-35

Linux 0.11-execve函数-35 execve函数读取文件开头 1KB 的数据解析这 1KB 的数据为 exec 结构判断是脚本文件还是可执行文件准备参数空间设置 eip 和 esp,完成摇身一变累了吧,休息会 转载 execve函数 书接上回,上回书咱们说到,进…

Linux内核Hook系统调用execve

资源下载地址:linux内核hook系统调用execve函数-Linux文档类资源-CSDN下载 (已在内核为 4.19.0-amd64-desktop版本uos编译通过,并成功达到目的) 在Linux系统中,用户层程序无法直接控制系统内核,只能通过系…

执行新程序 execve()

新程序的执行 一:execve() 之所以叫新程序的执行,原因是这部分内容一般发生在fork()和vfork()之后,在子进程中通过系统调用execve()可以将新程序加载到子进程的内存空间。这个操作会丢弃原来的子进程execve()之后的部分,而子进程…

简单的execve流程

本文转载于网络 基于Linux0.11源码来叙述该功能,源码可以在oldlinux.org上自行获取 _sys_execve:lea EIP(%esp),%eax #取堆栈中存放系统调用的返回地址的地址pushl %eax #将该地址入栈call _do_execve #调用do_execve函数addl $4,%esp #丢弃该地址ret这边做了一个很…

Linux0.11系统调用之execve流程解析

Linux0.11系统调用之execve流程解析 前言execve功能介绍execve本质execve系统调用流程总结 前言 本文是基于Linux0.11源码来叙述该功能,源码可以在oldlinux.org上自行获取。 execve功能介绍 execve是用于运行用户程序(a.out)或shell脚本的…

5.execve()到底干了啥?

导语 很多童鞋有分析阅读Linux源代码的强烈愿望,可是Linux内核代码量庞大,大部分人不知道如何下手,以下是我分析Linux源代码的一些经验,仅供参考,有不实之处请大神指正! 1.要想阅读内核首先要进入内核&…

Linux系统编程(再论execve)

文章目录 前言一、execve的第三个参数二、进程空间三、命令行参数规范四、optstring规则的扩展定义总结 前言 本篇文章我们继续来研究一下execve这个系统调用,上篇文章已经讲解了前两个参数的意义了,那么这篇文章就来讲解一下第三个参数的具体含义。 一…

Linux0.11 execve函数(六)

系列文章目录 Linux 0.11启动过程分析(一) Linux 0.11 fork 函数(二) Linux0.11 缺页处理(三) Linux0.11 根文件系统挂载(四) Linux0.11 文件打开open函数(五&#xff09…

C语言 execve()函数使用方法

1.君の名は execve() – 叫做执行程序函数 就像Python中的os.system(cmd)这个函数,我们可以用这个函数来执行我们的shell脚本,单独的shell命令,或者是调用其他的程序,我们的execve()这个函数就和Python中的os.system函数类似&am…

SPSS-因子分析

因子分析 有可能用较少的综合指标分析存在于各变量中的各类信息,而各综合指标之间彼此是不相关的,代表各类信息的综合指标称为因子。定义:因子分析就是用少数几个因子来描述许多指标或因素之间的联系,以较少几个因子反映原资料的 …

spss进行主成分分析

什么是主成分分析 简而概之, 就是一组数据受太多因素影响, 选出几个能代表他们的因素,并进行线性组合得到一组比原维度小的因素组合, 作为新的因素集 用spss操作 随手拿出一组数据 1.数据统一标准化 因为我们得到的原始数据大小,类型不一, 一起分析会不准确, 所以将数据全部…

实用干货!因子分析超全步骤总结

因子分析是统计数据分析方法之一,因子分析包括探索性因子分析和验证性因子分析。本文主要讨论探索性因子分析。 一、研究背景 关于工作满意度有14个问题,调研得到215份问卷结果。希望通过因子分析,用少量因子反映14个题目的信息,…

NLP | 朴素贝叶斯法的学习与分类

朴素贝叶斯法的学习与分类 《统计学习方法》李航第四章 1、概述 书上对朴素贝叶斯的描述如下: 朴素贝叶斯法时基于贝叶斯定理与特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入/输出的联合概率分布;然…

标定相机参数-张正友方法

一、实验原理 1.计算外参 设三维世界坐标的点为M=[X,Y,Z,1]T,二维相机平面像素坐标为m=[u,v,1]T,所以标定用的棋盘格平面到图像平面的单应性关系为: sm=A[R,t]M 其中 不妨设棋盘格位于Z = 0,定义旋转矩阵R的第i列为 ri, 则有: 令H=[h1 h2 h3]=λA[r1 r2 t] 于是空间到图…

《统计学习方法》——朴素贝叶斯法

引言 朴素贝叶斯法(Naive Bayes)是基于贝叶斯定理与特征条件独立假设的分类方法。朴素贝叶斯法实现简单,学习与预测的效率都很高,是一种常用的方法。 这一章需要大量的概率论知识,忘记了的同学建议先参阅人工智能数学基础之概率论。 朴素贝…

数据挖掘十大算法之 naïve Bayes

朴素贝叶斯法是基于贝叶斯定理和特征条件独立假设的分类方法。朴素贝叶斯法实现简单,学习与预测的效率都很高,被广泛应用于文本分类、垃圾邮件过滤、自然语言处理等场景。下面我们来介绍贝叶斯定理,在介绍贝叶斯定理之前,先介绍下…