游戏引擎架构——渲染

1. 场景描述

1.1 表面建模

矩形面片的表示:贝塞尔曲面、非均匀有理B样条、N面片
细分曲面(subdivision surface)
三角网格
=>固定镶嵌(tessellation)
=>动态镶嵌:细分曲面 or LOD:level of detail 物体与虚拟摄像机的距离的缩减而增加面片个数,最近的为LOD0
应用于可扩展的网格,如水面、地面(用高度场描述)

1.2 三角网格的表示

法线、背面剔除
索引化三角形表:顶点缓冲(DX)、顶点数组(OpenGL);索引存储在索引缓冲、索引数组中
顶点缓存优化:三角形带、三角形扇

1.3 模型空间

模型空间、局部空间、物体空间
世界空间:网格示例+模型至世界矩阵(旋转、缩放、位移)

1.4 颜色、纹理、材质

每像素位数Bits per pixel BPP
高动态范围high dynamic range HDR
顶点属性:位置、法线、切线、颜色、纹理坐标、蒙皮权重
纹理种类:漫反射贴图(diffuse map),法线贴图、光泽贴图、环境贴图(环境反射)
mipmap:多级渐远纹理,用于处理莫列波纹
纹素密度:纹素和贴图表面的(世界空间、屏幕)面积之比
纹理过滤:纹素->像素的采样过程(最近邻、双线性、三线性、各项异性)
材质:包含着色器、着色器的输入参数、纹理;不包含顶点属性

1.5 光照

1.5.1光传输模型:
局部光照模型:只考虑直接光照(每个物体不会影响其他物体的光照)
-Phong式反射模型:
环境光+漫反射+镜面反射,可用BRDF表示
BRDF:双反射分布函数,入射光和人看到的光线强度图,包含法线N,光源方向L和视线方向V
全局光照模型:考虑间接光照(光线追踪ray tracing, 辐射度算法 radiosity)
渲染方程/着色方程:全局光照模型可由单一数学公式描述

1.5.2 光源模型:
静态光照:存储在光照贴图light map中,是一个纹理贴图
不存储在漫反射纹理贴图中的原因:光照纹理贴在所有受光影响的物体上,处理动态物体经过光源的光照;更好压缩;漫反射纹理会重复使用,不能放在其中
环境光
平行光
点光
聚光(圆锥)
面光
发光物体:放射光贴图(emissive texture map)模拟,纹理的颜色以完全强度发射,不收附近光照的影响;+ 光源

1.6 虚拟摄像机

观察空间:摄像机位于空间原点、观察至世界矩阵View-World
模型->世界->观察:世界至观察矩阵、又称观察矩阵World-View,是观察至世界的逆矩阵
观察体积:view volume、近平面、远平面
透视投影对应平截头体(frustum)、正射投影对应长方体
投影:透视投影(perspective)、正射投影(orthographic),将点从观察空间变换至齐次裁剪空间
齐次裁剪空间:是观察空间的变形版本,将观察体积转换成标准观察体积:一个长方体,x,y和z坐标都是(-1,1)。这个坐标系统为齐次裁剪空间
屏幕空间:二维。屏幕映射:将裁剪空间坐标平移、缩放至屏幕正方形里。渲染时,忽略面片的z坐标,只使用x和y坐标绘制在屏幕上(帧缓冲)
光栅化:三角面片的片段(fragment)对应屏幕上的一个或部分像素
-抗锯齿(anti-aliasing):全屏抗锯齿FSAA:耗时
多重采样抗锯齿MSAA:将每个像素拆分成多个片段,渲染前结合成单个像素
帧缓冲:渲染后的图像存储在帧缓冲(frame buffer)的颜色位图缓冲里。显示硬件周期性读取缓冲。
-双缓冲:硬件读取缓冲时,渲染引擎更新另一个缓冲
-三缓冲:硬件读取缓冲A时,若已经渲染完毕缓冲B,则可以渲染缓冲C,而不需要等A读取完
深度缓冲:全屏缓冲,每个像素有深度数据。每个片段有z坐标,通过对比深度缓冲决定写入帧缓冲或是丢弃,写入帧缓冲时,更新深度缓冲
-深度冲突:当两个平面很接近时,由于表达精度不够造成像素刺穿的情况
-裁剪空间的z深度是观察空间z坐标的倒数,是非均匀分布的,越远离相机,越容易产生深度冲突
-w缓冲:使用观察空间的z坐标。存储的时裁剪空间的坐标,再算倒数
模型->世界->观察->裁剪空间->屏幕空间->帧缓冲

2. 渲染

2.1 渲染管道

