Unity Shader 学习笔记—图形基础/CG语法
2017-12-22 本文已影响0人
不停雨
图形编程历史
渲染流水线
目前最新的可编程图形硬件支持功能:
- 支持顶点和片段的可编程能力
- 支持IEEE32位的浮点运算(IEEE32是国际电工委员会置顶的浮点书表示方式,主要内容是用四个字节来表示浮点数,可以表示的数据的负数范围是(-22)128~-2127,2^-127~22^128)
- 支持四元向量和四阶矩阵
- 提供分支和循环的控制语句
- 具有高带宽的内存处理能力
- 支持1D,2D,3D的纹理查询和使用能力,而且速度非常快
- 支持绘制到纹理功能
渲染流水线
-
含义
: 计算机需要从一系列的顶点数据、纹理等信息出发、生成(或者说渲染)一张二维图像的过程。 - 渲染流程分为三个阶段
-
应用程序阶段
:(CPU)-
准备数据
eg.摄像机的位置、�视椎体、场景中的模型和光源等等 -
culling
粗粒度剔除 eg.将不可见的物体剔除 -
输出
输出渲染所需的几何信息(点、线、三角面),即渲染图元
。
-
-
几何阶段
:(GPU)-
处理�渲染图元
进行逐顶点、逐多边形的操作。顶点坐标转换到屏幕空间。 -
输出
屏幕空间的二维顶点坐标、每个顶点对应的深度值、着色等相关信息。
-
-
光栅化阶段�
:(GPU)- 对上阶段的数据进行插值,再进行逐像素的处理。
-
CPU与GPU之间的通信
-
CPU�流水线
(即应用阶段)- 把数据加载到显存里
- 设置渲染状态
- 调用Draw Call(发起方是CPU,接收方是GPU)
-
GPU流水线
(即几何阶段和光栅化阶段)
[图片上传失败...(image-260204-1513936425700)] - �
顶点着色器
: 必选,可编程,通常用于实现顶点坐标的变换,�计算顶点颜色。 -
曲面细分着色器
:可选,用于细分图元。 -
几何着色器
:可选,用于逐图元的着色操作,或者用于产生更多的图元。 -
裁剪
: 可配置,将不是摄像机视野中的顶点裁剪掉。 -
屏幕映射
: 不可编程,不可配置。把每个图元的坐标转换到屏幕坐标系。 -
三角设置
和三角形遍历
阶段都是固定函数的阶段。 -
片元着色器
:可编程,用于�实现逐片元的着色操作。 -
逐片元操作
: 可配置,eg.颜色修改,深度缓,冲进行混合等。
三种语言:
- OpenGl的GLSL
- Direct3D的HLSL
- NVIDIA的CG(CG编写的可同时兼容�OpenGL和Direct平台)
GPU流水线的两个重要阶段
-
顶点着色器
- 输入: GPU前端模块提取图元信息(顶点位置,法线向量,纹理坐标(uv))等。
- 操作: 顶点坐标空间转换,法向量空间转换,光照计算等(现在光照计算一般在片段着色器,比较细),然后将计算好的数据传入指定寄存器中。
-
片元着色器
- 输入:顶点着色器传入的数据。
- 操作:光照计算,uv扰动,纹理采样等,最后输出当前片段的颜色给光栅化阶段(片段着色器是对每个独立的颜色进行操作的)。
数学基础
推荐《3D数学基础:图形与游戏开发》
CG语言基础
- CG语言的特性:
Cg是一种类C的语言,他沿用了大量的C语言特性,但是也有不同之处。Cg语言是脚本性语言,不能编译,调试和断点;并且Cg语言的主要用途是绘制像素颜色到屏幕上,他不能处理文字类的内容。Cg语言对单精度浮点的数据类型是非常敏感的;Cg语言因为GPU的并发特性所以导致Cg语言的所有执行过程是并发式的; - CG语法
- 基础数据类型 :
- float : 32位浮点数据
float _Angle = 1.0
- half : 16位浮点数据
half _Angle = 1.0
- int : 32位整形数据
int _Angle = 1
- fixed : 12位浮点数据
fixed _Angle = 1
- bool : �布尔数据,用于判断
if(_Angle == 0) { colors = diffuses.rgb; }
- Sampler 纹理对象,6类 : Sampler,sampler1D,sampler2D,sampler3D,samplerCUBE和samplerRECT
sample2D _Diffuse;
- float : 32位浮点数据
- 特殊的数据类型
- 向量 : 一共拥有4种维度的向量,1-4之间
float3 a = float3(0,1,2);
- 矩阵 : 行和列都不得大于4和不得小于1
float2*2 a = {sin@,0,1,3};
矩阵在赋值的时候一定要人为的分开行与行之间的关系,但是程序只认识顺序的赋值
- 数组 : 因为CG是显卡操作语,没有内存,所以声明的时候要制定大小
float2 b[2]; int arrayLen = b.length; // 结果是2 float m[3][4]; arrayLen = m.length;// 结果是3; arrayLen = m[1].length;// 结果是4;
- 结构体 : 数据封装作用
struct a2v { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; };
- 表达式和控制语句
- 关系操作符 :<,>,<=,>=,!=,==,
- 逻辑操作符 :&&,||,!
- 数学操作符 :+,—,*,/,%
- 移位操作符 :>>
int2 a = int2(0.0,0.0); int2 b = a>>1;
- Swizzle操作符:
float4(a, b, c, d).xyz 等价于 float3(a, b, c)
- 控制流语句 :if ,if-else while ,for,break
- 点操作�符:只针对向量和结构
v2f o; o.pos = UnityObjectToClipPos(v.vertex);
- 点操作�符:只针对向量和结构
- 行参修饰词:
- in: 表示当前行参是只能输入的;
- out:表示当前行参用来输出数据的;
- inout: 表示可以进行输入和输出;
- 离散数据图元信息:
uniform
- 只读性,只要标有uniform标签的变量,这个变量我们就不能初始化也不能修改其内容;
- 使用范围特性,只能存在于入口函数的行参上或者是全局的变量身上;
- 他只能支持引擎向着色器传入的数据,不能向外提交数据;
- 向量 : 一共拥有4种维度的向量,1-4之间
- 语义
[图片上传失败...(image-525f9a-1513936425700)]
- 基础数据类型 :