CG着色语言

# CG

# 什么是可编程图形处理单元

Programmable Graphics Processing Unit(GPU),可编程图形硬件。将数据绘制成图像。GPU具有高并行处理数据的能力,在处理图形数据和复杂算法方面拥有比CPU更高的性能。

GPU与CPU区别

# 发展阶段

  • 20世纪70年代末-1998成为Pre-GPU时期
  • 1998往后的称为现代GPU时期
    • 1998年第一代Modern GPU时期
    • 1999-2000年第二代Modern GPU时期
    • 2001年是第三代Modern GPU时期
    • 2002年末-2003年是第四代Modern GPU时期
    • 第四代GPU开始全面支持顶点着色器和片元着色器编程

# GPU图形绘制管线

图形绘制管线就是描述GPU渲染流程,即“给定视点,三维物体,光源、照明模式和纹理等元素,如何绘制一幅二维图像”。一般认为计算机图形绘制的整个管线流程包含三个主要阶段:应用程序阶段、几何阶段和光栅阶段。应用阶段主要和CPU、内存打交道,诸如碰撞检查、场景图建立、空间八叉树更新、视锥裁剪等算法都在这个阶段完成,在这个阶段末端将顶点的几何数据(顶点坐标、法向量,纹理坐标,纹理等)通过数据总线传送给图形硬件。几何阶段主要负责顶点坐标变换、光照、投影、裁剪以及屏幕映射,在该阶段末端得到了经过变换和投影之后的顶点坐标、颜色以及纹理坐标。光栅阶段是基于几何阶段的输出数据,为像素正确配色,以便绘制完整的图像,该阶段进行的是单个像素的操作,每个像素的信息存储在颜色缓冲器中。

# 顶点坐标变换有哪些坐标空间

模型坐标空间(object space)--->世界坐标系空间(world space)--->观察坐标空间(eye space)--->投影坐标空间(Project space)--->屏幕坐标空间(Clip space)

GPU处理流程

# 什么是视锥空间

以相机为原点,由视线方向、视角和远近平面共同组成一个梯形体的三维空间,称之为视锥空间。

视椎空间

# 从视点空间到屏幕空间大致包含哪些步骤

  • 用透视变换矩阵将顶点从视锥体中变换到裁剪空间中的CVV中。(CVV:规范立方体)
  • 在CVV中进行图元裁剪
  • 屏幕映射,将经过前面过程得到的坐标映射到屏幕坐标系中
  • 屏幕坐标加上Z轴就形成了窗口坐标系(视口坐标系)

# 裁剪算法主要包含哪些

为了减少需要绘制的顶点数,而识别指定区域内或者指定区域外图形部分的算法都成为裁剪算法。主要包括:

  • 视域剔除(view frustum culling)
  • 背面剔除(Back-face culling)
  • 遮挡剔除(Occlusing culling)
  • 视口裁剪

# 什么是光栅化?什么是光栅操作?光栅操作包含哪些

  • 光栅化:决定哪些像素会被图元集合所覆盖的过程
  • 光栅操作:是在更新帧缓冲之前,执行最后一系列针对每个片段的操作,计算出每个像素的颜色。光栅操作也成为像素操作
  • 光栅操作包含:
    • 消除遮挡面
    • 纹理操作,根据像素的纹理坐标查找对应的纹理值
    • Blending混色,根据目前已经画好的颜色,与正在计算颜色的透明度混合为两种颜色,作为新的输出颜色。通常称之为alpha混合技术
    • flitering将正在计算的某种颜色经过某个flitering后输出。可以理解为经过一种数学运算后得到新的颜色

# GPU存储架构

GPU存储架构

# 什么是Z-buffer和Z值

z-buffer即为深度缓冲depth buffer,存放的是视点到每个像素的距离衡量,成为Z值或者深度值。通过Z-buffer可以判断空间点的遮挡关系。Z值是非线性的,Z值精度不够,两个相距很近的物体会出现随机遮挡的现象,即面闪烁

# 顶点着色器和片元着色器的处理流程

顶点着色器和片元着色器流程

# 片段和像素有什么不同

片段就是所有的三维顶点在光栅化的数据集合,这些数据还没有经过深度值比较,而现实在屏幕上的像素是经过深度值检查的

# CG语言的重要特点有哪些

CG程序的编译不但依赖于宿主程序所使用的三维编程接口,而且依赖于图形硬件环境。被特定的图形硬件环境或API支持的CG语言子集,称为CG Profiles

# CG有哪些数据类型

CG支持7种基本数据类型:

  • float 32位浮点数,half 16位浮点数,fixed 11位浮点数,int 32位整型数据,bool 布尔型
  • string 字符串类型 sampler 纹理对象的句柄--sampler,sampler1D,sampler2D,sampler3D,samplerCUBE,samplerRECT
  • 内置向量数据类型 ,比如 float4, int4, bool4 等等。向量最长为4
  • 内置矩阵数据类型,比如 float 4X4 ,float 3X2 等等,最大支持4X4的矩阵
  • 数组类型,非内置的类型。比如 float a[4] ,float4X4 b[4]
  • 结构类型,比如
  sturct Test
  {
    float4 m={1,1,1,1}
  };
