美文网首页
渲染原理

渲染原理

作者: APP4x | 来源:发表于2020-09-28 12:12 被阅读0次
    这是我在《游戏架构-核心技术与面试精粹》看的,记录一下~

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

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

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

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

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

    #pragma vertex vert
    struct v2f
    {
      float4 pos : SV_POSITION;
      fixed4 color : COLOR;
    };
    v2f vert (appdata_base v)
    {
      //vertex operation
    }
    

    每个顶点都会调用一次这个函数,并转化为这个函数的输出,这些输出被称为图元(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中会把函数返回值写为运算后的颜色

    fixed4 frag (v2f i) : SV_TARGET
    {
      //do framgent operation
    }
    

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

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

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

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

    AlphaTest Greater 0.5
    

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

    Stencil
    {
      Ref 2
      Comp equal
      Pass Keep
      ZFail decrWrap
    }
    
    //也就是,通过按位与的操作比较两侧结果
    
    if((RefValue & readMask) comparisonFunction (StencilBUfferValue * readMask))
    {
      pass;
    }
    else
    {
      discard;
    }
    

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

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

    Blend SrcAlpha OneMinusSrcAlpha
    

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

    ColorMask RG
    

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

    相关文章

      网友评论

          本文标题:渲染原理

          本文链接:https://www.haomeiwen.com/subject/hpcduktx.html