工具阶段:处理网格和表面材质。
资产调节阶段:资产调节管道(asset conditioning pipeline ACP)链接asset,生成静态场景数据(如BSP树)、静态光照
应用程序阶段(CPU):处理网格实例和子网格,每个子网格关联至一个材质
几何阶段(GPU):网格顶点变换、照明、投影至其次裁剪空间、使用几何着色器处理三角形,裁剪三角形
光栅化阶段(GPU):三角形分解为片段,片段着色器着色,深度测试、alpha测试、模板测试后输出到帧缓冲

2.2 GPU管道

顶点着色器:可编程的。变换着色、光照顶点,如透视投影、光照、蒙皮、修改顶点位置等等。输入是世界坐标顶点位置、法线,输出是其次裁剪空间的顶点坐标和法线。顶点可以存取纹理数据(顶点纹理拾取vertex texture fetch VTF)
几何着色器:可编程的。处理以其次裁剪坐标表示的图元,能剔除或修改图元,生成新的图元,如阴影体积拉伸、动态镶嵌、布料模拟、线段分型细分模拟闪电效果等等。
流输出:将数据写回内存,并回到管道初始进行处理(重历顶点着色器和几何着色器)。如头发样条在顶点着色器上进行物理模拟,几何着色器上变成头发线段,流输出后重新在管道中渲染头发线段
裁剪:可配置的。在平截头体之外的三角面片切掉
屏幕映射:变换到屏幕空间
三角建立、遍历:将三角面片分解为片段,光栅化,生成片段属性。
提前深度测试:可配置的。丢弃部分片段
像素着色器:可编程的。输入是片段属性,输出是片段颜色,也可丢弃片段,此时不输出
合并、混合阶段:可配置的。光栅运算阶段(raster operation stage)。深度测试、alpha测试、模板测试。根据alpha混合片段颜色。先渲染不透明物体到帧缓冲,然后将半透明表面从后往前排序渲染

2.3 着色器

着色语言:
-Cg: C for graphics
-HLSL: Dx
-GLSL: OpenGL
内存访问:不能直接读写内存,只能通过寄存器和纹理贴图
寄存器:128位,能存放4个32位的整数、浮点数
-输入寄存器:GPU自动设置值,如顶点坐标等等
-常数寄存器:也可作为输入,如观察矩阵、投影矩阵、光照参数等等
-临时寄存器:着色器内部存储中间结果
-输出寄存器:着色器填写。GPU会将一些输出寄存器写入缓存,防止重复计算
纹理贴图:能用渲染到纹理(render to texture RTT)将数据写入纹理,并将场景渲染至屏幕外帧缓冲,后续的渲染阶段把帧缓冲作为纹理贴图使用
效果文件:Cg中为CgFX,GLSL中为COLLADA文件。定义struct,着色器程序(函数),全局变量;定义多个技术(technique),包含主版本和回退版本技术供低级图形硬件使用;技术中定义多个pass,描述如何渲染一帧。pass中包含顶点、几何、像素着色器程序函数的引用

2.4 应用程序阶段

遍历可见的网格,对子网格材质对,以材质规格设置渲染状态,并调用底层的绘制函数(这些函数构建了GPU命令表),提交图元至GPU

2.4.1 可见性判别:剔除(cull)不可见的物体
平截头体剔除:包围体积(包围球体)判断
遮挡剔除(occlusion culling):
-预计算潜在可见集(potentially visible set PVS):将场景切割成区域,提供相机在该区域的可见其他区域列表。脱机或美工指定。自动方法:每个区域挑视点渲染场景,不同区域物体用不同颜色编码,扫描帧缓冲得到可见区域表
-入口(portal):窗户、门等。入口建立平截头体
-遮挡体积、反入口(anti-portal):被物体遮挡的体积

2.4.2 提交图元至GPU
渲染状态、硬件状态(render state):GPU管道内所有可配置参数,如世界观察矩阵、光源方向、纹理绑定、深度测试是否启用、alpha混合选项
状态泄露:忘记设置渲染状态,使用脏渲染状态数据,得到错误渲染结果
渲染状态是全局的,渲染状态改变的次数越少越好。按渲染状态排序后的结果绘制。通过深度预渲染(z prepass)防止overdraw,即一个像素绘制多次。
渲染场景两次:
1. 按深度从前到后的顺序渲染深度缓冲,此时关闭着色器,仅仅更新深度缓冲
2. 按渲染状态排序,参照深度缓冲的结果绘制帧缓冲,最少的改变渲染颜色
3. 从后至前的顺序渲染半透明表面,此时会频繁的切换渲染状态

2.4.3 场景图
快速排序、剔除物体
-四叉树:二维,递归的把空间分割成象限,叶子节点有均匀的图元数,平截头体剔除
-八叉树:三维版本
-包围球树:图元分成小组,计算小组的包围球,再将小组合并成大组,算大组的包围球,递归至整个场景。平截头体剔除
-BSP树:递归的把场景分成两半,分割平面任意方向。平截头体剔除、排序
-kd树:BSP树的变种,依次与k维空间的轴对齐(先以x坐标分割,再以y坐标分割)

