Unity Shader (二)Cg语言
一、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 语言中对于常量数据可以加上类型后缀,表示该数据的类型,例如:
常量的类型后缀有3种:
二、数组
三、结构体
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轴的偏导数 |
函数 ddx和ddy用于求取相邻像素间 属性的差值;
函数 ddx和ddy的输入参数通常是纹理坐标;
函数 ddx和ddy返回相邻像素键的属性差值;
调试函数
| void debug(float4 x) | 如果在编译时设置了DEBUG,片段着 色程序中调用该函数可以将值x作为COLOR语义的最终输出;否则该函数什么也不做。 |
这个函数写到这里只是表示有这么一个函数,实际上这个函数并不能帮助我们多少。
Unity Shader (二)Cg语言的更多相关文章
- 【Unity Shader】---CG标准函数库
1.CG标准函数库 和C的标准函数库类似,CG也提供了一系列的内建函数库,这些函数用于计算数学上的通用计算或算法(如纹理映射).例如:求取入射光线的反射光线用Reflect函数,求折射光线用Refla ...
- 【我的书】Unity Shader的书 — 文件夹(2015.12.21更新)
写在前面 感谢全部点进来看的朋友.没错.我眼下打算写一本关于Unity Shader的书. 出书的目的有以下几个: 总结我接触Unity Shader以来的历程,给其它人一个借鉴.我非常明确学Shad ...
- 【我的书】Unity Shader的书 — 目录(2016.5.19最后一次更新)
写在前面 感谢所有点进来看的朋友.没错,我目前打算写一本关于Unity Shader的书. 出书的目的有下面几个: 总结我接触Unity Shader以来的历程,给其他人一个借鉴.我非常明白学Shad ...
- Unity Shader基础
Unity Shader基础 先上代码,代码一般是这样的. void Initialization(){ //先从硬盘加载代码再加载到GPU中 string vertexShaderCode = Lo ...
- 第二章 Unity Shader基础
[TOC] 1. Unity Shader 的基础: ShaderLab 学习和编写着色器的过程一直是一个学习曲线很陡峭的过程,通常情况下为了自定义渲染效果往往要和很多文件和设置打交道,这些设置很容易 ...
- 【Unity Shader】Shader基础
目录 Chapter3 Unity Shader 基础 Chapter3 Unity Shader 基础 概述 在Unity需要材质(Material)与Unity Shader配合使用来达到满意的效 ...
- 【Unity Shader】---UnityShader 提供的CG/HLSL语义
一.语义的解释 语义,其实就是一个赋给Shader输入和输出的字符串,这个字符串表达了这个参数的含义.通俗的讲这些语义可以让Shader知道从哪读取输送到哪里去,他们是在CG/HLSL的shader流 ...
- 解读Unity中的CG编写Shader系列八(镜面反射)
转自http://www.itnose.net/detail/6117378.html 讨论完漫反射之后,接下来肯定就是镜面反射了 在开始镜面反射shader的coding之前,要扩充一下前面提到的知 ...
- Unity Shader 知识点总结(二)
紧接着上一篇文章的shader入门知识的总结,本文主要总结shader中的纹理贴图.透明度混合.顶点动画.后期特效处理等操作.如果有什么地方有错,请指出更正,谢谢.本文的代码主要来自开源书:unity ...
随机推荐
- Codeforces 845C. Two TVs 思路:简单贪心算法
题目: 题目原文链接:http://codeforces.com/contest/845/problem/C 题意:现在我们有一个电视清单,有两个电视,电视清单上有每一个节目的开始时间和结束时间. 电 ...
- javaEE的开发模式
1.什么是模式 模式在开发过程中总结出的“套路”,总结出的一套约定俗成的设计模式 2.javaEE经历的模式 model1模式: 技术组成:jsp+javaBean model1的弊端:随着业务复杂性 ...
- windows下mysql解压版安装及centos下mysql root密码忘记
windows安装 1. 下载zip版的解压后将bin添加到path. 2. 修改解压目录D:\mysql\mysql-5.7.12-winx64下的my.ini,设置路径: 还要添加 [client ...
- shell-3.bash的基本功能:通配符和其他特殊字符
1. 2.
- PHP————系统常量
PHP常量默认为大小写敏感.传统上常量标识符总是大写的. PHP常量名和其它任何 PHP 标签遵循同样的命名规则.合法的常量名以字母或下划线开始,后面跟着任何字母,数字或下划线.用正则表达式是这样表达 ...
- 贰、js的基础(一)
1.js的语法 a.区分大小写 b.弱类型变量:变量无特定类型 c.每行结尾的分号可有可无 d.括号用于代码块 e.注释的方法与c语言和java相同 2.变量 注意事项: a.通过关键字var来声明. ...
- Mint-UI 没有样式?
如果用mint-ui组件,如toast没有样式,是因为没有映入全局样式和导入MintUI 方法如下: 1.安装 npm install mint-ui -S -S表示 --save 2.在main.j ...
- BZOJ 2565 最长双回文串(回文自动机)
题意 给一个长度为N的字符串S.对于一个字符串AB,如果A和B都是回文串,那么称AB是一个双回文串.求问S最长双回文子串的长度?N <= 100000 题解 正反双向构造回文自动机,得到某一个点 ...
- [NOIP2015普及组]推销员
题目:洛谷P2672.codevs5126.Vijos P1977 题目大意:有个推销员要去推销,要你求他推销1~n户人家分别最多花多少“疲劳值”.具体见题目. 解题思路:如果用$O(n^2)$做的话 ...
- python 面向对象 继承
什么是继承 继承表达的是一种”是“的关系,比如人是动物 继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类 继承是基于抽象的结 ...