目录
1、引言
上一篇我们讲述了基本数据,这里我们主要讲解数据类型和Swizzle操作,涉及的知识点如下:
- 向量
- Swizzle操作
- 矩阵
- 数组
- 结构体
2、演示
这里我们对上面的知识点进行一一举例说明。
2.1、布尔(bool)类型
Cg中bool的使用方式:
bool [变量名] = [值]
eg:下面一段程序,运行后变成绿色
SubShader
{
Pass
{
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR0)
{
pos = float4(objPos,0,1);
col = pos;
}
void frag(inout float4 col:COLOR0)
{
col = float4(1,1,0,1);
bool b = false;
col = b ? float4(1,0,0,1) : float4(0,1,0,1);
}
ENDCG
}
}
效果:
2.2、int
Cg中的int会被当做float使用,这里就不再演示了。
2.3、sampler
sampler有有以下几种扩展:
sampler
sampler2D 表示一种2d纹理
sampler3D 表示一种3d纹理
samplerCUBE 表示一种类似天空盒子的纹理(一般用作天空盒子)
sampler这里不做详细说明,后面我们再次讲解。
2.4、向量
以上这里的基本数据类型都可以组合为基本类型的向量。形如如下:
Shader "lxt610/NewSurfaceShaderTest" {
SubShader
{
Pass
{
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR0)
{
pos = float4(objPos,0,1);
col = pos;
}
void frag(inout float4 col:COLOR0)
{
col = float4(1,1,0,1);
bool b = false;
col = b ? float4(1,0,0,1) : float4(0,1,0,1);
}
bool2 b12 = bool2(true,false);
bool3 b13 = bool3(true,false,false);
bool4 b14 = bool4(true,false,false,true);
int2 i12 = int2(1,0);
int3 i13 = int3(1,0,1);
int4 i14 = int4(1,0,0,1);
float2 f12 = float2(1,0);
float3 f13 = float3(1,0,1);
float4 f14 = float4(1,0,0,1);
int
// int
ENDCG
}
}
}
这里需要注意的是Cg当中向量的最大维度是4,不能超过4否则是错误的!
2.5、Swizzle操作
当使用Swizzle操作组合变量时,可以使用xyzw或者rgba但是二者只可以使用一种,不能混合使用!
eg:
Shader "lxt610/NewSurfaceShaderTest" {
SubShader
{
Pass
{
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR0)
{
pos = float4(objPos,0,1);
col = pos;
}
void frag(inout float4 col:COLOR0)
{
col = float4(1,1,0,1);
bool b = false;
col = b ? float4(1,0,0,1) : float4(0,1,0,1);
bool2 b12 = bool2(true,false);
bool3 b13 = bool3(true,false,false);
bool4 b14 = bool4(true,false,false,true);
int2 i12 = int2(1,0);
int3 i13 = int3(1,0,1);
int4 i14 = int4(1,0,0,1);
float2 f12 = float2(1,0);
float3 f13 = float3(1,0,1);
float4 f14 = float4(1,0,0,1);
//swizzle
float4 ff1 = float4(f12.xy,1,0);
float4 ff2 = float4(f12.yx,0,0);
float4 ff3 = float4(f14);
float4 ff4 = float4(f14.xxxx);
float4 ff5 = float4(f14.xyzw);
float4 ff6 = float4(f14.wzxy);
float4 ff7 = float4(f14.xz,1,0);//可以通过swizzle操作,随意组合
float4 ff8 = float4(f14.rgba);//也可以通过rgba进行swizzle操作,随意组合
//float4 ff9 = float4(f14.rgb,f14.z);//错误的
}
ENDCG
}
}
}
2.6、使用别名
我们可以使用别名来声明变量,采用形如:
typedef [变量类型] 别名名称
别名名称 变量名 = [值]
Shader "lxt610/NewSurfaceShaderTest" {
SubShader
{
Pass
{
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
//使用别名
typedef float4 fff;
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR0)
{
pos = float4(objPos,0,1);
col = pos;
}
void frag(inout float4 col:COLOR0)
{
col = float4(1,1,0,1);
bool b = false;
col = b ? float4(1,0,0,1) : float4(0,1,0,1);
bool2 b12 = bool2(true,false);
bool3 b13 = bool3(true,false,false);
bool4 b14 = bool4(true,false,false,true);
int2 i12 = int2(1,0);
int3 i13 = int3(1,0,1);
int4 i14 = int4(1,0,0,1);
float2 f12 = float2(1,0);
float3 f13 = float3(1,0,1);
float4 f14 = float4(1,0,0,1);
//swizzle
float4 ff1 = float4(f12.xy,1,0);
float4 ff2 = float4(f12.yx,0,0);
float4 ff3 = float4(f14);
float4 ff4 = float4(f14.xxxx);
float4 ff5 = float4(f14.xyzw);
float4 ff6 = float4(f14.wzxy);
float4 ff7 = float4(f14.xz,1,0);//可以通过swizzle操作,随意组合
float4 ff8 = float4(f14.rgba);//也可以通过rgba进行swizzle操作,随意组合
//使用别名
fff ff9 = float4(ff7.rrrr);
}
ENDCG
}
}
}
2.7、宏定义
我们可像c语言一样使用宏定义来定义变量!
语法形如:
#define [宏定义变量名] [值];
Shader "lxt610/NewSurfaceShaderTest" {
SubShader
{
Pass
{
CGPROGRAM
#pragma fragment frag
#pragma vertex vert
//宏定义 这里使用了别名
#define DIYCOLOR fff(ff7.rrrr);
typedef float4 fff;
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR0)
{
pos = float4(objPos,0,1);
col = pos;
}
void frag(inout float4 col:COLOR0)
{
col = float4(1,1,0,1);
bool b = false;
col = b ? float4(1,0,0,1) : float4(0,1,0,1);
bool2 b12 = bool2(true,false);
bool3 b13 = bool3(true,false,false);
bool4 b14 = bool4(true,false,false,true);
int2 i12 = int2(1,0);
int3 i13 = int3(1,0,1);
int4 i14 = int4(1,0,0,1);
float2 f12 = float2(1,0);
float3 f13 = float3(1,0,1);
float4 f14 = float4(1,0,0,1);
//swizzle
float4 ff1 = float4(f12.xy,1,0);
float4 ff2 = float4(f12.yx,0,0);
float4 ff3 = float4(f14);
float4 ff4 = float4(f14.xxxx);
float4 ff5 = float4(f14.xyzw);
float4 ff6 = float4(f14.wzxy);
float4 ff7 = float4(f14.xz,1,0);//可以通过swizzle操作,随意组合
float4 ff8 = float4(f14.rgba); //也可以通过rgba进行swizzle操作,随意组合
//宏定义
fff ff9 = DIYCOLOR //上面定义宏的时候使用了分号,这里的分号可以省略
}
ENDCG
}
}
}
2.8、矩阵
m行n列矩阵,cg中支持矩阵最大是4x4的。eg:
Shader "lxt610/NewSurfaceShaderTest" {
SubShader
{
Pass
{
CGPROGRAM
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices
#pragma exclude_renderers gles
#pragma fragment frag
#pragma vertex vert
//宏定义 这里使用了别名
#define DIYCOLOR fff(ff7.rrrr);
typedef float4 fff;
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR0)
{
pos = float4(objPos,0,1);
col = pos;
}
void frag(inout float4 col:COLOR0)
{
col = float4(1,1,0,1);
bool b = false;
col = b ? float4(1,0,0,1) : float4(0,1,0,1);
bool2 b12 = bool2(true,false);
bool3 b13 = bool3(true,false,false);
bool4 b14 = bool4(true,false,false,true);
int2 i12 = int2(1,0);
int3 i13 = int3(1,0,1);
int4 i14 = int4(1,0,0,1);
float2 f12 = float2(1,0);
float3 f13 = float3(1,0,1);
float4 f14 = float4(1,0,0,1);
//swizzle
float4 ff1 = float4(f12.xy,1,0);
float4 ff2 = float4(f12.yx,0,0);
float4 ff3 = float4(f14);
float4 ff4 = float4(f14.xxxx);
float4 ff5 = float4(f14.xyzw);
float4 ff6 = float4(f14.wzxy);
float4 ff7 = float4(f14.xz,1,0);//可以通过swizzle操作,随意组合
float4 ff8 = float4(f14.rgba);//也可以通过rgba进行swizzle操作,随意组合
//宏定义
fff ff9 = DIYCOLOR //上面定义宏的时候使用了分号,这里的分号可以省略
//矩阵
float2x2 m0m2x2 = {1,0,0,1}; //m行n列的矩阵
float2x4 m1m2x4 = {0,0,1,1, 0,1,0,1}; //2行4列的矩阵
col = m1m2x4[0]; //这里取的是第一行,是蓝色
float2x4 m2m2x4 = {{0,0,1,1}, {0,1,0,1}}; //2行4列的矩阵
float2x4 m3m2x4 = {{ff5}, {0,1,0,1}}; //2行4列的矩阵
float2x4 m4m2x4 = {ff5, {0,1,0,1}}; //2行4列的矩阵
float2x4 m5m2x4 = {ff5, 0,1,0,1}; //2行4列的矩阵 这些形式都是可以的
float2x4 m6m2x4 = {ff5.rgba, 0,1,0,1}; //2行4列的矩阵 这些形式都是可以的
col = m3m2x4[0];
}
ENDCG
}
}
}
2.9、数组
Cg中的也是支持数组的。语法格式如下:
数组类型 数组名[数组长度] = {值,值,值…}
eg:
Shader "lxt610/NewSurfaceShaderTest" {
SubShader
{
Pass
{
CGPROGRAM
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices
#pragma exclude_renderers gles
#pragma fragment frag
#pragma vertex vert
//宏定义 这里使用了别名
#define DIYCOLOR fff(ff7.rrrr);
typedef float4 fff;
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR0)
{
pos = float4(objPos,0,1);
col = pos;
}
void frag(inout float4 col:COLOR0)
{
col = float4(1,1,0,1);
bool b = false;
col = b ? float4(1,0,0,1) : float4(0,1,0,1);
bool2 b12 = bool2(true,false);
bool3 b13 = bool3(true,false,false);
bool4 b14 = bool4(true,false,false,true);
int2 i12 = int2(1,0);
int3 i13 = int3(1,0,1);
int4 i14 = int4(1,0,0,1);
float2 f12 = float2(1,0);
float3 f13 = float3(1,0,1);
float4 f14 = float4(1,0,0,1);
//swizzle
float4 ff1 = float4(f12.xy,1,0);
float4 ff2 = float4(f12.yx,0,0);
float4 ff3 = float4(f14);
float4 ff4 = float4(f14.xxxx);
float4 ff5 = float4(f14.xyzw);
float4 ff6 = float4(f14.wzxy);
float4 ff7 = float4(f14.xz,1,0);//可以通过swizzle操作,随意组合
float4 ff8 = float4(f14.rgba);//也可以通过rgba进行swizzle操作,随意组合
//宏定义
fff ff9 = DIYCOLOR //上面定义宏的时候使用了分号,这里的分号可以省略
//矩阵
float2x2 m0m2x2 = {1,0,0,1}; //m行n列的矩阵
float2x4 m1m2x4 = {0,0,1,1, 0,1,0,1}; //2行4列的矩阵
col = m1m2x4[0]; //这里取的是第一行,是蓝色
float2x4 m2m2x4 = {{0,0,1,1}, {0,1,0,1}}; //2行4列的矩阵
float2x4 m3m2x4 = {{ff5}, {0,1,0,1}}; //2行4列的矩阵
float2x4 m4m2x4 = {ff5, {0,1,0,1}}; //2行4列的矩阵
float2x4 m5m2x4 = {ff5, 0,1,0,1}; //2行4列的矩阵 这些形式都是可以的
float2x4 m6m2x4 = {ff5.rgba, 0,1,0,1}; //2行4列的矩阵 这些形式都是可以的
col = m3m2x4[0];
//数组
float arr[4] = {1,0,0,1};
//col = arr //错误
//col = float4(arr.x,arr.y,arr.z,arr.w); //错误,不是基本数据类型
col = float4(arr[0],arr[1],arr[2],arr[3]);
}
ENDCG
}
}
}
2.10、结构体
Cg中支持结构体,语法形如:
//结构体
struct v2f{
float f;
float2x2 m2x2;
//基本数据类型
};
使用示例如下:
Shader "lxt610/NewSurfaceShaderTest" {
SubShader
{
Pass
{
CGPROGRAM
// Upgrade NOTE: excluded shader from OpenGL ES 2.0 because it uses non-square matrices
#pragma exclude_renderers gles
#pragma fragment frag
#pragma vertex vert
//宏定义 这里使用了别名
#define DIYCOLOR fff(ff7.rrrr);
typedef float4 fff;
//结构体
struct vf{
float4 pos;
float2 uv;
};
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR0)
{
pos = float4(objPos,0,1);
col = pos;
}
void frag(inout float4 col:COLOR0)
{
col = float4(1,1,0,1);
bool b = false;
col = b ? float4(1,0,0,1) : float4(0,1,0,1);
bool2 b12 = bool2(true,false);
bool3 b13 = bool3(true,false,false);
bool4 b14 = bool4(true,false,false,true);
int2 i12 = int2(1,0);
int3 i13 = int3(1,0,1);
int4 i14 = int4(1,0,0,1);
float2 f12 = float2(1,0);
float3 f13 = float3(1,0,1);
float4 f14 = float4(1,0,0,1);
//swizzle
float4 ff1 = float4(f12.xy,1,0);
float4 ff2 = float4(f12.yx,0,0);
float4 ff3 = float4(f14);
float4 ff4 = float4(f14.xxxx);
float4 ff5 = float4(f14.xyzw);
float4 ff6 = float4(f14.wzxy);
float4 ff7 = float4(f14.xz,1,0);//可以通过swizzle操作,随意组合
float4 ff8 = float4(f14.rgba);//也可以通过rgba进行swizzle操作,随意组合
//宏定义
fff ff9 = DIYCOLOR //上面定义宏的时候使用了分号,这里的分号可以省略
//矩阵
float2x2 m0m2x2 = {1,0,0,1}; //m行n列的矩阵
float2x4 m1m2x4 = {0,0,1,1, 0,1,0,1}; //2行4列的矩阵
col = m1m2x4[0]; //这里取的是第一行,是蓝色
float2x4 m2m2x4 = {{0,0,1,1}, {0,1,0,1}}; //2行4列的矩阵
float2x4 m3m2x4 = {{ff5}, {0,1,0,1}}; //2行4列的矩阵
float2x4 m4m2x4 = {ff5, {0,1,0,1}}; //2行4列的矩阵
float2x4 m5m2x4 = {ff5, 0,1,0,1}; //2行4列的矩阵 这些形式都是可以的
float2x4 m6m2x4 = {ff5.rgba, 0,1,0,1}; //2行4列的矩阵 这些形式都是可以的
col = m3m2x4[0];
//数组
float arr[4] = {0,1,1,1};
//col = arr //错误
//col = float4(arr.x,arr.y,arr.z,arr.w); //错误
col = float4(arr[0],arr[1],arr[2],arr[3]);
//结构体使用
vf v;
v.pos = ff4;
v.uv = ff3.xy;
col = v.pos;
}
ENDCG
}
}
}
3、总结
通过以上内容我们已经知道了Cg中的基本数据类型和使用方式,在实际的使用中我们在变量的后面还要使用语义来进一步说明,这里先卖一个关子,后续内容我们将会慢慢的了解到!
4、结束语
The End
好了,今天的分享就到这里,如有不足之处,还望大家及时指正,随时欢迎探讨交流!!!
喜欢的朋友们,请帮顶、点赞、评论!您的肯定是我写作的不竭动力!