switch…case

💡 需要注意的是早期版本Cg不支持switch…case语句,但是保留了这些关键字!

switch(条件变量)
{
 case 条件1:
 [语句块]
 break;
 case 条件2:
 [语句块]
 break;
 ...

 default:
 [语句块]
 break;
}

示例如下:

Shader "lxt610/NewSurfaceShaderTest2" {
 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);

 //关于switch case验证
 int i = 3;

 switch(i)
 {
 case 0:
 col = float4(1,0,0,1);//红色
 break;
 case 1:
 col = float4(0,1,0,1);//绿色
 break;
 case 2:
 col = float4(0,0,1,1);//蓝色
 break;
 case 3:
 col = float4(1,0,0.5,1);
 break;
 case 4:
 col = float4(1,0.5,1,1);
 break;
 default:
 col = float4(1,1,1,1);//白色
 break;
 }
 }
 ENDCG
 }
 }
}

这里修改i的值使其进入相应的条件,发现颜色发生了相应的变化并没有进入default条件中,这说明现在的Cg支持了这个语句!或者说至少我这里是支持的,我这里使用的是unity2017.4.27f1,shader model 3.0是支持的!

if…else条件语句

if…else条件语句的语法为:

if(条件语句)
 {
 //语句块1
 }
 elseif(条件语句)
 {
 //语句块2
 }
 ...
 else
 {
 //语句块
 }

示例如下:

Shader "lxt610/NewSurfaceShaderTest2" {
 SubShader 
 {
 Pass
 {
 CGPROGRAM

 #pragma fragment frag
 #pragma vertex vert

 void vert(in float2 objPos:POSITION,out float4 col:COLOR0,out float4 pos:POSITION)
 {
 pos = float4(objPos,0,1);

 if(pos.x < 0)
 {
 col = float4(1,0,0,1);//红色
 }
 else
 {
 col = float4(0,1,0,1);//绿色
 }

 //col = pos;
 }

 void frag(inout float4 col:COLOR0)
 { 

 }
 ENDCG
 }
 }
}

Untitled

💡 回到unity中编译通过我们我们发现,左边变成了红色,右边成了绿色,中间是一个过渡区域。这是因为在摄像机的剪裁空间cvv中坐标范围是(-1,1),而物体的模型坐标处于(-0.5,0.5)之间(左下角(-0.5,-0.5),右上角(0.5,0.5)),所以物体的左边就变成了红色,右边就成了绿色。而中间的部分我们发现是一个缓慢的融合过程区域!这是由于顶点的颜色处理过后,还有大量的像素没有处理这时在光栅化阶段就是片元函数处理的过程中做了一个差值的运算

while循环语句

while语句的语法格式

while(条件语句)//满足条件执行,否则退出循坏(先判断,再执行))
{
语句块;
}

下面是一个示例,代码和效果如下

Shader "lxt610/NewSurfaceShaderTest2" {
SubShader
{
Pass
{
CGPROGRAM
#pragma fragment frag
#pragma vertex vert

 void vert(in float2 objPos:POSITION,out float4 col:COLOR0,out float4 pos:POSITION)
 {
 pos = float4(objPos,0,1);

 if(pos.x < 0 && pos.y < 0)
 {
 col = float4(1,0,0,1);//红色
 }
 else if(pos.x < 0)
 {
 col = float4(0,1,0,1);//绿色
 }
 else if(pos.y > 0)
 {
 col = float4(1,1,0,1);//黄色
 }
 else
 {
 col = float4(0,0,1,1);//蓝色
 }

 //col = pos;
 }

 void frag(inout float4 col:COLOR0)
 {
 int i = 0;
 while(i < 10)
 {
 i++;
 }

 if(i == 10)
 col = float4(0,0,0,1);
 }
 ENDCG
 }
}
}

这里为了方便演示我们只是循环了十次,由于没有控制台输出这里为了方便观察,结束循环后颜色设为黑色(float4(0,0,0,1))!这说明循环执行了10次!

do…while循环语句

do…while语句的语法格式

{
语句块;
}
while(条件语句);//满足条件执行,否则退出循坏(先执行一次,再判断)
下面是一个示例,代码和效果如下:
Shader "lxt610/NewSurfaceShaderTest2" {
SubShader
{
Pass
{
CGPROGRAM
#pragma fragment frag
#pragma vertex vert

 void vert(in float2 objPos:POSITION,out float4 col:COLOR0,out float4 pos:POSITION)
 {
 pos = float4(objPos,0,1);

 if(pos.x < 0 && pos.y < 0)
 {
 col = float4(1,0,0,1);//红色
 }
 else if(pos.x < 0)
 {
 col = float4(0,1,0,1);//绿色
 }
 else if(pos.y > 0)
 {
 col = float4(1,1,0,1);//黄色
 }
 else
 {
 col = float4(0,0,1,1);//蓝色
 }

 //col = pos;
 }

 void frag(inout float4 col:COLOR0)
 {
 int i = 0;
 while(i < 10)
 {
 i++;
 }

 if(i == 10)
 col = float4(0,0,0,1);

 i = 0;

 do{
 i++;
 }
 while(i < 10);

 if(i == 10)
 col = float4(1,1,1,1);
 }
 ENDCG
 }
}
}

这里为了方便演示我们只是循环了十次,由于没有控制台输出这里为了方便观察,结束循环后颜色设为白色(float4(1,1,1,1))!这说明循环执行了10次退出,然后设为了白色!

for循环

for循环的语法

for(int i = 0; i < 10; i++)(初始值,条件1,语句2)
{
 语句块;
}

下面是一个示例,代码和效果如下:

Shader "lxt610/NewSurfaceShaderTest2" {
SubShader
{
Pass
{
CGPROGRAM
#pragma fragment frag
#pragma vertex vert

 void vert(in float2 objPos:POSITION,out float4 col:COLOR0,out float4 pos:POSITION)
 {
 pos = float4(objPos,0,1);

 if(pos.x < 0 && pos.y < 0)
 {
 col = float4(1,0,0,1);//红色
 }
 else if(pos.x < 0)
 {
 col = float4(0,1,0,1);//绿色
 }
 else if(pos.y > 0)
 {
 col = float4(1,1,0,1);//黄色
 }
 else
 {
 col = float4(0,0,1,1);//蓝色
 }

 //col = pos;
 }

 void frag(inout float4 col:COLOR0)
 {
 for(int i = 0; i < 10; i++)
 {
 }
 if(i == 10)
 col = float4(0.5,0.5,0,1);
 }
 ENDCG
 }
}
}

Untitled

💡 观察发现变为暗黄色,说明执行了条件语句中的内容,说明了能够正常跳出循环! 💡 值得注意的是for循环的次数有些版本是有限制的,超过了1024就会报运行异常,有的则不会根据实际情况测试!