Shader编程学习笔记(五)—— Fixed Function Shader 1

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


1、Fixed Function Shader涉及的知识点

  在学习固定管线着色器中要涉及到的知识点是:

  • Properties(属性)
  • Material(材质)
  • Lighting(光照)
  • SetTexture(纹理)
  • Pass(通道)

2、ShaderLab的基本结构

shader "name"{
  [Properties]
  SubShaders
  [FallBack]
}

  在shader主要的三个部分中除了SubShaders有且至少需要一个之外,Properties和FallBack都是可以没有的。但是,如果没有Properties,我们就不能为Shader定制属性,没有FallBack,当任何一个SubShader都无法执行的时候,那么这个着色就会失败,就没有任何的方案去用于显示,所以一般条件下我们不了解我们的Shader是否适应所有的平台硬件时,我们都会使用一个FallBack,保证能够得到基本的正确的显示。

  需要注意:

  • SubShader中至少有一个Pass通道
  • ShaderLab本身是没有大小写之分
  • Properties中的代码语句之间没有分号隔开,否则报异常
  • Pass语句块中的CG程序块中一个语句结束必须要用分号隔开,否则报异常
  • Pass语句块中的CG程序块是区分大小写的,否则报异常(这里我们还是推荐大小写区分)
  • CG程序块通常以CGPROGRAM开始,以ENDCG为结束

3、示例介绍

  下面我们以一个示例来介绍Fixed Function Shader涉及到的知识点。

3.1、搭建场景

  下面我们在Unity中创建一个新的工程,这里我使用的unity2017.4.27f1。保存当前场景,添加一个小球,一个材质球崇明名为M1和一个名为FixedFunctionShader1的shader,如图所示:
在这里插入图片描述

3.2、颜色属性(color)

  此时我们打开FixedFunctionShader1.shder文件,我们删除全部内容书写如下代码:


//这里的shader名字不要求和文件名相同,也可以是一个路径
Shader "lxt610/FixedFunctionShader1" {

	//subshader至少有一个
	SubShader{
	
		//Pass块至少有一个
		Pass
		{
			color(1,1,1,1)	 // 分别代表了 r,g,b,a
		}
	}
	
}

  此时我们把M1材质球拖拽给小球,在小球中的shader组件中选择 lxt610/FixedFunctionShader1,在Unity工程中就可以看到球体变成了红色,如下图所示:
在这里插入图片描述

  我们虽然实现了改变颜色的功能,但是不方便调色!我们这里希望可以通过检视面版来操作颜色属性,办法也是有的。这里我们可以添加属性,属性的位置放在shaderd的开头,以便于后面的SubShader使用,属性的形式如下所示:


Properties{
		//这里的变量名子前一半需要添加下划线防止和系统重名(不分大小写容易重名如:color和Color)
		变量名("检视面版显示的该变量的名字",变量类型)=变量的初始值	//这里不能添加分号,否则报异常
	}

  这里我们修改颜色只需要改代码为以下形式:

Shader "lxt610/FixedFunctionShader1" {

	Properties{
		_Color("Main Color",color)=(1,1,1,1) //分别代表了r、g、b、a,当前默认值为白色。
	}

	SubShader{
		Pass
		{
			//这里的_Color是区分大小写的这里把_Color改为_color时,默认就是_color = (0,0,0,0)由于这里和属性中的_Color是不同的,取不到属性中的值
			//此时小球就会变为黑色
			color[_Color]	// 分别代表了 r,g,b,a  
		}
	}
}

  这里我们把Pass块中的括号改为中括号,并赋予Properties里的“_Color”参数,原因是小括号中的值是固定值,中括号里的值是可变参数值。然后在球体的检视面板中就可以通过“Main Color”来修改颜色值:
在这里插入图片描述

3.3、漫反射(diffuse)

  这种以color形式着色的着色器,我们无论如何转换视角球体看起来都只是一个平面的圆,并没有体现球体三维立体的感觉,要达到三维立体的感觉需要运用光照。我们知道一个有立体感的物体表面是明暗变化的,这里的相对暗一点的颜色就是我们平常说的漫反射,高亮部分就是高光镜面反射。这里我们就是漫反射来达到这样一个效果。
  这里就需要引入一些固定管线功能——漫反射:

