4.ShaderLab-ShaderLab语法规则-Shader的属性
4.1 知识点
知识回顾
ShaderLab主要由四个部分组成:
- Shader的名字
- Shader的属性
- 1至多个子着色器
- 备用的Shader
第一部分:
// Shader "着色器名字"
{
// 第二部分
Properties
{
// 材质面板上可以看到的属性
}
// 第三部分
SubShader
{
// 顶点-片段着色器 或 表面着色器 或 固定函数着色器
}
SubShader
{
// 更加精简的版本
// 目的是适配旧设备
}
// 可以有多个SubShader代码块
// 第四部分
Fallback "备用的Shader"
}
Shader的属性的作用
在Shader编写时,我们经常会用到不同类型的变量或贴图等资源。为了增加Shader的可调节性,有些变量不会直接在Shader程序中写死,而是作为开放的属性显示在我们的材质面板上,供我们使用时调节。这些开放的属性就是通过属性来定义的。
Shader的属性具有两个特点:
- 可以在材质面板被编辑
- 可以在后续当作输入变量提供给所有子着色器使用
Shader的属性的基本语法
在Shader文件中,Shader属性是存在于Shader语句块中的Properties属性语句块。我们只需要在Properties语句块中按照语法规则声明属性即可。
Unity Shader的属性主要分成三大类:数值、颜色和向量、纹理贴图。
属性的基本语法:
_Name("Display Name", type) = defaultValue[{options}]
- _Name: 属性名字,规则是需要在前面加一个下划线,方便在之后获取
- Display Name: 材质面板上显示的名字
- type: 属性的类型
- defaultValue: 将Shader指定给材质的时候初始化的默认值
例子:
// Shader "着色器名字"
{
// 第二部分
Properties
{
// 材质面板上可以看到的属性
_Name("Display Name", type) = defaultValue[{options}]
}
// 第三、四部分
.......
.......
}
数值类型属性
数值类型有三种:
- 整形
_Name("Display Name", Int) = number
- 浮点型
_Name("Display Name", Float) = number
- 范围浮点型
_Name("Display Name", Range(min,max)) = number
注意:Unity Shader中的数值类型属性基本都是浮点型(Float)数据。虽然提供了整数(Int),但是编译时最终都会转换为浮点型。因此,我们更多使用的是Float类型。
创建顶点着色器,编辑Properties:
Properties
{
// 数值类型属性
_MyInt("MyInt", Int) = 666
_MyFloat("MyFloat", Float) = 0.666 // 不要加f,C#才要加
_MyRange("MyRange", Range(1,5)) = 3
}
在材质中选择当前的顶点着色器,观察Inspector面板。
颜色和向量类型属性
颜色和向量类型属性之所以归纳在一起,是因为颜色是由RGBA四个分量代表,向量是由XYZW四个分量代表,它们都可以由一个四个数组成的类型表示。
颜色
_Name("Display Name", Color) = (number1,number2,number3,number4)
注意:颜色值中的RGBA的取值范围是 0
1 (映射0255)向量
_Name("Display Name", Vector) = (number1,number2,number3,number4)
注意:向量值中的XYZW的取值范围没有限制
在Properties添加颜色和向量类型属性:
Properties
{
// 颜色和向量类型属性
_MyColor("MyColor", Color) = (1,1,0,1)
_MyVector("MyVector", Vector) = (123,456,789,666)
}
观察Inspector窗口。
纹理贴图类型属性
纹理贴图类型有四种:
- 2D 纹理(最常用的纹理,漫反射贴图、法线贴图都属于2D纹理)
_Name("Display Name", 2D) = "defaulttexture" {}
- 2DArray 纹理(纹理数组,允许在纹理中存储多层图像数据,每层看做一个2D图像,一般使用脚本创建,较少使用,了解即可)
_Name("Display Name", 2DArray) = "defaulttexture" {}
- Cube map texture纹理(立方体纹理,由前后左右上下6张有联系的2D贴图拼成的立方体,比如天空盒和反射探针)
_Name("Display Name", Cube) = "defaulttexture" {}
- 3D纹理(一般使用脚本创建,极少使用,了解即可)
_Name("Display Name", 3D) = "defaulttexture" {}
注意:
关于defaulttexture默认值取值:
- 不写: 默认贴图为空
- white: 默认白色贴图(RGBA:1,1,1,1)
- black: 默认黑色贴图(RGBA:0,0,0,1)
- gray: 默认灰色贴图(RGBA:0.5,0.5,0.5,1)
- bump: 默认凸贴图(RGBA:0.5,0.5,1,1),一般用于法线贴图默认贴图
- red: 默认红色贴图(RGBA:1,0,0,1)
关于默认值后面的 {} ,固定写法(老版本中括号内可以控制固定函数纹理坐标的生成,但是新版本中没有该功能了)
在Properties添加纹理贴图类型属性:
Properties
{
// 纹理贴图类型属性
_My2D("My2D", 2D) = "white" {}
_My2DArray("My2DArray", 2DArray) = "" {} // 不常用
_MyCube("MyCube", Cube) = "red" {}
_My3D("My3D", 3D) = "" {} // 不常用
}
创建cubmap天空和盒,观察Inspector窗口。
总结
Shader的属性主要就是三种类型:数值、颜色和向量、纹理贴图。我们只需要掌握属性声明的基础语法即可。它的主要特点是:
- 可以在材质面板被编辑
- 可以在后续当作输入变量提供给所有子着色器使用
4.2 知识点代码
Lesson04_ShaderLab_ShaderLab语法规则_ShaderLab的属性
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Lesson04_ShaderLab_ShaderLab语法规则_ShaderLab的属性 : MonoBehaviour
{
void Start()
{
#region 知识回顾
//ShaderLab主要由4个部分组成
//1.Shader的名字
//2.Shader的属性
//3.1~n个子着色器
//4.备用的Shader
//第一部分
//Shader "着色器名字"
//{
// //第二部分
// Properties
// {
// //材质面板上可以看到的属性
// }
// //第三部分
// SubShader
// {
// //顶点-片段着色器 或 表面着色器 或 固定函数着色器
// }
// SubShader
// {
// //更加精简的版本
// //目的是适配旧设备
// }
// .....可以有n个SubShader代码块
// //第四部分
// Fallback "备用的Shader"
//}
#endregion
#region 知识点一 Shader的属性的作用
//在Shader编写时我们经常会用到不同类型的变量或贴图等资源
//为了增加Shader的可调节性,有些变量不会直接在Shader程序中写死
//而是作为开放的属性显示在我们的材质面板上,供我们使用时调节
//而这些开放的属性就是通过属性来定义的
//Shader的属性具有两个特点
//1.可以在材质面板被编辑
//2.可以在后续当作输入变量提供给所有子着色器使用
#endregion
#region 知识点二 Shader的属性的基本语法
//1.在Shader文件中
// Shader属性是存在于Shader语句块中的Properties属性语句块
// 我们只需要在Properties语句块中按照语法规则声明属性即可
//2.Unity Shader的属性主要分成三大类:数值、颜色和向量、纹理贴图
//3.属性的基本语法
// _Name("Display Name", type) = defaultValue[{options}]
// _Name: 属性名字,规则是需要在前面加一个下划线,方便在之后获取
// Display Name:材质面板上显示的名字
// type:属性的类型
// defaultValue:将Shader指定给材质的时候初始化的默认值
//例子:
//第一部分
//Shader "着色器名字"
//{
// //第二部分
// Properties
// {
// //材质面板上可以看到的属性
// _Name("Display Name", type) = defaultValue[{options}]
// }
// //第三、四部分
// .......
// .......
//}
#endregion
#region 知识点三 数值类型属性
//数值类型有三种:
//1.整形
//_Name("Display Name", Int) = number
//2.浮点型
//_Name("Display Name", Float) = number
//3.范围浮点型
//_Name("Display Name", Range(min,max)) = number
//注意:Unity Shader中的数值类型属性基本都是浮点型(Float)数据
// 虽然提供了整数(Int),但是编译时最终都会转换为浮点型
// 因此我们更多的使用的还是Float类型
#endregion
#region 知识点四 颜色和向量类型属性
//颜色和向量类型属性之所以归纳在一起
//是因为
//颜色是由RGBA四个分量代表
//向量是由XYZW四个分量代表
//他们都可以由一个四个数组成的类型表示
//1.颜色
//_Name("Display Name", Color) = (number1,number2,number3,number4)
//注意:颜色值中的RGBA的取值范围是 0~1 (映射0~255)
//2.向量
//_Name("Display Name", Vector) = (number1,number2,number3,number4)
//注意:向量值中的XYZW的取值范围没有限制
#endregion
#region 知识点五 纹理贴图类型属性
//纹理贴图类型有四种
//1.2D 纹理(最常用的纹理,漫反射贴图、法线贴图都属于2D纹理)
//_Name("Display Name", 2D) = "defaulttexture"{}
//2.2DArray 纹理(纹理数组,允许在纹理中存储多层图像数据,每层看做一个2D图像,一般使用脚本创建,较少使用,了解即可)
//_Name("Display Name", 2DArray) = "defaulttexture"{}
//3.Cube map texture纹理(立方体纹理,由前后左右上下6张有联系的2D贴图拼成的立方体,比如天空盒和反射探针)
//_Name("Display Name", Cube) = "defaulttexture"{}
//4.3D纹理(一般使用脚本创建,极少使用,了解即可)
//_Name("Display Name", 3D) = "defaulttexture"{}
//注意:
//1.关于defaulttexture默认值取值
// 不写:默认贴图为空
// white:默认白色贴图(RGBA:1,1,1,1)
// black:默认黑色贴图(RGBA:0,0,0,1)
// gray:默认灰色贴图(RGBA:0.5,0.5,0.5,1)
// bump:默认凸贴图(RGBA:0.5,0.5,1,1),一般用于法线贴图默认贴图
// red:默认红色贴图(RGBA:1,0,0,1)
//2.关于默认值后面的 {} ,固定写法(老版本中括号内可以控制固定函数纹理坐标的生成,但是新版本中没有该功能了)
#endregion
#region 总结
//Shader的属性主要就是三种类型
//数值、颜色和向量、纹理贴图
//我们只需要掌握属性声明的基础语法即可
//它的主要是:
//1.可以在材质面板被编辑
//2.可以在后续当作输入变量提供给所有子着色器使用
#endregion
}
}
Lesson04_NewUnlitShader.shader
Shader "ShaderTeach/Lesson04_NewUnlitShader"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
//_Name("Display Name", type) = defaultValue[{options}]
//数值类型属性
_MyInt("MyInt", Int) = 666
_MyFloat("MyFloat", Float) = 0.666//不要加f C#才要加
_MyRange("MyRange", Range(1,5)) = 3
//颜色和向量类型属性
_MyColor("MyColor", Color) = (1,1,0,1)
_MyVector("MyVector", Vector) = (123,456,789,666)
// 纹理贴图类型属性
_My2D("My2D", 2D) = "white" {}
_My2DArray("My2DArray", 2DArray) = "" {}//不常用
_MyCube("MyCube", Cube) = "red" {}
_My3D("My3D", 3D) = "" {}//不常用
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
4.3 练习题
Unity的 ShaderLab 中属性Properties语句块中声明的各属性有什么作用?并说出至少6种常用的属性类型
ShaderLab中属性的作用:
- 语句块中声明的属性可以在材质面板上进行设置,通过设置,允许我们自定义着色器的一些表现。
- 这些属性之后可以在着色器的实现代码中进行使用,进行逻辑处理。
常用属性类型:
- Int
- Float
- Range(min,max)
- Color
- Vector
- 2D
- 2DArray
- 3D
- Cube
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com