首先说明,博主是一位Shader的初学者,在大学里也是菜鸟一枚,只是对游戏有着热情才开始学习Shader,若有写的不好地方,望各位见谅。。。哈哈哈,废话不多说,开始正题。O(∩_∩)O
效果展示
1.学过计算机图形学的同学都知道,计算机图形学中的渲染管线一共有两种:
1)固定功能渲染管线
2)可编程渲染管线
ps:渲染管线就是计算机绘制图形的过程:
局部坐标系->世界坐标系->观察坐标系->背面消除->光照->裁剪->投影->计算视口->光栅化
无论是固定渲染管线还是可编程管线,大致都需要经过这九个步骤
那么什么叫固定功能渲染管线和可编程渲染管线呢?
可编程渲染管线,从名字上就可以看出来了,可编程,所谓的可编程就是自己可以控制了嘛,就像API函数封装前的样子,可以自己随意修改达到自己想要的效果
这是博主自己的理解,若有说的不好地方,希望大家指出。。。
Shader,即着色器,着色器分为顶点着色器和像素着色器。
顶点着色器是在进行坐标变换和光照计算时工作
像素着色器是在光栅化环节工作
人们对着色器进行自定义编程时,这个流水线就叫做 **可编程管线**
当游戏或应用程序完全使用默认着色器程序时,这个流水线就叫做 **固定管线**
1.固定功能着色器
2.表面着色器
3.顶点着色器&片段着色器
顾名思义
固定功能着色器便是我们所说的固定功能渲染管线的具体表现
表面着色器、顶点着色器以及片段着色器便属于可编程渲染管线。
表面着色器这个概念更多的只是在Unity中听说,可以说是Unity自己发扬光大的一项使Shader的书写门槛降低和更易用的技术。
顶点着色器和片段着色器,应该很多学过DirectX和OpenGL的同学都不陌生:
顶点着色器:产生纹理坐标,颜色,点大小,雾坐标,然后把它们传递给裁剪阶段。
片段着色器:进行纹理查找,决定什么时候执行纹理查找,是否进行纹理查找,及把什么作为纹理坐标
没有嵌套CG语言,也就是代码段中没有CGPROGARAM和ENDCG关键字的,就是固定功能着色器。
嵌套了CG语言,代码段中有surf函数的,就是表面着色器。
嵌套了CG语言,代码段中有#pragma vertex name和 #pragma fragment frag声明的,就是顶点着色器&片段着色器。
Shader实际上就是一小段程序,它负责将输入的Mesh以指定的方式和输入的贴图或者颜色等组合作用,然后输出。绘图单元可以依据这个输出来将图像绘制到屏幕上。输入的贴图或者颜色等,加上对应的Shader,以及对Shader的特定的参数设置,将这些内容(Shader及输入参数)打包存储在一起,得到的一个就是Material。
之后,我们便可以将材质赋予给合适的render来渲染输出了。。。所以说,Shader就是规定好输入和输出的程序。而shader的开发者就是要做根据输入,进行计算变换,产生输出而已。
先来看一段代码:
Shader "Custom/Lighting_Material" {
Properties
{
_MainColor("主颜色",Color) = (1,.1,.5,1)
}
SubShader
{
Pass
{
Material
{
Diffuse[_MainColor]
Ambient[_MainColor]
}
Lighting On
}
}
//备胎设为Unity自带的普通漫反射
Fallback" Diffuse "
}
大致的框架为:
1.着色器通过properties来可选的定义一个可通过材质设定界面来自定义的列表。具体到上述代码中写的Properties,就是定义了一个基本属性,参数名叫做_MainColor,在编辑器中显示的名称叫做“主颜色”
2.后面紧跟着核心部分子着色器SubShader,里面的一个Pass里面设置了颜色为我们属性中定义的那个_ MainColor
3.添加一句Fallback代码用于应对我们Shader中的SubShader不能正确运行的情况,类似我们switch里面最后的default,当所有的通道都不能满足时就执行这个
Properties { Property [Property ...] }
定义属性块,其中可包含多个属性,其定义如下:
name (“display name”, Range (min, max)) =number
定义浮点数属性,在检视器中可通过一个标注最大最小值的滑条来修改。name (“display name”, Color) =(number,number,number,number) 定义颜色属性
name (“display name”, 2D) = “name” {options }
定义2D纹理属性
此处博主只列举部分,需要其他功能的请自行查阅
示例:
Shader "Custom/Lighting_Material_Beat" {
Properties
{
_MainColor("主颜色",Color) = (1,1,1,0)
_SpecColor("反射高光",Color) = (1,1,1,0)
_Emission("自发光",Color) = (0,0,0,0)
_Shininess("光泽度",Range(0.1,2)) = 0.7
_MainTex("主纹理",2D) = "white"{}
}
}
这些代码一般是写在Pass{ }中的:
Color Color
设定对象的纯色。颜色即可以是括号中的四值(RGBA),也可以是被方框包围的颜色属性名。Material { Material Block }
材质块被用于定义对象的材质属性。Lighting On | Off
开启光照,也就是定义材质块中的设定是否有效。想要有效的话必须使用Lighting On命令开启光照,而颜色则通过Color命令直接给出。SeparateSpecular On | Off
开启独立镜面反射。这个命令会添加高光光照到着色器通道的末尾,因此贴图对高光没有影响。只在光照开启时有效。ColorMaterial AmbientAndDiffuse | Emission
使用每顶点的颜色替代材质中的颜色集。AmbientAndDiffuse 替代材质的阴影光和漫反射值;Emission 替代材质中的光发射值。
示例:
Pass
{
Material
{
Diffuse[_MainColor]
Ambient[_MainColor]
//光泽度
Shininess[_Shininess]
//反射高光
Specular[_SpecColor]
//自发光
Emission[_Emission]
}
//开启光照
Lighting On
//开启镜面反射
SeparateSpecular On
}
[]中的定义详见前面属性Properties中的定义
Diffuse Color(R,G,B,A)
漫反射颜色构成。这是对象的基本颜色。
Ambient Color(R,G,B,A)
环境色颜色构成.这是当对象被RenderSettings.中设定的环境色所照射时对象所表现的颜色。
`Specular Color(R,G,B,A)
对象反射高光的颜色。(R,G,B,A)四个分量分别代表红绿蓝和Alpha,取值为0到1之间。`
Shininess Number
加亮时的光泽度,在0和1之间。0的时候你会发现更大的高亮也看起来像漫反射光照,1的时候你会获得一个细微的亮斑。
Emission Color
自发光颜色,也就是当不被任何光照所照到时,对象的颜色。(R,G,B,A)四个分量分别代表红绿蓝和Alpha,取值为0到1之间。
示例:
Material
{
Diffuse[_MainColor]
Ambient[_MainColor]
//光泽度
Shininess[_Shininess]
//反射高光
Specular[_SpecColor]
//自发光
Emission[_Emission]
}
[]中参数的定义详见前面Properties中的定义,属性中的定义
1.纯色的shader
1)首先,我们打开Unity创建工程,创建几个文件夹分别是Material,Shader,Texture 这就不需要多说了吧
2)在Shader文件夹上点击右键Create->Shader->Standard Surface Shader,取名。。。
3)打开所创建的shader文件,删除原本的代码,输入以下代码
Shader "Custom/SingleColor" {
//---------------------------------【子着色器】----------------------------------
SubShader
{
//----------------通道---------------
Pass
{
//设为蓝色单色
Color(0,0,0.5,0)
}
}
//FallBack "Diffuse"
}
4)保存shader文件,返回unity中,在Material上点击右键创建材质,将Shader文件拖到材质文件上
是不是很激动呢,嘿嘿,毕竟这是自己写的第一个shader
2.光照&材质shader
一样的方法,在这里,博主就不多说啦。。。
Shader "Custom/Lighting_Material" {
Properties
{
_MainColor("主颜色",Color) = (1,.1,.5,1)
}
SubShader
{
Pass
{
Material
{
Diffuse[_MainColor]
Ambient[_MainColor]
}
Lighting On
}
}
}
3.光照&材质&贴图
Shader "Custom/Lighting_Material_Beat" {
Properties
{
_MainColor("主颜色",Color) = (1,1,1,0)
_SpecColor("反射高光",Color) = (1,1,1,0)
_Emission("自发光",Color) = (0,0,0,0)
_Shininess("光泽度",Range(0.1,2)) = 0.7
_MainTex("主纹理",2D) = "white"{}
}
SubShader
{
Pass
{
Material
{
Diffuse[_MainColor]
Ambient[_MainColor]
//光泽度
Shininess[_Shininess]
//反射高光
Specular[_SpecColor]
//自发光
Emission[_Emission]
}
//开启光照
Lighting On
//开启镜面反射
SeparateSpecular On
SetTexture[_MainTex]
{
Combine texture * primary DOUBLE ,texture * primary
}
}
}
}
在贴图属性中,shader赋予给材质以后,材质可选择什么纹理
大家是不是都做完了呢。。。。。。好啦,今天就写到这里,谢谢大家的关注,时间不早了,写了一下午,吃饭去咯,希望能帮到大家,同时也是对我自己的一种鞭策吧,加油,骚年