1
2
3
4
  • 绑定语义类型,比如POSITION(位置)、COLOR(颜色)、NORMAL(法向量),Texcoord(纹理坐标)
  • 接口类型

# CG有哪些操作符

关系操作符
逻辑操作符
数学操作符

位移操作符、Swizzle操作符和条件操作符

# 操作符的优先顺序如下

操作符的优先顺序

# 什么是输入输出与语义

  • in ,out, inout:表示函数的输入参数的传递方式

    in修饰一个形参只用于输入,进入函数体时被初始化,且该形参值的改变不会影响实参的值,这是典型的值传递。

    out修饰一个形参只用于输出,进入函数体时并没有被初始化,这种类型的形参一般是一个函数的运行结果。

    inout修饰形参既用于输入也用于输出,这是典型的引用传递。

  • uniform:用于指定变量数据的初始化方式

    CG语言将输入数据流分为两类:Varying inputs 和 Uniform inputs。

    前者表示数据流输入图元信息的各种组成要素,从应用程序到GPU的数据,除了顶点位置数据,还有顶点的法向量数据,纹理坐标数据等。CG提供了一组语义词来表明参数是由顶点的哪些数据初始化的。

    后者表示一些与三维渲染有关的离散信息数据,这些数据通常由应用程序传入,通常不会随图元的信息变化而变化。如材质对光的反射信息,运动矩阵等。

  • const:用于指定修饰的变量为常量变量

    语义是两个处理阶段(顶点程序和片段程序)输入输出数据和寄存器之间的桥梁,同时语义还表示数据的含义,如POSITION一般表示参数中存放的数据是顶点位置。

    语义只对两个处理阶段的输入输出数据有意义,也就是说语义只有在入口函数中才有效,在内部函数(一个阶段的内部处理函数,和下个阶段没有数据传递关系)无效,被忽略。

  • 顶点着色程序的输入语义

    POSITION:顶点位置坐标(通常在模型空间中),在OpenGL中对应为接受应用程序传递的顶点数据的寄存器。(四元向量)

    但DX10之后就推荐使用SV_POSITION作为vertex shader的输出和fragment shader的输入了,注意vertex shader的输入还是使用POSITION!切记

    但是DX10以后的代码依旧兼容POSITION作为全程表达,估计编译器会自动判断并替换的吧。

    NORMAL:顶点法向量坐标(通常位于模型空间中),在OpenGL中对应位接受应用程序传递的法向量数据的寄存器。(四元向量)

    TANGENT、BINORMAL、PSIZE、BLENDWEIGHT、BLENDINDICES、TEXCOORD0、TEXCOORD1、TEXCOORD2、TEXCOORD3、TEXCOORD4、TEXCOORD5、TEXCOORD6、TEXCOORD7。

    输入语义
  • 顶点着色程序的输出语义

    顶点程序的输出数据被传入到片段程序中,所以顶点着色程序的输出语义词,通常也是片段程序的输入语义词,不过语义词POSITION除外。

    POSITION、COLOR0-COLOR1、PSIZE、FOG、TEXCOORD0-TEXCOORD7适用于所有的顶点输出语义和片段输入语义。

    顶点着色程序必须申明一个输出变量,并绑定POSITION语义,该变量中的数据将被用于且只能被用于光栅化。如果没有申明一个绑定了POSITION语义词的输出变量,编译会出错。为了保持顶点程序输出语义和片段程序输入语义的一致性,通常使用相同的struct类型数据作为两者之间的传递。

  • 片段程序的输出语义

    片段程序的输出语义词比较少,通常只有COLOR。这是因为片段程序运行完毕基本就到了GPU流水线的末端了。片段程序必须申明一个out向量并绑定COLOR语义,这个值将被作为该片段的最终颜色值。

  • 语义绑定方法

    入口函数输入输出数据的绑定有4种方法:

    • 绑定语义放在函数参数列表的参数申明后面
    放在参数申明后面
    • 绑定语义词可以放在结构体成员的后面
    放在结构体成员后面
    • 绑定语义放在函数申明的后面
    放在函数的后面
    • 将绑定语义放在全局非静态变量申明的后面,这种形式很少用到

    在unity中,填充到POSITION,NORMAL这些语义的数据是从哪里来的呢?它们是由使用这个Shader的MeshRender组建提供的。在每帧调用DrawCall时,MeshRender组建会把它负责渲染的模型数据发送给Shader,在Shader中可以通过顶点着色器访问这些数据并做出相应变换处理。

# CG标准函数库

CG标准函数主要有5个部分:

  • 数学函数(Mathematical functions)
  • 几何函数(Geometric functions)
  • 纹理映射函数(Texture Map functions)
  • 偏导函数(Derivative functions)
  • 调试函数(Debugging functions)
数学函数1
数学函数2
数学函数3
数学函数4
数学函数5
数学函数6
数学函数7
几何函数
纹理映射函数1
纹理映射函数2
纹理映射函数3
偏导函数
上次更新: 2025/03/22, 13:47:44
最近更新
01
Git问题集合
01-29
02
安装 Nginx 服务器
01-25
03
安装 Docker 容器
01-25
更多文章>
×
×