渲染管线

news2024/11/24 14:33:24

Unity 是一款跨平台的 3D 引擎,有着强大的渲染功能,并主要用于游戏开发。

谈到 Unity 的渲染功能,我们不得不提及到着色器(Shader)——3D 游戏引擎中最重要的一个因素­,它在游戏效果以及画面显示方面起到了决定性的作用。Shader 编程也属于计算机图形学中一个重要的部分。

接下来让我们从可编程渲染管线来了解 Shader 编程。

渲染管线模型

3D 游戏以及 3D 模型通过渲染管线来渲染到 2D 的屏幕上。渲染管线的流程是在 GPU 中进行的,它主要占有计算机的显存部分。渲染管线在这个过程中进行了顶点处理、面处理、光栅化、像素处理。

1)顶点处理

大多数接触过 3D 图形的人都知道3D 模型是通过众多点构成的面而展现出来的。

顶点处理,是通过一系列坐标系的变换,让各个顶点通过一定的规律在摄像机前位移,最终在屏幕上对应这些顶点的过程。

首先,物体的各个顶点从自身坐标系,通过世界变换矩阵处理转换到世界坐标系,再通过取景变换矩阵变换到观察者坐标系,最后通过投影变换,将顶点转移到屏幕坐标系。

有一点大家会经常忘记,在观察者坐标系转换到投影坐标系的过程中,GPU(图形处理单元)还对材质属性和光照属性进行了处理。

2)面处理

三点成一面。面处理有三个部分:面的组装、面的截取、面的剔除。

面的组装:模型中的三个点会组成一个三角形的面(非任意点,因为每个点都有自己的编号)。这些面,面面相接,组成了我们能看到的模型。

面的截取:由于摄像机和人眼一样,可视的区域是一个锥形,模型在摄像机可视范围内可能并不是全覆盖,也就是在摄像机外,这些在摄像机之内的部分就会被截取。

面的剔除:为了模拟肉眼,摄像机前的物体会出现近大远小的现象,那么物体和物体之间会有遮挡,被遮挡的面会被剔除不处理;每个面都有法向量,所以只有在面的法向量和摄像机散射向量夹角大于90度的才会被摄像机捕捉到。

3)光栅化

光栅化,又称之合并阶段。它的主要功能是将面转换成一帧中的像素集合。

这一阶段是不可以编程的,它负责执行多个片段测试,包括:深度测试、alpha 测试和模板测试,程序员可以通过高度配置来实现想要的效果。如果通过了所有的测试,这部分颜色就会与帧缓冲存储的颜色通过 alpha 混合函数进行合并。

4)像素处理

这个阶段将像素区域着色,然后赋予贴图。

(左上为3D网格模型,左下为赋予贴图后的3D模型,右图为贴图)

Shader 详解

介绍完GPU 渲染管线之后,我们再来简单了解一下可编程着色器 Shader —— 图形渲染里最有趣的部分。Shader 能让渲染的图形展示出水面效果、火焰的热流效果、角色的虚化效果等视觉效果。

着色器可分为顶点着色器(VertexShader)、几何着色器(Geometry Shader)和像素着色器(Pixel Shader)。它们从输入的数据中取得一个元素,通过程序计算,变换为输出数据的一个或多个元素

顶点着色器输入源为顶点,顶点包含其在自身坐标系或世界坐标系的位置和矢量信息,而输出源为已通过变换和照明处理的顶点,包含其投影坐标系的信息。

几何着色器的输入源为一个有 n 个顶点的几何图元以及最多 n 个作为控制点的额外顶点,输出源则变成 0 或多个图元。根据效果需要,这些图元的可能和输入的时候不同。

像素着色器输入为顶点间的片段,这些片段所包含的信息来自于对三角形顶点信息的插值,输出成将要写到帧缓冲里的颜色

渲染管线概述

Unity渲染管线流程:

多相机渲染

CPU渲染管线

层级剔除

遮挡剔除

发送数据(将所有数据打包,发送给GPU)

GPU渲染管线

图元装配及光栅化