Shader "lxt610/FixedFunctionShader1" {
	properties{
          _Color("Main Color",color)=(1,1,1,1)
    }
  
    SubShader {
        pass{
            // color(1,0,0,1) // 分别代表了 r,g,b,a 
            // color[_Color] // 小括号内容表示固定值,中括号内容表示可变参数值
            material{
                diffuse[_Color] // 漫反射
            }
        }
     }
}

  代码中material材质是一个命令块,在这个命令块中可以添加属性,其中的diffuse属性描述的是材质的漫反射颜色,也可以把它理解为物体本身固有的颜色。然后回到Unity工程,编译成功后可以发现,在当前shader检视面板中无论怎么改变“Main Color”的颜色,球体的颜色都没有什么变化,这是什么原因呢?打个比方在真实的世界当中,所有颜色的呈现都必须依靠光,没有光的话我们将看不到任何东西,在有光的情况下,物体会接受光照,然后并反射出一部分光,这样我们才能够看到物体。

ShaderLab默认情况下光照不启用的,因此在这里漫反射没有反应,需要在pass通道中添加光照命令lighting,开启为on,关闭为off

Shader "lxt610/FixedFunctionShader1" {

    properties{
        _Color("Main Color",color)=(1,1,1,1)
    }

    SubShader {
        pass{
            // color(1,0,0,1) // 分别代表了 r,g,b,a
            // color[_Color]
            material{
                diffuse[_Color] // 漫反射
            }
            lighting on // 光照开关
        }
    }
}

  这时我们在项目中shader编译成功后就可以看到球体有一定的立体效果了,球体被光照射的面相对变亮了,不背光照射的面相对变黑了,如下图。

在这里插入图片描述

3.4、环境光(ambient)

  此时我们调整视角来观察球体,可以发现球体的状态还是不够形象生动,我们只是添加了漫反射,球体处在某一个环境当中,应该还会受到环境光的影响,所以还需要ambient环境光属性。

Shader "lxt610/FixedFunctionShader1" {

	properties{
          _Color("Main Color",color)=(1,1,1,1)
		  _Ambient("Ambient",COLOR) = (0.3,0.3,0.3,1)
    }
  
    SubShader {
        pass{
            // color(1,0,0,1) // 分别代表了 r,g,b,a 
            // color[_Color] // 小括号内容表示固定值,中括号内容表示可变参数值
            material{
                diffuse[_Color]		// 漫反射
				ambient[_Ambient]	//环境光
            }

			lighting on
        }
     }
}

  在环境光ambient命令也配上一个参数“_Amnient”,声明在“Properties”中,类型也是“color”颜色,默认值范围是0~1,如果值为1,表示环境光全部为白色,这样的话即使有光照也反应不了光对物体的影响,环境光把物体全部照到最亮了,因此环境光的默认值rgb可以设置为0.3或者其他值,至于alpha值暂时可以随便设置,可以是1,也可以是0,对于目前的环境光没有影响。
  回到Unity工程中,在检视面板中修改Ambient的颜色值,可以发现环境光属性对球体的影响。
在这里插入图片描述

3.5、高光反射(specular)

  我们在日常中有不少表面光滑的物体具有很强的反光效果,我们如何让这个球体来表现这种现象呢?为了表现这种光滑的物体表面看到高光的效果,固定管线中有一个名为“specular”的命令,来表现高光部分。
  我们在material中添加specular,并配上参数“_Specular”,“_Specular”类型“color”,默认颜色为白色。

如果在material使用了“specular”命令,还必须在pass通道中添加“separatespecular on”开启命令,否则specular镜面高光不启用。

Shader "lxt610/FixedFunctionShader1" {

	properties{
          _Color("Main Color",color)=(1,1,1,1)
		  _Ambient("Ambient",COLOR) = (1,0,0,1)
		  _Specular("Specular",COLOR) = (1,1,1,1)
    }
  
    SubShader {
        pass{
            // color(1,0,0,1) // 分别代表了 r,g,b,a 
            // color[_Color] // 小括号内容表示固定值,中括号内容表示可变参数值
            material{
                diffuse[_Color]		// 漫反射
				ambient[_Ambient]	//环境光
				specular[_Specular] // 高光
            }

			lighting on // 光照开关
			separatespecular  on //镜面高光开关

        }
     }
}

  编译后,可以发现specular已经起作用,改变specular的颜色也能得到即时的反馈。
