一、Cg基本数据类型

float 32位浮点数
half 16位浮点数
int 32位整型
fixed 12位定点数
bool 布尔数据
simpler* 纹理对象的句柄( the handle to a texture object ) ,分为 6 类:
sampler, sampler1D, sampler2D, sampler3D, samplerCUBE, 和 samplerRECT 
string 字符类型(几乎不使用)
例如float4,bool4等

向量数据类型,向量长度不能超过4元,可以有float1,float2,float3,float4,没有float5及以上

例如float4x4,float2x3等

矩阵数据类型,最大维数不超过4*4阶矩阵

计算机中的数除了整数之外,还有小数。如何确定小数点的位置呢?通常有两种方法:

一种是规定小数点位置固定不变,称为定点数。

另一种是小数点的位置不固定,可以浮动,称为浮点数。

在计算机中,通常是用定点数来表示整数和纯小数,分别称为定点整数和定点小数。对于既有整数部分、又有小数部分的数,一般用浮点数表示。

类型转换:
Cg 中的类型转换和 C 语言中的类型转换很类似。 C 语言中类型转换可以是强制类型转换,也可以是隐式转换,如果是后者,则数据类型从低精度向高精度转换。在 Cg 语言中也是如此。
float a = 1.0;  
half b = 2.0;  
float c = a+b; //等价于 float c = a + (float)b;

 
当有类型变量和无类型常量数据进行运算时,该常量数据不做类型转换,例如:
float a = 1.0;
 float b = a + 2.0; //2.0 为无类型常量数据,编译时作为 float 类型 
 

Cg 语言中对于常量数据可以加上类型后缀,表示该数据的类型,例如:

float a = 1.0;  
float b = a + 2.0h; //2.0h 为 half 类型常量数据,运算是需要做类型转换  
 

常量的类型后缀有3种:

f:表示float
h:表示half
x:表示fixed

二、数组

 数组数据类型在Cg中的作用:作为函数的形参,用于大量数据的传递,例如:顶点参数数组、光照参数数据等。
 
 一维数组:
float a[10];//声明了一个数组,包含 10 个 float 类型数据  
float a[4] = {1.0, 2.0, 3.0, 4.0}; //初始化一个数组  
int length = a.length;//获取数组长度  
 
多维数组:
float b[2][3] = {{0.0, 0.0, 0.0},{1.0, 1.0, 1.0}};  
int length1 = b.length; // length1 值为 2  
int length2 = b[0].length; // length2 值为 3  
 

三、结构体

结构体的声明以关键字 struct 开始,然后紧跟结构体的名字,接下来是一个大括号,并以分号结尾(不要忘了分号) 。大括号中是结构体的定义,分为两大类:成员变量和成员函数。例如:

struct myAdd

{

float val;

float add(float x)

{

return val + x;

}

};

myAdd s;

使用符号“.”引用结构体的成员变量和成员函数:

float a = s.value;

float b = s.add(a);

一般来说 ,Cg 的源代码都会在文件首部定义二个结构体,分别用于定义输人和输出的类型,这二个结构体定义与普通的 C 结构定义不同,除了定义结构体成员的数据类型外,还定义了该成员的绑定语义类型( Binding Semantics) ,所谓绑定语义类型是为了与宿主环境进行数据交换的时候识别不同数据类型的。 目前Cg 支持的绑定语义类型包括 POSTION 位置 ) , COLOR( 颜色 ) , NORMAL( 法向量 ) , Texcoord( 纹理坐标 ) 等类型。

四、Cg语言操作符

1、关系操作符

<

小于

<=

小于或等于

!=

不等于

==

等于

>=

大于或等于

>

大于

2、逻辑操作符

&&

逻辑与

||

逻辑或

!

逻辑非

3、数学操作符

* 乘法; / 除法; - 取反; + 加法;- 减法; % 求余; ++ ;--; *= ; /= ; += ; -= ;

需要注意的是:求余操作符 % 。只能在 int 类型数据间进行

4、移位操作符

Cg 语言中的移位操作符,功能和 C 语言中的一样,也可以作用在向量上,但是向量类型必须是 int 类型。例如:

int2 a = int2(0.0,0.0);

int2 b = a>>1;

5、Swizzle 操作符