执行裁剪

裁剪空间转换到NDC

计算NDC

背面剔除

图元装配

光栅化

片元着色器Shader

纹理寻址模式

纹理压缩格式

光照计算

光照模型

经验光照模型

环境光

输出合并

Alpha测试

模板测试

深度测试

混合Blending

后处理

Unity渲染管线流程:

CPU打包数据,材质,法线

a. 剔除物体(摄像机外的物体将被剔除)

b. 渲染排序(安装给定顺序和深度对物体进行排序)

c. 发送数据(将所有数据打包,发送给GPU)

d. 调用Shader:SetPassCall,DrawCall

GPU渲染管线

a. 顶点着色器,将逐顶点执行。将模型空间转换到裁剪空间。可以处理顶点偏移和顶点光照。

b. 顶点着色器后:光栅化阶段

裁剪片元: 将裁剪空间外的模型裁剪掉

转换为NDC(标准化设备坐标,使用透视除法)

剔除(背面剔除,正面剔除等),将特定方向的顶点进行剔除

视口转换(转换到屏幕坐标)

图元装配

光栅化(会产生锯齿)

c. 片元着色器,逐像素执行。

d. 片元着色器之后:输出合并阶段

Alpha测试

模板测试

深度测试

颜色混合

e. 帧缓冲区

f. 后处理阶段(CPU调用GPU渲染管线)

g. GPU渲染到屏幕

多相机渲染

每个摄像机都会渲染一遍该相机内的物体的顶点。

每个相机都会跑一次完整的渲染管线流程

默认会清除除天空盒之外的其他物体,通过ClearFlags和Depth设置清楚条件和渲染顺序。

如果不清楚其他相机的物体将会出现渲染叠加。

通过一个相机清除,一个相机保留好像可以实现3D视频的左右眼效果。(虽然需要两倍的渲染时间)

CPU渲染管线

剔除物体(摄像机外的物体将被剔除)

视锥体剔除

即:使用摄像机可视范围的视锥体构成的区域与物体进行碰撞检测。

优化:但是复杂的物体碰撞检测很耗性能,因此会使用一个简单的碰撞体Box Colider进行包裹,称为AABB包围盒。

层级剔除

通过摄像机进行特定物体的剔除。剔除特定层级的物体(未被勾选即被剔除物体)。

感觉这个可以实现物体的快速隐藏。(通过将物体设置到隐藏层来减少渲染,而又无需摧毁)。

遮挡剔除

通过判断物体位置和遮挡关系对被不透明物体完全遮挡的物体进行剔除。

渲染排序(安装给定顺序和深度对物体进行排序)

通过Render Queue数值进行排序,相等时使用深度进行排序。

不透明物体默认2000

透明物体默认3000

大于2500理解为半透明队列,将按深度进行从后向前排序

小于2500理解为不透明物体,按深度从前向后排序

不透明物体从前向后排序有助于优化,被遮挡物体将不会被渲染。

半透明物体从后向前渲染才能保证渲染颜色正确,半透明颜色混合顺序不同,结果颜色不同。

半透明物体内部不能保证完全从后向前进行渲染。导致的显示效果:1.向面片一样没有厚度,

发送数据(将所有数据打包,发送给GPU)

模型数据

格式:obj格式,fbx格式(推荐)

obj数据:

顶点坐标(三维)

法线信息(法线向量)

UV坐标(二维数据,最后一位无用)

索引列表,一行数据表示一个三角面(通过索引找到每个顶点的顶点、法线、UV)。通过索引记录有助于压缩数据,

调用Shader:SetPassCall,DrawCall

GPU渲染管线

顶点着色器Shader

Unity中的顶点Shader

最重要的任务:将顶点坐标从模型空间变换到裁剪空间:

通过MVP矩阵对顶点的坐标进行变换。

模型空间变化到世界空间:

参考系由物体自身变化到世界统一坐标

模型空间时建模软件的坐标空间,就是模型生成的坐标。

世界空间变化到相机空间

参考系由世界坐标变化到以相机为中心

