游戏图像学基础 实践经验和优化(一)

来源:互联网 发布:淘宝上买刀具犯法吗 编辑:程序博客网 时间:2024/06/06 16:29

游戏图形学基础、实践和优化

一.发展历史

  OpenGL发展由最早的仅支持桌面的OpenGL1.0到支持移动平台的OpenGLES1.x可采用固定管线编程,发展到OPenGLES2.x可以支持可编程管线,包括常用的顶点着色器和片元着色器等,到OpenGLES3.x开始支持MRT,ETC2,多实例化渲染,sRGB纹理,UBO,浮点纹理,3D纹理,现在最新(2017)的OPenglES3.1+AEP支持了Compute Shader和tessellation。

名词解释:

固定管线着色器:比较老的着色器,现在用的少。

可编程管线着色器:也就是现在常用的顶点着色器和片元着色器。

MRT多目标渲染:简单来说就是把颜色深度法线等信息存储在不同的RT里边方便使用。

ETC2.0:比ETC1压缩质量更好而且支持Alpha通道。

sRGB纹理:伽马矫正的时候使用。

 

二.渲染管线

     所谓渲染管线就是一条线性的流水线,如下:

按阶段划分:

    1.应用阶段:(CPU)输出渲染图元,粗粒度剔除碰撞检查,传递给下一阶段使用。


2.几何阶段:(GPU)负责把顶点坐标转换到屏幕空间,再交给光栅化阶段处理。该阶段包括顶点着色器,曲面细分着色器,几何着色器,裁剪,屏幕映射。


3.光栅化阶段:这一阶段将上个阶段的数据产生到屏幕上的像素。该阶段包括三角形设置,三角形遍历,片元着色器逐片元操作,最终输出到屏幕图像。

 

*我们比较关注的顶点坐标变换:模型空间-世界空间-View空间-Project空间-齐次裁剪NDC坐标空间-屏幕空间。

*透明度测试,模板测试,深度测试,颜色混合(按顺序进行)几大测试需要深入理解

 

名词解释:

几何阶段:

a.顶点着色器:坐标变换和逐顶点光照,将顶点空间转换到齐次裁剪空间。

b.曲面细分着色器:可选

c.几何着色器:可选

d.裁剪:通过齐次裁剪坐标的-w<x<w判断不在视野范围内的部分或者全部裁剪,归一化。
e.屏幕映射:把NDC坐标转换为屏幕坐标

光栅化阶段:

a.三角形设置:计算网格的三角形表达式

b.三角形遍历:检查每个像素是否被网格覆盖,被覆盖就生成一个片元。

c.片元着色器:对片元进行渲染操作

d.逐片元操作:模板测试,深度测试 混合等

e.屏幕图像

 

三.线性空间和伽马空间:由于人眼天生对光线较暗的比较敏感,比如亮度为0.10.2之间看起来会比0.9.1.0之间看起来差别更大。为了更加精确的反映人类的视觉,我们通常把更多的存储空间用来存储亮度低的像素值。


伽马空间:对颜色值一般进行Power(col,0.45)计算,比如0,0.22,1编码到00.5,1.把更多的颜色值用来存储眼睛容易辨别的较暗局域。该转换会使颜色看起来变亮了、我们的大多数图片颜色值存储在该空间。


伽马矫正:指将线性空间衍射到伽马空间。2.2*0.45=1

CRT显示伽马:由于历史和巧合,屏幕对颜色进行输出的时候会进行显示伽马操作,计算Power(col,2.2),所以输出会比原图变暗。


Unity ColorSpace Setting:不支持移动平台,所以我们一般都选择Gamma Space

Gamma Space:实际上就是放任模式,不会对shader的输入进行任何处理,即使输入可能是非线性的;也不会对输出像素进行任何处理,这意味着输出的像素会经过显示器的display gamma转换后得到非预期的亮度,通常表现为整个场景会比较昏暗。

 