可以使用 Cg 语言中的 swizzle 操作符( . )将一个向量的成员取出组成一个新的向量。 swizzle 操作符被 GPU 硬件高效支持。 swizzle 操作符后接 x 、 y 、 z 、 w ,分别表示原始向量的第一个、第二个、第三个、第四个元素; swizzle操作符后接 r 、 g 、 b 和 a 的含义与前者等同。不过为了程序的易读性,建议对于表示颜色值的向量,使用 swizzle 操作符后接 r 、 g 、 b 和 a 的方式。

举例如下:

float4(a, b, c, d).xyz    等价于   float3(a, b, c)

float4(a, b, c, d).xyy    等价于   float3(a, b, b)

float4(a, b, c, d).wzyx   等价于   float4(d, c, b, a)

float4(a, b, c, d).w      等价于   float d

值得注意的是, Cg 语言中 float a 和 float1 a 是基本等价的,两者可以进行类型转换; float 、 bool 、 half 等基本类型声明的变量也可以使用 swizzle 操作符。例如:

float a = 1.0;

float4 b = a.xxxx;

注意: swizzle 操作符只能对结构体和向量使用,不能对数组使用,如果对数组使用 swizzle 操作符则会出现错误信息: error C1010: expression left of . ” x ” is not a struct or array (其实个人觉得,提示的错误信息中 array 换成vector 更加合适)。

要从数组中取值必须使用 [] 符号。例如:

float a[3] = {1.0,1.0,0.0};

float b = a[0]; // 正确

float c = a.x; // 编译会提示错误信息

6、条件操作符

条件操作符的语法格式为: expr1 ? expr2 : expr3;

expr1 的计算结果为 true 或者 flase ,如果是 true, 则 expr2 执行运算,否则 expr3 被计算。

五、控制流语句

条件语句有: if 、 if-else ;循环语句有: while 、 for 。 break 语句可以和在 for 语句中使用。

六、函数

1、入口函数

由于着色程序分为顶点程序和片段程序,两者对应的图形流水线上的不同阶段,所以这两个程序都各有一个入口函数。

struct C2E1v_Output {

float4 position : POSITION;

float3 color    : COLOR;

};

C2E1v_Output C2E1v_green(float2 position : POSITION)

{

C2E1v_Output OUT;

OUT.position = float4(position,0,1);

OUT.color = float3(0,1,0);

 return OUT;

}