相机空间变化到裁剪空间

将相机的视锥体进行压扁标准化成2x2x1的(CVV矩阵)

图元装配及光栅化

执行裁剪

在裁剪坐标空间中裁剪多余的像素和图像。

超过CVV之外的形状将会被裁剪。

空间范围:[w, w, 0] ~ [-w, w, w]

NDC - 标准化设备坐标

为转换到屏幕坐标做准备

空间范围:[-1, -1, 1]~[1, 1, 0]

空间中的z值为深度值,将会在下面几个操作中保留,然后再深度剔除中排上用场。

裁剪空间转换到NDC

P.xyz / P.w = NDC

同时要注意不同的设备NDC不同

DX平台:左上角[0, 0], 右下角[1, 1]

OpenGL:左下角[0, 0],右上角[1, 1]

// 适应不同平台下的ndc坐标

o.screen_pos.y = o.screen_pos.y * _ProjectionParams.x;

计算NDC

我们能直接获得的最远只有裁剪空间下的坐标,想要获取NDC坐标需要自己计算。但是很简单。

裁剪空间下坐标空间为:[-w,-w,w] -> [w, w, 0]

NDC坐标为:[-1, -1,1] -> [1, 1, 0]

裁剪空间坐标除以w可以得到=>[-1, -1, 0] -> [1, 1, 0]

方法一:

// 顶点着色器

o.screen_pos = o.vertex;

// 适应不同平台下的ndc坐标

o.screen_pos.y = o.screen_pos.y * _ProjectionParams.x;

// 片段着色器

// 计算屏幕空间NDC坐标

// 透视除法 xyz范围 [-w,-w,w],[w,w,0] => [-1, -1,1]=>[1,1,0]

half2 screen_ndc = i.screen_pos.xy / (i.screen_pos.w + 0.000001);

half2 screen_uv = (screen_ndc + 1.) * .5; // [x, y]范围: [-1, 1] => [0, 1]

方法二:

// 顶点着色器

o.screen_pos = ComputeScreenPos(o.vertex);

// 片段着色器

// 计算屏幕空间NDC坐标

// [x, y]范围: [-1, 1] => [0, 1]

half2 screen_uv = i.screen_pos.xy / (i.screen_pos.w + 0.000001);

背面剔除

将背对着摄像机的物体进行剔除。

通过三角面的索引列表进行排列,如果排列顺序为顺时针则为正面,为逆时针则为背面。

屏幕坐标空间- 视口转换

将xy坐标转换到屏幕空间的宽高。

将NDC空间下转换到屏幕空间下的坐标

图元装配

在平面中将顶点连线,形成一个一个封闭的三角形。

光栅化

在平面中对每一个图元中每一个片元生成像素。

深度值Z

法线

顶点色

切线

位置

所有自定义数据

片元着色器Shader

纹理技术

纹理采样

在纹理坐标UV中进行采样[0, 0] ~ [1, 1]。通过UV映射到纹理的像素上,取出那个点的像素。

纹理过滤机制

小图像映射到大块区域:相当于图片放大显示。

四舍五入 - 会产生比较尖锐的边缘

双线性差值

大图像映射到小块区域引起的失真:

Mipmap,通过给定一组大小不同的图像进行映射。显示大区域时用大图像,小区域小图像。

Mipamp只会增加1/3的存储占用。每个图像大小依次递减1/2。

纹理寻址模式

当索引超过UV时应该怎么取值。

Repeat重复模式 - 取小数(将形成循环取UV的效果)

Clamp截取 - 超过将会取最大、最小值。

纹理压缩格式

RGBA 32bit

ASTC 4x4 block, ASTC 6x6 - 纹理细节保留较好,压缩明显

ETC2 8bits

PVRTC 4bits

光照计算

光照组成:

直接光照

间接光照

光照模型

BRDF基于物理的渲染模型,过于复杂。

经验光照模型

光照模型基本框架 = 直接光漫反射 + 直接光镜面反射 + 间接光漫反射 + 间接光镜面反射 + …(次表面散射,PDR等)

