渲染原理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了渲染原理相关的知识,希望对你有一定的参考价值。

参考技术A

啥玩意是渲染?
游戏图像的绘制被称为渲染

啥玩意是渲染管线?
表示绘制到游戏视图的过程中,一个模型文件的数据经过了哪些转换步骤
通常指的是GPU流水线,不包含CPU部分

CPU主要是准备好顶点、贴图、法线、灯光方向、颜色等东西之后,告诉GPU
GPU接收到数据后,就要对其处理最终显示到屏幕上

因为屏幕是2D画面,模型是3D资源,必然有一部操作,就是将3D转化为2D。
这个操作之前被称为顶点阶段(几何阶段),主要是处理3D模型数据
之后被称为片元阶段(光栅化阶段),处理2D像素数据

1.顶点着色器(Vertex Shader)
如下所示:

每个顶点都会调用一次这个函数,并转化为这个函数的输出,这些输出被称为图元(Primitive)
一般可以在这里改变顶点或者法线相关信息

2.曲面细分(Tessellation Shader)
是OpenGL 4.0新加入的特性,很多设备还不支持
主要的作用是可以优化曲面,eg:使曲面更平滑

3.几何着色器(Gemoetry Shader)
几何着色器的输入输出都是图元(Primitive),不是顶点
可以将简单的图元扩展成更为复杂的形式

4.变化回执(Transform Feedback)
是在OpenGL 3.0之后加入的特性
可以将图元存放到 Transform Feedback Buffer中,并可以决定是否按照先前的流程光栅化
主要特性:在下一帧渲染时,可以得到上一帧图元的数据,对于定量变化的情况,可以节省掉流水线之前的步骤
(常被用于粒子系统 or 角色的头发)

5.裁剪(Clipping)
图元会根据视域的平截头体(Frustums)做可见性判断
区域外的定点会被舍弃,与这个定点连线的三角形的边会与平截体求交点,这些交点就变成裁剪后的新顶点

6.屏幕映射(Screen Transform)
图元的坐标从齐次裁剪空间变换到屏幕空间

7.图元装配(Primitive Assembly)
顶点会被转化成基础图元,供后续步骤使用
三角形的朝向剔除(Face Culling)是在这个阶段完成的

8.光栅化(Rasterization)
三角形会经历两个步骤:
1.三角形会被转化成片段
2.会遍历三角形,获取顶点属性进行插值,在每个像素点上产生一个插值

如果开启了多重采样抗锯齿(Multisample Antialiasing,MSAA),此处就会对每个像素进行多次采样,产生多个偏远,最后在混合,以达到抗锯齿的效果

9.提前深度测试(Early Depth Test)
检查片元的深度,如果不需要显示则丢弃它
可以在片元着色器运行之前去掉不合理的值,减少运算的消耗
但是 与后续的透明测试有冲突 ,如果在后续的透明度测试中失败,这步深度测试也不应该将其通过
有些GPU会判断是否有此类冲突,如果有就跳过(有一定消耗)

10.片元着色器(Fragment Shader)
可以自定义光照计算、读取贴图颜色、设置透明度等
输入是光栅化后得到的片元数据,输出值也为片元数据
Unity中会把函数返回值写为运算后的颜色

11.逐片元操作(Pre-Sample Operation)
这个阶段:主要是先测试后混合

测试共经历了4个测试:
他们的作用都是确定一个像素是否应该显示

1.裁切测试(Scissor Test)
通过区域判断的,与基于顶点的 Clipping 阶段不同

2.透明测试(Alpha Test)
透明度达不到,就不绘制

3.模板测试(Stencil Test)
通过缓冲区来进行像素比较,与ColorBuffer或DepthBUffer,StencilBuffer是一个8位图像,每个像素保存一个无符号整型

4.深度测试(Depth Test)
通过深度缓冲区的比较,判断是否应该绘制像素
需要先制定深度写入规则,然后再指定比较规则
分别对应Unity的 ZWrtie 和 ZTest
(深度写入不透明物体默认打开,透明物体默认关闭,测试方法默认是小于等于)

混合阶段主要有2个阶段:
1.混合(Blending)
通过测试的颜色与ColorBuffer中颜色的叠加方式
混合有多种叠加方式,一般会使用RGBA的值作为计算因子,采用插值的方式进行线性计算

