• 图形渲染基础学习


    原文链接:游戏开发入门(三)图形渲染_如果一个面只有三个像素进行渲染可以理解为是定点渲染吗?-CSDN博客

    游戏开发入门(三)图形渲染笔记:

    渲染一般分为离线渲染与实时渲染,游戏中我们用的都是实时渲染。

    1.实时渲染又可以分为2D渲染与3D渲染。
    早期的2D渲染,是通过把一块内存(图片像素数据)往另一块(显示缓冲区)上搬运的方式,实现图片绘制的。

    不过现在很多2D渲染的渲染方式已经采用3D渲染了。原因是当前显卡从架构上就利于并行处理,绘制速度更快,可以很方便提供各种3D效果,还节省图片资源内存。

    3D的渲染简单概括一下,就是把一个空间中的模型所有点的数据取出来,经过空间转换到2维屏幕上,然后根据各项参数与数据在绘制到屏幕上。

    现在几乎所有的游戏都是使用3D的渲染流程。

    2.3D渲染中基本单位就是顶点,顶点数据信息包括如下

    • 位置(相对模型位置)
    • 颜色(可有可无,可以在后面再处理)
    • 法线(主要是用于光照计算,可以知道哪边是背光)
    • 骨骼权重(一个点可能跟随多个骨骼运动)
    • 贴图UV

    3.MipMap 一般自动生成,远处的角色自动使用小的贴图,减少不必要的开销
    MipMap生成时由于边缘问题可能产生混色,所以一个贴图明显不同的地方可以留几个像素

    4.DX 微软的图形编程API,着色语言是High Level Shader Language(HLSL),只能在Windows使用
    OpenGL(OpenGraphicsLibrary) 着色语言是OpenGL Shader Language(GLSL)跨编程语言,跨平台

    5.DX8与OpenGL2.0以后就都支持可编程渲染管线
    vertexShader与pixelShader。现在更新的版本还支持GeometryShader

    渲染管线: 

    6.ES2.0管线流程
    顶点buffer数据——Vertex Shader——PrimitiveAssembly(图元装配)—— 【如果有的话GeometryShader】 Rasterization 光栅化——Fragment Shader(即Pixel Shader)——PerFragementOperation——FrameBuffer

    7.ES2.0管线简述
    Vertex Shader
    顶点变换 移动,旋转,缩放,坐标系转换,投影变换
    光照计算 做法线变换和法线规格化
    纹理坐标转换 修改UV,偏移缩放等

    这个阶段所接收到的数据则是每个顶点的属性特征,输出则是变换后的顶点数据

    GeometryShader
    对一组已经组成图元的顶点进行处理,可以改变图元类型和个数

    Rasterization 光栅化
    把一个矢量三角形变成一个位图图像(填充像素),每个顶点之间会通过颜色数据自动进行插值。

    Fragment(Pixel) Shader
    得到的是片元信息,即每个像素的深度颜色等,可以修改颜色也可改变像素的深度(z-buffering)。
    一个Pixel Shader不能产生复杂的效果,因为它只在一个像素上进行操作,而不知道场景的几何形状

    PerFragementOperation 片段测试,进一步筛选出不必要的信息,具体测试流程如下:

    • Pixel ownership test:测试该像素用户是否可见是否被其他窗口遮挡
    • Scissors Test:裁剪测试,判断是否在定义的裁剪区域内
    • Stencil Test:模板测试,决定了像素的颜色值是否要被写入到渲染目标 这个有点像PS里面的遮罩,相当于我用一个锅把桌子盖住,盖住的部分不渲染
    • Depth Test:深度测试,就是距离摄像机近裁剪面的距离,剔除深度高的
    • Blending:混合,对于特殊的材质(比如玻璃等半透明物体)
    • Dithering:抖动显示,就是用少量的颜色来表现更广泛的颜色的,可以到wiki上查一下https://en.wikipedia.org/wiki/Dither
    • FrameBuffer:最终的渲染数据

    8.HDR基本原理
    高动态范围图像(High-Dynamic Range),从表现上可以提供更高的色深、更广的动态范围和更强的色彩表现力,经常用来调整曝光。

    基本原理:现实最亮的物体亮度和最暗的物体亮度之比为10^8,人的肉眼识别的亮度信息只有10^5左右。但是显示器表示256种亮度。
    所以问题就是一般我们的显示设备的亮度跨度过大(而且人眼对不同亮度的敏感度也不同,参考伽马校正 https://en.wikipedia.org/wiki/Gamma_correction),所以需要一套校正显示器显示的系统,可以简单理解为HDR。

    9.为什么一个角色的衣服要在多个帧去渲染?
    因为不同位置的材质可能不同,其管线中的vertexshader等处理也可能不同,所以要分开绘制。

    10.常见的渲染效果

    • 全局光照:解决的核心问题就是如何很好地表现物体间的相互反射问题,最直接的问题就是如何找到一种更合理的方式来取代局部光照中的ambient(环境光),有多种实现方法,例如辐射度、光线追踪、环境光遮蔽(ambient occlusion)、Light Probe等
    • 阴影:比较流行的主要是shadow mapping和shadow volume。
    • shadow mapping基本原理是场景的深度渲染到一张深度缓冲区中,我们可以在场景中获得一张阴影或者无阴影的贴图,然后用这个深度图进行渲染。
    • Shadow volume基本原理是根据光源和遮蔽物的位置关系计算出场景中会产生阴影的区域(shadow volume),然后对所有物体进行检测,以确定其会不会受阴影的影响。
    • 扭曲:把一定范围的像素的UV进行扭曲

    11.后处理
    相当于对渲染完成后图片的处理,这个是对像素进行处理的,不在渲染管线的流程里面

    AO:环境光遮蔽,描绘物体和物体相交或靠近的时候遮挡周围漫反射光线的效果,基本原理就是物体相交位置的深度不同,深度大的位置就变暗。现在游戏中比较常用的还有一个SSAO。

    模糊:有高斯模糊,径向模糊等,基本原理就是对一定范围的像素点的颜色进行平均混合操作。

    景深:Z值高达一定值就行像素虚化

    辉光(光溢出):某一点的颜色会扩散到他附近的屏幕空间,可以首先进行一次模糊处理,然后对模糊后的图片与原来的图片进行Alpha混合。

    12.材质、贴图、纹理
    (34 封私信 / 81 条消息) 贴图、纹理、材质的区别是什么? - 知乎 (zhihu.com)

    一堂课学会shader笔记:

    第一节课:
    1.Shader分为两种:

    vertex Shader(vs), Pixel Shader(ps)

    2.在3D空间渲染中,一个贴图渲染其实与3D渲染相似,只不过他是有四个在一个平面的定点组成,把图的渲染(类似贴图) 信息取出来进行渲染。
    拓展:传统的2D游戏,是通过把一块内存(图片)往另一块(显示缓冲区)上搬运的方式,实现图片绘制的,
    渲染都是靠CPU的多媒体指令加速。举例来说,一个二维角色动画,可以通过制作其多个序列帧图片循环
    播放来实现。所以我们需要保存多个图片资源,加载时间长还占用内存。
    DX里面的Direct2D是在Direct3D基础上多出来的一层封装,借助Direct3D的功能实现了对底层硬件的直接访问
    从使用的接口上是简化了直接使用Direct3D实现2D效果的一些复杂代码,因此可以认为效率和3d相同,而使用方法上更简单了
    问:我们常见的UI的渲染走的是不是3D渲染管线? 是的。

    3.问:vs函数不写shader也会执行?默认管线里面的顶点处理与shader里面的是什么关系?
    答:默认可以不写shader,那么渲染管线就像传统管线一样正常输出。DX8与OpenGL2.0以后出现可编程渲染渲染管线,管线里面多出了VS与PS阶段。

    4.问:默认vertex Shader都进行哪些操作?
    答:vs默认就是处理顶点变换的,可以简单认为是将空间中的顶点坐标转为摄像机屏幕空间的顶点坐标,这里面涉及到多个转换。

    5.Shader函数执行是通过GPU执行的,而且是并行执行每个顶点的每个函数。

    6.问:顶点需要进一步进行图元装配变成三角形,图元装配怎么理解?在哪一步进行?
    答:图元装配就是根据一定数量的顶点装配成可以渲染管线可以处理的基本图元。在顶点处理之后

    7.三角形是最小的光栅化单元,光栅化简单理解就是把顶点数据“位图”化,从顶点转换为像素。
    要确定三角形在屏幕占多少个像素点,光栅化时所有的像素是没有颜色的。需要从贴图里面拷贝 颜色信息。

    8.PS函数,是针对像素来处理的,也是并行的。

    9.注意两种投影 透视投影perspective 与 正交投影 orthography。
    透视投影的过程简单理解就是,将一个视锥不断的压缩 ,得到的效果就是近大远小。正交投影就是无论从哪个位置看,大小都是一样的。

    10.关于景深图
    就是其Z值构成的,能也清晰的看到轮廓,原因就是一个Z值小的地方浅,边缘处 是其他物体Z值大。(0-1)

    11.Z值深度应用

    a.景深效果 Z值高达一定值就行像素虚化
    b.SSAO 屏幕空间环境光遮蔽
    发现如果当前位置与附近像素点的位置深度信息不同,深度大的位置就变暗

    第二节课:
    1.Render Texture(离屏渲染)

    渲染结果不仅可以到屏幕,也可以到图片上。虚幻里面有一个RenderTarget,原理相同。

    2.顶点处理MVP

    Modeling Transformation(模型矩阵变换,模型点相对坐标转换到相对世界坐标,平移,旋转,缩放)
    View(相对视角变换,世界坐标系一个点转换到摄像机坐标系里)
    Projection(投影变换,挤压过程,比较复杂)
    3.Shader里面最简单的变换就是MVP
    将输入的顶点相对其模型的坐标,输出一个完成MVP变换的可以 与屏幕空间对应的二维坐标(结果是3维,另外两维可以认为无效)

    4.DX9之前,渲染管线是几乎固定的,我们无法使用shader参与中间过程的渲染

    5.对于某些顶点,我们直接返回其在屏幕上固定的坐标,可以实现类似UI的效果

    6.VS函数可以用来处理蒙皮骨骼动画,根据权重处理渲染

    7.CPU与GPU架构不同,互相不能访问显存与内容

    8.CPU一开始会得到模型的顶点等数据,需要UpLoad到GPU,然后GPU去处理
    这个UPload过程不能频繁进行,因为顶点数据是很多的,所以一般渲染时我们看到模型在变化,其实在CPU他的位置是没变的

    第三节课:
    1.BillBoard广告板的效果实现原理:
    效果就是一个物体永远对着摄像机。原理是先做MV处理,在投影前把广告版强制沿着摄像机视窗平面展开
    使图像一直对着摄像机,然后再做投影变化P处理。

    2.shader传入的参数可以自己规定

    3.图元装配细节
    一个VertexBuffer作为顶点缓存,一个IndexBuffer作为索引缓存,然后索引缓存里面,每三个顶点对应一个三角形(顶点顺序不能反)

    4.光栅化是一个有损的过程
    把一个矢量三角形变成一个位图图像,每个顶点之间会通过颜色数据自动进行 插值。

    5.UV
    UV就是我们每个渲染顶点对应图片的坐标位置,渲染的时候需要根据当前顶点的UV数据去图片上找到对应的颜色信息。

    6.采样
    属于光栅化的一个步骤,就是上面描述的根据UV从图片对应位置取颜色信息

    7.VS函数的输出就是PS函数的输入,PS函数输出的是颜色值

    8.由于顶点的数量是有限的,PS得到的UV信息需要在VS里面经过插值处理

    9.FilterMode

    • Point采样(只在指定位置采样)
    • Bilinear采样(附近4个位置采样)
    • Trilinear(两次,一次在精细图四个位置采样,第二次在小的图四个位置采样)

    10.shader应用

    • 裁剪图片
    • 马赛克(先扩大100倍,取值后缩小忽略小数点,有的只重复会被忽略)
    • 阴影(从光源方向加一个摄像机,先渲染一遍记录深度。最终渲染利用这个信息)
    • 全屏泛光(可以影响模型之外的像素,从当前像素附近取其他像素颜色进行调整)
    • UI处理 可以直接丢弃某些位置的渲染,实现拼图功能

    11.减少采样有利于性能的提升

    视频链接:游戏开发入门系列(3) 图形渲染(第1节)_哔哩哔哩_bilibili

  • 相关阅读:
    JS-全局dom对象的使用---使用htm样式和js函数动作的完全分离
    机器学习之决策树【西瓜书】
    Windows11企业版安装WSL2和Ubuntu发布版(避坑)
    深度学习-通过Resnet18实现CIFAR10数据分类
    CMake
    降水预报之双重惩罚
    BuyVM 拉斯维加斯 VPS 测评
    有哪些挣钱软件一天能赚几十元?盘点十个能长期做下去的挣钱软件
    jupyter notebook 中文本编辑快捷键
    这些项目管理实际问题,你遇到过几个
  • 原文地址:https://blog.csdn.net/zaizai1007/article/details/136168685