Lambert漫反射光照模型

Phong光照模型

通过入射光方向和法向量计算反射光方向。知道了反射光就可以对比视线和反射光的夹角来得出其看到的光线多少。

Blinn光照模型

通过入射光方向和法向量夹角,计算出其半角向量。以半角方向对反射光方向进行近似(半角计算更简单)。

Ground光照模型

Flat光照模型

环境光

可以等同于间接光进行模拟。

间接光照实现:

Lightmap

Reflection Probe

Light Probe

输出合并

最重要任务:处理遮挡关系,处理半透明混合。

帧缓冲区FrameBuffer:

颜色缓冲区ColorBuffer

深度缓冲区DepthBuffer,Z-buffer

模板缓冲区StencilBuffer

Alpha测试

完全透明的,或者不满足给定透明度的片元将被丢弃。

模板测试

选定一个区域进行对比,不在区域中会被丢弃。

深度测试

使用深度进行测试,不通过将被丢弃。

通过测试的片元的深度将被存在Z-buffer中。(也可控制不写入)。

在Shader中可以通过ZWrite和ZTest进行控制。

ZWrite:是否写入Z-buffer

ZTest:深度测试规则

提前深度测试技术:

Early-Z,发生在顶点Shader之后,图元装配之前。

是一种提前优化技术,通过提前测试避免不必要的图元装配和片元计算。

混合Blending

对半透明像素进行颜色混合。

从后到前

一般情况下会关闭ZWrite

写在Shader中如:

Blend SrcAlpha OneMinusSrcAlpha

Blend SrcAlpha One

后处理

后处理可以在着色器工作完成后由CPU调用GPU对整体屏幕画面进行调整。

渲染管线可以看成3大步骤组成:

CPU处理要渲染的数据,将数据发送给GPU

GPU根据CPU发来的数据,将画面渲染到帧缓冲区

一个画面在帧缓冲区渲染完了,进行后处理后输出

一、CPU阶段

剔除

将不在视锥范围内的物体剔除掉

渲染顺序

将根据视锥范围内的物体位置决定渲染顺序

不透明队列(RenderQueue<2500),按照从前到后的顺序排序

透明队列(RenderQueue>2500),按照从后到前的顺序排序

先透明队列后不透明队列

打包发送数据

将要渲染的数据发送给GPU

一个模型的数据,包含以下内容:

顶点坐标(Position)

法线向量(Normal)

贴图采样位置(UV)

索引列表

每一行表示一个面的数据,而一个面是由三个点构成

每个点的数据,都包含上述abc三个数据

因此每一行的数据可以看成:

点1.Position/点1.UV/点1.Normal

点2.Position/点2.UV/点2.Normal

点3.Position/点3.UV/点3.Normal

调用SetPass Call与Draw call

SetPass Call:设置好各种渲染状态、背面剔除、要使用的Shader与混合模式

Draw Call:通知GPU去渲染模型

二、GPU阶段

GPU阶段可以视为:

点:将拿到的顶点坐标,转化为屏幕屏幕坐标

线:将各个顶点连接起来,形成一个个三角面(即图元)

面:给三角面上色

最后输出合并。

顶点Shader:将模型空间顶点转化为裁剪空间(投影成像)

裁剪操作:将不在裁剪空间里的顶点给裁剪掉

NDC标准化设备坐标:将裁剪空间转化为NDC标准化设备坐标

背面剔除:将背面的三角面剔除掉

视口变换:将裁剪空间转换为屏幕空间坐标

线

图元装配:将顶点连接,形成三角面,称为图元

光栅化:通过插值,将图元内部形成一个个片元(片元可以理解成一个像素点)

片元Shader:通过纹理着色、光照着色来给片元上色

输出合并

通过alpha测试、模板测试、深度测试、颜色混合,

处理遮挡关系、处理半透明混合,将结果绘制到帧缓冲区

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

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

相关文章

录制电脑屏幕的软件哪个性价比高?这4款软件就很实用