在这里插入图片描述

3.6、高光强度(shininess)

  这个高光效果看起来很奇怪,大面积地照亮了这个物体,看起来不是很舒服,并没有达到预期物体高光反射的感觉,在这里还需要另一个属性“shininess”,其参数类型为浮点值,用来描述“specular”的强度,它的参数“_Shininess”的类型可以是float,也可以用range给定一个范围,取值范围是[0.0, 128.0],值越高,表示物体越光滑,高光点越小且越亮(聚焦越好)。这里范围给定0~8,默认值为4。

Shader "lxt610/FixedFunctionShader1" {

	properties{
          _Color("Main Color",color) = (1,1,1,1)
		  _Ambient("Ambient",color)=(0.3,0.3,0.3,0)
		  _Specular("Specular",COLOR) = (1,1,1,1)
		  _Shininess("Shininess",Range(0,8)) = 4
    }
  
    SubShader {
        pass{
            // color(1,0,0,1) // 分别代表了 r,g,b,a 
            // color[_Color] // 小括号内容表示固定值,中括号内容表示可变参数值
            material{
                diffuse[_Color]			// 漫反射
				ambient[_Ambient]		// 环境光
				specular[_Specular]		// 高光
				shininess[_Shininess]	// 述specular强度
            }

			lighting on // 光照开关
			separatespecular  on //镜面高光开关

        }
     }
}

  在shader编译通过后,可以看到球体的高光部分变得很集中了,通过拖动修改“Shininess”的值,可以看到物体高光反射部分的区域起了相应的变化。
在这里插入图片描述

3.7、自发光(emission)

  固定管线着色器中还有一个功能是自发光,叫做“emission”,它可以使物体自身发光,不依赖于外部光源,参数类型也是颜色“color”。 如果将emission设置为白色,那么就会发现整个球体都变成白色了,因为在计算机当中颜色值从0到1,0是全黑,1是全白,因此即使没有光照,物体自发光都已经达到了全白,为了达到真实的感觉我们可以降低自发光的强度。

Shader "lxt610/FixedFunctionShader1" {

	properties{
          _Color("Main Color",color) = (1,1,1,1)
		  _Ambient("Ambient",color)=(0.3,0.3,0.3,0)
		  _Specular("Specular",COLOR) = (1,1,1,1)
		  _Shininess("Shininess",Range(0,8)) = 4
		  _Emission("Emission",COLOR) = (1,1,1,1)
    }
  
    SubShader {
        pass{
            // color(1,0,0,1) // 分别代表了 r,g,b,a 
            // color[_Color] // 小括号内容表示固定值,中括号内容表示可变参数值
            material{
                diffuse[_Color]			// 漫反射
				ambient[_Ambient]		// 环境光
				specular[_Specular]		// 高光
				shininess[_Shininess]	// 述specular强度
				emission[_Emission]		//自发光
            }
			lighting on // 光照开关
			separatespecular  on //镜面高光开关
        }
     }
}

在这里插入图片描述

4、Demo下载

  如果有不明白的童鞋可以在这里下载上面的演示Demo,包含了全部效果!

5、总结

  以上解释了ShaderLab的固定管线着色器的部分功能,通过设置diffuse(漫反射)、ambient(环境光)、specular(高光)、shininess(高光强度)、emission(自发光)等来修改固定管线着色器的功能,来改变material(材质)对物体产生的着色效果。

ShaderLab默认情况下光照不启用的,因此在这里漫反射没有反应,需要在pass通道中添加光照命令lighting,开启为on,关闭为off
如果在material使用了“specular”命令,还必须在pass通道中添加“separatespecular on”开启命令,否则specular镜面高光不启用。

6、结束语


The End
  好了,今天的分享就到这里,如有不足之处,还望大家及时指正,随时欢迎探讨交流!!!


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

对酒当歌﹏✍

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

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

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

打赏作者

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

抵扣说明:

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

余额充值