2、Cg标准函数库
数学函数
abs(x) 返回输入参数的绝对值
acos(x) 反余切函数,输入参数范围为[-1,1], 返回[0,π]区间的角度值
all(x) 如果输入参数均不为0,则返回ture; 否则返回flase。&&运算
any(x) 输入参数只要有其中一个不为0,则返回true。
asin(x) 反正弦函数,输入参数取值区间为[−1,1],返回角度值范围为, [−π2,π2]
atan(x) 反正切函数,返回角度值范围为[−π2,π2]
atan2(y,x) 计算y/x的反正切值。实际上和atan(x)函数功能完全一样,至少输入参数不同。atan(x) = atan2(x, float(1))。
ceil(x) 对输入参数向上取整。例如: ceil(float(1.3)) ,其返回值为2.0
clamp(x,a,b) 如果x值小于a,则返回a;
如果x值大于b,返回b;
否则,返回x。
cos(x) 返回弧度x的余弦值。返回值范围为[−1,1]
cosh(x) 双曲余弦(hyperbolic cosine)函数,计算x的双曲余弦值。
cross(A,B) 返回两个三元向量的叉积(cross product)。注意,输入参数必须是三元向量!
degrees(x) 输入参数为弧度值(radians),函数将其转换为角度值(degrees)
determinant(m) 计算矩阵的行列式因子。
dot(A,B) 返回A和B的点积(dot product)。参数A和B可以是标量,也可以是向量(输入参数方面,点积和叉积函数有很大不同)。
exp(x) 计算ex的值,e=2.71828182845904523536
exp2(x) 计算2x的值
floor(x) 对输入参数向下取整。例如floor(float(1.3))返回的值为1.0;但是floor(float(-1.3))返回的值为-2.0。该函数与ceil(x)函数相对应。
fmod(x,y) 返回x/y的余数。如果y为0,结果不可预料。
frac(x) 返回标量或矢量的小数
frexp(x, out i) 将浮点数x分解为尾数和指数,即x=m∗2i, 返回m,并将指数存入i中;如果x为0,则尾数和指数都返回0
isfinite(x) 判断标量或者向量中的每个数据是否是有限数,如果是返回true;否则返回false;
isinf(x) 判断标量或者向量中的每个数据是否是无限,如果是返回true;否则返回false;
isnan(x) 判断标量或者向量中的每个数据是否是非数据(not-a-number NaN),如果是返回true;否则返回false;
ldexp(x, n) 计算x∗2n的值
lerp(a, b, f) 计算(1−f)∗a+b∗f或者a+f∗(b−a)的值。即在下限a和上限b之间进行插值,f表示权值。注意,如果a和b是向量,则权值f必须是标量或者等长的向量。
lit(NdotL, NdotH, m) N表示法向量;
L表示入射光向量;
H表示半角向量;
m表示高光系数。 
函数计算环境光、散射光、镜面光的贡献,返回的4元向量。 
X位表示环境光的贡献,总是1.0; 
Y位代表散射光的贡献,如果 N∙L<0,则为0;否则为N∙L 
Z位代表镜面光的贡献,如果N∙L<0 或者N∙H<0,则位0;否则为(N∙L)m;
W位始终位1.0
log(x) 计算ln(x)的值,x必须大于0
log2(x) 计算log(x)2的值,x必须大于0
log10(x) 计算log(x)10的值,x必须大于0
max(a, b) 比较两个标量或等长向量元素,返回最大值。
min(a,b) 比较两个标量或等长向量元素,返回最小值。
modf(x, out ip) 把x分解成整数和分数两部分,每部分都和x有着相同的符号,整数部分被保存在ip中,分数部分由函数返回
mul(M, N) 矩阵M和矩阵N的积
mul(M, v) 矩阵M和列向量v的积
mul(v, M) 行向量v和矩阵M的积
noise(x) 根据它的参数类型,这个函数可以是一元、二元或三元噪音函数。返回的值在0和1之间,并且通常与给定的输入值一样
pow(x, y) xy
radians(x) 函数将角度值转换为弧度值
round(x) 返回四舍五入值。
rsqrt(x) x的平方根的倒数,x必须大于0
saturate(x) 把x限制到[0,1]之间
sign(x) 如果x>0则返回1;否则返回0
sin(x) 输入参数为弧度,计算正弦值,返回值范围 为[-1,1]
sincos(float x, out s, out c) 该函数是同时计算x的sin值和cos值,其中s=sin(x),c=cos(x)。该函数用于“同时需要计算sin值和cos值的情况”,比分别运算要快很多!
sinh(x) 计算x的双曲正弦
smoothstep(min, max, x) 值x位于min、max区间中。如果x=min,返回0;如果x=max,返回1;如果x在两者之间,按照下列公式返回数据:
−2∗(x−minmax−min)3+3∗(x−minmax−min)2
step(a, x) 如果x<a,返回0;否则,返回1
sqrt(x) 求x的平方根,x√,x必须大于0
tan(x) 计算x正切值
tanh(x) 计算x的双曲线切线
transpose(M) 矩阵M的转置矩阵
如果M是一个AxB矩阵,M的转置是一个BxA矩阵,它的第一列是M的第一行,第二列是M的第二行,第三列是M的第三行,等等
几何函数
distance(pt1, pt2) 两点之间的欧几里德距离(Euclidean distance)
faceforward(N,I,Ng) 如果Ng∙I<0,返回N;否则返回-N。
length(v) 返回一个向量的模,即sqrt(dot(v,v))
normalize(v) 返回v向量的单位向量
reflect(I, N) 根据入射光纤方向I和表面法向量N计算反射向量,仅对三元向量有效
refract(I,N,eta) 根据入射光线方向I,表面法向量N和折射相对系数eta,计算折射向量。如果对给定的eta,I和N之间的角度太大,返回(0,0,0)。
只对三元向量有效

关于几何函数需要注意以下两点:

1、着色程序中的向量最好进行归一化之后再使用,否则会出现难以预料的 错误;

2、reflect 函数和 refract 函数都存在以“入射光方向向量”作为输入参数, 注意这两个函数中使用的入射光方向向量,是从外指向几何顶点的;平时我 们在着色程序中都是将入射光方向向量作为从顶点出发的。