电脑是我们学习和办公不可以缺少的工具&#xff0c;除了使用它上面的应用之外&#xff0c;我们有时还需要它进行屏幕录制。那有没有可以录制电脑屏幕的软件呢&#xff1f;当然有&#xff01;录制电脑屏幕的软件哪个性价比高&#xff1f;今天小编就给大家分享4款性价比高的软件&…

报表生成器 FastReport .Net 用户指南 2023(三):Bands

FastReport .Net是一款全功能的Windows Forms、ASP.NET和MVC报表分析解决方案&#xff0c;使用FastReport .NET可以创建独立于应用程序的.NET报表&#xff0c;同时FastReport .Net支持中文、英语等14种语言&#xff0c;可以让你的产品保证真正的国际性。 FastReport.NET官方版…

Echarts环形图、饼图径向渐变示例

第005个点击查看专栏目录在上一篇文章中已经讲过 ECharts线性渐变色示例演示&#xff08;2种渐变方式&#xff09;&#xff0c;这里做了环形图&#xff0c;饼图的一个径向渐变的示例演示&#xff0c;这里type: ‘radial’,想&#xff0c;y、x、z需要设置相应的数值&#xff0c…

【微服务】Elasticsearch概述环境搭建(一)

&#x1f697;Es学习起始站~ &#x1f6a9;本文已收录至专栏&#xff1a;微服务探索之旅 &#x1f44d;希望您能有所收获 一.初识elasticsearch (1) 作用 elasticsearch是一款非常强大的开源搜索引擎&#xff0c;具备非常多强大功能&#xff0c;可以帮助我们从海量数据中快速…

如何扛住游戏流量高峰?Evil Dead 主创这样说

“完全对得起原作电影。” “鬼玩人 (Evil Dead)”系列是恐怖幽默动作电影的经典之作&#xff0c;40多年的IP经典化历程中&#xff0c;《鬼玩人》&#xff08;Evil Dead&#xff09;正在推出该系列的第5部电影作品。同时也从经典三部曲中衍生出了“Evil Dead: The Game”——主…

【elementUi】与【elementPlus】图标引入的区别,elementPlus图标引入不成功

elementui图标官网 组件 | Element elementui中以类的名字与标签绑定即可引入 elementPlus图标官网&#xff1a; Icon 图标 | Element Plus (element-plus.org) elementplus中要自己成为一个标签的形式引入 如果引入不成功 最好在使用标签之前安装elementplus npm instal…

【云原生】nuclio:一个高性能的“serverless”框架

文章目录nuclio简介Nuclio框架架构函数处理器事件响应模式Dealer广泛的应用实时例子&#xff1a;车联网的事件驱动分析其他函数定义文件事件模型日志接口数据绑定模型nuclio看板CIL命令nuclio简介 Nuclio是一个高性能的“无服务器”框架&#xff0c;专注于数据、I/O和计算密集…

Signal tap 的各种用法

本文分为两部分&#xff0c;前一部分用于介绍signal tap基本功能&#xff0c;如果是初学者&#xff0c;看完这部分就可以用signal tap抓取一些简单的波形数据了。第二部分用于介绍一些特殊要求时的软件设置&#xff0c;比如连续触发&#xff0c;自定义触发条件等等。Signal Tap…

Linux从安装到实战+瑞吉外卖Linux项目部署

1.1虚拟机介绍1.2VMware Workstation虚拟化软件下载CentOS;5分钟教你下载安装VMware16虚拟机&#xff08;含许可证密钥&#xff09;【全免费VMware虚拟机 上集】_哔哩哔哩_bilibili1.3远程链接Linux系统 &FinalShell链接finalshell半天没连接进去他说ip adress 看IP地址不对…

【电子学会】2022年12月图形化一级 -- 和平使者

和平使者 1. 准备工作 &#xff08;1&#xff09;删除小猫角色&#xff1b; &#xff08;2&#xff09;选择背景Nebula&#xff0c;Space&#xff0c;删除默认的白色背景&#xff1b; &#xff08;3&#xff09;选择角色Dove。 2. 功能实现 &#xff08;1&#xff09;点击…

