Shader编程学习笔记(十)—— Cg语言入门2 - 数据类型和Swizzle操作

18 篇文章 1 订阅
16 篇文章 1 订阅


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
  好了,今天的分享就到这里,如有不足之处,还望大家及时指正,随时欢迎探讨交流!!!


喜欢的朋友们,请帮顶、点赞、评论!您的肯定是我写作的不竭动力!

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

对酒当歌﹏✍

您的鼓励是我写作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值