纹理映射函数
tex1D(sampler1D tex, float s) 一维纹理查询
tex1D(sampler1D tex, float s, float dsdx, float dsdy) 使用导数值(derivatives)查询一维纹理
Tex1D(sampler1D tex, float2 sz) 一维纹理查询,并进行深度值比较
Tex1D(sampler1D tex, float2 sz, float dsdx,float dsdy) 使用导数值(derivatives)查询一维纹理, 并进行深度值比较
Tex1Dproj(sampler1D tex, float2 sq) 一维投影纹理查询
Tex1Dproj(sampler1D tex, float3 szq) 一维投影纹理查询,并比较深度值
Tex2D(sampler2D tex, float2 s) 二维纹理查询
Tex2D(sampler2D tex, float2 s, float2 dsdx, float2 dsdy) 使用导数值(derivatives)查询二维纹理
Tex2D(sampler2D tex, float3 sz) 二维纹理查询,并进行深度值比较
Tex2D(sampler2D tex, float3 sz, float2 dsdx,float2 dsdy) 使用导数值(derivatives)查询二维纹理,并进行深度值比较
Tex2Dproj(sampler2D tex, float3 sq) 二维投影纹理查询
Tex2Dproj(sampler2D tex, float4 szq) 二维投影纹理查询,并进行深度值比较
texRECT(samplerRECT tex, float2 s) 二维非投影矩形纹理查询(OpenGL独有)
texRECT (samplerRECT tex, float3 sz, float2 dsdx,float2 dsdy) 二维非投影使用导数的矩形纹理查询(OpenGL独有)
texRECT (samplerRECT tex, float3 sz) 二维非投影深度比较矩形纹理查询(OpenGL独有)
texRECT (samplerRECT tex, float3 sz, float2 dsdx,float2 dsdy) 二维非投影深度比较并使用导数的矩形纹理查询(OpenGL独有)
texRECT proj(samplerRECT tex, float3 sq) 二维投影矩形纹理查询(OpenGL独有)
texRECT proj(samplerRECT tex, float3 szq) 二维投影矩形纹理深度比较查询(OpenGL独有)
Tex3D(sampler3D tex, float s) 三维纹理查询
Tex3D(sampler3D tex, float3 s, float3 dsdx, float3 dsdy) 结合导数值(derivatives)查询三维纹理
Tex3Dproj(sampler3D tex, float4 szq) 查询三维投影纹理,并进行深度值比较
texCUBE(samplerCUBE tex, float3 s) 查询立方体纹理
texCUBE (samplerCUBE tex, float3 s, float3 dsdx, float3 dsdy) 结合导数值(derivatives)查询立方体纹理
texCUBEproj (samplerCUBE tex, float4 sq) 查询投影立方体纹理

所有这些函数返回四元向量值

s:一元、二元、三元纹理坐标

z:使用深度比较的值

q:一个透视值(其实就是透视投影后得到的齐次坐标的最后一位),这个值被用来除以纹理坐标(s),得到新的纹理坐标(已归一化)然后用于纹理查询

偏导函数
ddx(a) 近似a关于屏幕空间x轴的偏导数
ddy(a) 近似a关于屏幕空间y轴的偏导数
  1. 函数 ddx和ddy用于求取相邻像素间 属性的差值;

  2. 函数 ddx和ddy的输入参数通常是纹理坐标;

  3. 函数 ddx和ddy返回相邻像素键的属性差值;

调试函数
void debug(float4 x) 如果在编译时设置了DEBUG,片段着 色程序中调用该函数可以将值x作为COLOR语义的最终输出;否则该函数什么也不做。

这个函数写到这里只是表示有这么一个函数,实际上这个函数并不能帮助我们多少。