2.写入遮罩(Write Mask)
主要是颜色遮罩(Color Mask),在最终绘制时,对颜色进行过滤

so,
经过上面所有的步骤后,最终这个像素会被绘制到颜色缓冲区,并被显示到屏幕上

浏览器渲染原理 渲染树和页面渲染

来自:https://blog.csdn.net/qq243541844/article/details/51922947

【浏览器渲染原理】 渲染树和页面渲染

  • 我们主要讨论以下列出的几个问题:
  • 什么是渲染树?和DOM树及CSSOM树有什么关系?
  • 渲染树是如何形成的?
  • 浏览器渲染顺序问题

1.什么是渲染树?和DOM树及CSSOM树有什么关系?

首先我们得先了解一下渲染的基本步骤 
当用户请求的资源通过浏览器网络层到达渲染引擎后。渲染工作就会开始。 
第一步:浏览器解析HTML文档和解析CSS样式表形成DOM树和CSSOM树 
第二步 : 结合DOM树和CSSDOM树形成 render树。 也就是我们所说的渲染树。渲染树 
第三步: 浏览器在render树内对每个render节点进行布局处理,计算出每一个元素的大小和位置。确定其在屏幕上的位置 
第四步:绘制。通过遍历render树将实际的像素显示到屏幕上

以上的步骤是一个渐进的步骤,但是为了提高用户体验,浏览器并不会等待所有html文档加载完成之后才建立渲染树并渲染。 他会在从网络层获取html文档的同时把已经接收到的局部内容先渲染出来


2.渲染树是如何形成的? 
基于DOM树的一些可视化的节点,WebKit根据需要来创建相应的RenderObject节点,这些节点也构成了一颗树,称为render树。

Render树是基于Dom树建立起来的新的一棵树,Render节点和Dom节点并不是一一对应。所以什么情况下需要建立新的render节点呢? 
- DOM树document节点 
- DOM树种的可视化节点 
- 某些情况下建立匿名的render节点 
有一个问题就是什么算可视化节点呢? 
比如 Html,Body,Div,P等就是可视化结点, 而非可视化节点就是 Head, Meta, Script等。 
比如一个DIV的display属性是none,那么它就是非可视节点。 
但是注意. 如果DIV的visibility属性是hidden,它是可视节点。 
这是一个细节需要注意。 
什么情况下建立匿名的render节点? 
RenderBlock用来是用来表示块级元素, 为了处理上的方便,某些情况下需要建立匿名的RenderBlock对象,因为RenderBlock的子女必须都是内嵌的元素或者都是非内嵌的元素。所以,当它包含两种元素的时候,那么它会为相邻的内嵌元素创建一个块级RenderBlock节点,然后设置该节点为自己的子女并且设置这些内嵌元素为它的子女。


浏览器的渲染顺序问题(摘抄)

1.浏览器加载和渲染html的顺序

1、IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的。

2、在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元素都已经下载完)

3、如果遇到语义解释性的标签嵌入文件(JS脚本,CSS样式),那么此时IE的下载过程会启用单独连接进行下载。

4、并且在下载后进行解析,解析过程中,停止页面所有往下元素的下载。阻塞加载

5、样式表在下载完成后,将和以前下载的所有样式表一起进行解析,解析完成后,将对此前所有元素(含以前已经渲染的)重新进行渲染。

6、JS、CSS中如有重定义,后定义函数将覆盖前定义函数

2. JS的加载

2.1 不能并行下载和解析(阻塞下载)

2.2 当引用了JS的时候,浏览器发送1个js request就会一直等待该request的返回。因为浏览器需要1个稳定的DOM树结构,而JS中很有可能有代码直接改变了DOM树结构,比如使用 document.write 或 appendChild,甚至是直接使用的location.href进行跳转,浏览器为了防止出现JS修改DOM树,需要重新构建DOM树的情况,所以 就会阻塞其他的下载和呈现.

以上是关于渲染原理的主要内容,如果未能解决你的问题,请参考以下文章

图像编程:渲染原理

uniapp渲染原理

前端技能树,面试复习第 40 天—— 浏览器原理:浏览器渲染原理,如何优化渲染过程

React Native 渲染原理

WPF 渲染原理

vue中渲染函数Render原理解析