线程安全的集合类(多线程环境下使用ArrayList、队列及哈希表)

目录&#xff1a;多线程环境下使用ArrayList多线程环境下使用队列多线程环境下使用哈希表多线程环境下使用ArrayList在多线程环境下使用ArrayList可以有以下三种方式&#xff1a;1.使用同步机制 (synchronized 或者 ReentrantLock)2.Collections.synchronizedList(new ArrayLis…

Python __slots__:限制类实例动态添加属性和方法

那么&#xff0c;Python 是否也允许动态地为类或实例对象添加方法呢&#xff1f;答案是肯定的。我们知道&#xff0c;类方法又可细分为实例方法、静态方法和类方法&#xff0c;Python 语言允许为类动态地添加这 3 种方法&#xff1b;但对于实例对象&#xff0c;则只允许动态地添…

相机标定与3D重建(3)使用OpenCV对摄像机进行标定

相机已经存在很长很长时间了。然而&#xff0c;随着20世纪末廉价针孔相机的出现&#xff0c;针孔相机在我们的日常生活中司空见惯。不幸的是&#xff0c;这种廉价是有代价的:严重的扭曲。幸运的是&#xff0c;这些都是常量&#xff0c;通过标定和一些重新映射&#xff0c;我们可…

WebDAV之葫芦儿·派盘+GeniusScan

GeniusScan 支持WebDAV方式连接葫芦儿派盘。 推荐一款功能极其强大的手机微型扫描仪软件,可以将所有的东西扫描成为pdf格式的文档,还支持连接葫芦儿派盘服务。 GeniusScan让您的安卓设备变身微型扫描仪。它能让您快速扫描文档,将扫描结果保存JPEG或PDF格式,

【数字化】要点整理-《数据治理体系完整指南》

导读&#xff1a;本文整理内容来自一篇关于数据治理体系相对比较完整内容文章&#xff0c;体系化的范围介绍主要包括了介绍元数据、数据标准、数据建模、数据集成、数据质量、数据开发、数据安全、ETL。可以作为数据治理建设参考。01 数据治理体系02 元数据2.1、元数据解决的问…

先天性心脏病的6大症状,家长要重视治疗!

先天性心脏病是一种严重的心血管疾病&#xff0c;与遗传和环境有密切的关系&#xff0c;而且先天性心脏病越早治疗效果越好&#xff0c;因此要了解先天性心脏病的相关症状&#xff0c;能够更早的确诊病情&#xff0c;并提高患者的治愈几率。 天天性心脏病有哪些症状&#xff1f…

【链表面试题考察】

以下题目均为IO型。1.给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。题目示例如上&#xff1a;解题思路&#xff1a;双指针问题&#xff0c;给定指针prev和cur&#xff0c;从头结点开始往…

Unity SKFramework Documentation

文章目录Audio 音频背景音乐音效音频库Audio ListenerActions 事件Action 事件类型Action Chain 事件链Sequence 序列事件链Concurrent 并发事件链Timeline 时间轴事件链FSM 有限状态机State 状态State Machine 状态机State Builder 状态构建器ObjectPool 对象池IPoolable 接口…

2023 年 1 月的5篇深度学习论文推荐

本文整理了 2023 年 1 月5 篇著名的 AI 论文&#xff0c;涵盖了计算机视觉、自然语言处理等方面的新研究。 InstructPix2Pix: Learning to Follow Image Editing Instructions https://arxiv.org/abs/2211.09800v2 伯克利分校的研究人员开发了一种使用人工指令编辑图像的新方…

小程序项目学习--**第三章:WXSS-WXML-WXS语法**事件处理-组件化开发

第三章&#xff1a;WXSS-WXML-WXS语法事件处理-组件化开发 01_(掌握)WXML语法-基本规则和mustache语法 Page({data: {message: "Hello World",firstname: "kobe",lastname: "bryant",date: new Date().toLocaleDateString(),}, }) <!-- 1.Mu…