Linear Space:Unity会背地里把输入纹理设置为sRGB模式,这种模式下硬件在对纹理进行采样时会自动将其转换到线性空间中.也会设置一个sRGB格式的buffer,此时GPU会在shader写入color buffer前自动进行伽马校正再次转换到伽马空间。


常规做法:图片格式在伽马空间,选择ColorSpaceGamma,进行颜色采样时先进行float3 diffuseCol = pow(tex2D( diffTex, texCoord ), 2.2 ); 伽马矫正,在线性空间计算光照屏幕后处理,最后在matcopy输出的时候再return fragColor.rgb = pow(fragColor.rgb, 1.0/2.2);还原回去。最后经过CRT的伽马矫正输出。

 

四.关于高通GPU:

1.tile based rendering默认开启

2.内部采用了Binning Pass和Rendering Pass优化.

3.VulKan:和OpenGL类似 是一种跨平台的图像应用接口,主要优势包括:多平台,多线程,所有平台统一API,相比OpenGL提供了更丰富的API,需要开发者去维护更多的状态,以前OpenGL自己维护的状态需要开发者去操心,所以开发成本会更高。它的OverHead比OpenGl更小,采用了Command Pools,Sync Object,Render Pass.其中memory Allocation由开发者自己管理,可采用offset寻址的方式分配内存带来更高效率。但是需要硬件支持。

4.关于多线程渲染和功耗问题,比如一个gpu渲染的时候负荷100%,采用了两个GPU渲染后 每个负荷50%,实际功耗会下降很多,而不是成线性关系。当然多线程满负荷运行的时候会导致GPU发热而产生降频,这会导致性能持续下降。

5. GPU图像分析工具:snapdragon profiler,这款工具通过三种数据捕获模式显示应用程序的CPU、GPU、DSP、内存、功率、网络连接和设备运行时的发热数据,从多个不同的角度展现设备性能实时(Realtime)模式下,您可以在设备应用程序运行的同时查看实时度量数据。跟踪捕获(Trace Capture)模式仅捕获Snapdragon处理器驱动设备可用的跟踪事件和数据。快照捕获(Snapshot Capture)模式下,开发人员可借助图形应用程序捕获和调试其OpenGL ES应用程序框架,包括单步调试绘制指令,查看和编辑着色器(但因为unity是编译后的shader无法在profile里边查看和修改).程序纹理以及查看像素历史的能力。(但是调试手机必须是高通GPU)。

6.Battery Power工具检测电池状态 功耗等,Symphony SDK 可优化功耗。

7美术使用调色器可用八猴渲染器

 

关于游戏优化的建议:

1.减少像素,其中包括使用更低的屏幕分辨率和使用低分辨率的纹理去存储一些精度要求不高的纹理,中低端推荐分辨率为1280*720,好一点的手机可以采用1080P。

2.降低DrawCall,其中包括模型批次合并和纹理拼成合集。

3.降低带宽 ,其中包括图像压缩,使用mipmaps,高通内部会采用统一带宽压缩技术,在传输的过程中会提前把纹理压缩好,使用的时候再解压使用。

4.FBO VBO,减少Frame Buffer Object的切换, 减少 Vertex Buffer Object之间的切换,采用先合并在draw的方式。

5.渲染排序,防止OverDraw,包括材质排序,先渲染近的再渲染远处最后渲染Sky。对于不需要的depth buffer和stencil buffer尽早discard掉。

6.Tessellation曲面细分着色器

7.精度选择,对精度要求不高的一些特殊纹理 采用更低的精度去渲染。

8.通道使用,合理使用RGBA通道 防止浪费。

9.防止亚像素三角形的产生,亚像素三角形会导致后期GPU压力变大。

10.ComputeShader和FragmentShader之间尽量减少GPU状态切换。


 

 

 

 

 

 

 

 

 

 

 

阅读全文
0 0