3. 光照

3.1 基于图像的光照

-法线贴图:存在RGB中,由于值域不同,所以要加偏移量
-高度贴图:灰阶。方法有视差贴图法(parallax mapping)和浮雕贴图法(relief mapping)。能自遮挡和自阴影
-镜面、光泽贴图:存储镜面反射参数(反射率、镜面幂)贴图(specular map),模拟汗水。只有反射率的有时叫光泽贴图(gloss map)、镜面遮罩(specular mask),0表示没有镜面效果的部分。只有镜面幂的叫镜面幂贴图(specular power map),可控制镜面高光的集中程度
-环境贴图:有如全景照片,低成本反射渲染用到。球面环境贴图、立方体环境贴图
-三维纹理:一系列二维纹理,之间是连续的。三维纹理渲染的大理石球体,切面的贴图连续

3.2 高动态范围光照(high dynamic range HDR)

真是世界中光强可无限大,此技术允许保存>1强度的光,而不是限制在0-1之间。在显示之前做一个色调映射(tone mapping),归一化光线强度。可实现bloom effect,强光从物体边缘溢出。HDR表示方法:RGB各用32位存储,或者LUV中UV用8位,L用16位且以log2X存储,以放大存储范围

3.3 全局光照(global illumination GI)

3.3.1 阴影
半影(penumbra)
阴影体积:从光源的位置到物体轮廓边缘,轮廓边缘沿光线方向延伸,生成一个阴影体积。使用特殊的全屏缓冲:模板缓冲(stencil buffer),它对应屏幕每个像素存储一个整数值,渲染时模板缓冲可作为遮罩。
首先渲染没有阴影的场景,填充深度缓冲。渲染阴影体积并设置模板缓冲,正向的三角形+1,反向的-1。将模板缓冲中非0的区域加深颜色。
阴影贴图:从光源的视角进行深度测试,把深度信息存储在阴影贴图纹理里。再以正常方式渲染场景,对于在阴影贴图中被遮挡的片段加深颜色。若片段到光源的距离比阴影贴图里的远,则表明被遮挡。

3.3.2 环境遮挡(ambient occlusion AO)
渲染接触阴影的技术。接触阴影是指场景仅以环境光照明时产生的软阴影。如管子内部的阴影、房子和地面接触点的阴影等。计算方法是以该点为圆心画球体,求球体表明光照面积和球体面积的百分比。AO脱机计算成纹理,与观察方向与入射光方向无关。

3.3.3 镜像:环境贴图、或者把摄像机从反射点渲染一张贴图

3.3.4 焦散(caustics):水下的高光。投影半随机亮点的纹理至物体表面

3.3.5 次表面反射(subsurface scattering SSS):光线在表面下散射。柔软的效果如玉。
根据一张贴图度量光线需要经过多少距离才能通过遮挡物,同时漫反射光照强度与光线经过物体到另一面的距离成反比,便可实现淡淡泛光的感觉

3.3.6 预计算辐射传输(precomputed radiance transfer PRT):预先计算来自所有方向的入射光和表面的互动
(反射等)并存到入射光查找表中。运行时迅速得到准确的光照。

3.4 延迟渲染

将光照计算从观察空间延迟到屏幕空间。先迅速生成不含光照的场景,并将所有用于光照计算的信息存储在几何缓冲(G buffer)中,如深度、表面法向量、颜色、PRT系数等。完成场景渲染后用几何缓冲的信息计算光照和着色。这样更高效。

4. 其他渲染系统

4.1 粒子效果:由多个quad组成,都是面向摄像机的billboard
4.2 贴花(decal)
4.3 天空:先将帧缓冲填满天空的纹理,再渲染三维物体。天空的z值最大。天空盒:盒子中心位于摄像机的位置,z值最大
4.4 地形:高度场地形(height field terrain)存为灰阶纹理贴图,每个区域三角形数量按摄像机距离调整。地形的贴图是纹理混合
4.5 水体

5. 覆盖层、UI层

覆盖层在主场景之后渲染,并关上深度测试确保他们会显示在三维场景之上。
归一化屏幕坐标:一个轴的范围是0-1,适应不同分辨率。但不能两个轴都设为0-1

6. 伽马校正

阴极射线管CRT屏幕中,亮度值a和实际的亮度b是非线性的。b=a^gamma,gamma>1。校正此情况,颜色传至CRT前会做个逆变换,a_new = a^(1/gamma)

7. 全屏后处理

把全屏内容传送至像素着色器渲染。如动态模糊、景深模糊、晕影(vignette,屏幕边角变灰)、着色(将屏幕上的颜色后处理)

版权声明:本文为CSDN博主「peerlessbloom」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/PeerlessBloom/article/details/72644498

最新文章