Unity Shader (二)Cg语言的更多相关文章

  1. 【Unity Shader】---CG标准函数库

    1.CG标准函数库 和C的标准函数库类似,CG也提供了一系列的内建函数库,这些函数用于计算数学上的通用计算或算法(如纹理映射).例如:求取入射光线的反射光线用Reflect函数,求折射光线用Refla ...

  2. 【我的书】Unity Shader的书 — 文件夹(2015.12.21更新)

    写在前面 感谢全部点进来看的朋友.没错.我眼下打算写一本关于Unity Shader的书. 出书的目的有以下几个: 总结我接触Unity Shader以来的历程,给其它人一个借鉴.我非常明确学Shad ...

  3. 【我的书】Unity Shader的书 — 目录(2016.5.19最后一次更新)

    写在前面 感谢所有点进来看的朋友.没错,我目前打算写一本关于Unity Shader的书. 出书的目的有下面几个: 总结我接触Unity Shader以来的历程,给其他人一个借鉴.我非常明白学Shad ...

  4. Unity Shader基础

    Unity Shader基础 先上代码,代码一般是这样的. void Initialization(){ //先从硬盘加载代码再加载到GPU中 string vertexShaderCode = Lo ...

  5. 第二章 Unity Shader基础

    [TOC] 1. Unity Shader 的基础: ShaderLab 学习和编写着色器的过程一直是一个学习曲线很陡峭的过程,通常情况下为了自定义渲染效果往往要和很多文件和设置打交道,这些设置很容易 ...

  6. 【Unity Shader】Shader基础

    目录 Chapter3 Unity Shader 基础 Chapter3 Unity Shader 基础 概述 在Unity需要材质(Material)与Unity Shader配合使用来达到满意的效 ...

  7. 【Unity Shader】---UnityShader 提供的CG/HLSL语义

    一.语义的解释 语义,其实就是一个赋给Shader输入和输出的字符串,这个字符串表达了这个参数的含义.通俗的讲这些语义可以让Shader知道从哪读取输送到哪里去,他们是在CG/HLSL的shader流 ...

  8. 解读Unity中的CG编写Shader系列八(镜面反射)

    转自http://www.itnose.net/detail/6117378.html 讨论完漫反射之后,接下来肯定就是镜面反射了 在开始镜面反射shader的coding之前,要扩充一下前面提到的知 ...

  9. Unity Shader 知识点总结(二)

    紧接着上一篇文章的shader入门知识的总结,本文主要总结shader中的纹理贴图.透明度混合.顶点动画.后期特效处理等操作.如果有什么地方有错,请指出更正,谢谢.本文的代码主要来自开源书:unity ...

随机推荐

  1. 关于PageRank的总结

    好久不用CSDN,最近想给带的本科生实验课开个期末习题专题页,发现CSDN的博客忽然要绑定之类.只好弃用回博客园写学习总结了.塞翁失马焉知非福. *************************** ...

  2. Android 实现下拉刷新和上拉加载更多的RECYCLERVIEW和SCROLLVIEW

    PullRefreshRecyclerView.java /** * 类说明:下拉刷新上拉加载更多的RecyclerView * Author: gaobaiq * Date: 2016/5/9 18 ...

  3. IOS设备获取崩溃日志的办法

    除了用xcode 的devices功能获取之外,在windows下面也是可以获取的.首先安装itools.下载地址: http://www.itools.cn/ 安装好后将设备(iphone或ipad ...

  4. 【原创】Google的文本内容对比代码

    /* * Diff Match and Patch * * Copyright 2006 Google Inc. * http://code.google.com/p/google-diff-matc ...

  5. 记我安装Caffe的血泪史(2)

    不知不觉居然花了一个星期来安装Caffe...真是醉了. 接上一篇blog,本以为编译完cuda,opencv之后问题就差不多了(其实本来是没有什么问题的,但硬是被我搞了一堆事情出来....) 出于对 ...

  6. SpringCloud学习笔记(3)----Spring Cloud Netflix之深入理解Eureka

    1. Eureka服务端的启动过程 1.1  入口类EurekaServerInitializerConfiguration类, public void start() { (new Thread(n ...

  7. 一、数组---数组中的K-diff数对※※※※※

    给定一个整数数组和一个整数 k, 你需要在数组里找到不同的 k-diff 数对.这里将 k-diff 数对定义为一个整数对 (i, j), 其中 i 和 j 都是数组中的数字,且两数之差的绝对值是 k ...

  8. 批量删除harbor中的镜像

    一 说明 这个是我第一篇博客,所以我想放上原创的东西,尽管我一直都很担心自己写得太low,但是总要学会尝试,学会改变自己,相信自己.在写这个脚本时,由于我接触LInux不是很多,能力有限,仅仅是为了让 ...

  9. TODOList 多线程交互、RCP、事物控制、数据倾斜、HBase数据同步性

    TODOList 多线程交互.RCP.事物控制.数据倾斜.HBase数据同步性 TODO List thread.join()如何互相之间通知? 线程池何时最后运行完成? MemCache性能要优于R ...

  10. C++ Primer笔记13_运算符重载_总结

    总结: 1.不能重载的运算符: . 和 .* 和 ?: 和 ::  和 sizeof 和 typeid 2.重载运算符有两种基本选择: 类的成员函数或者友元函数, 建议规则例如以下: 运算符 建议使用 ...