文章著作权归作者所有。转载请联系作者,并在文中注明出处,给出原文链接。

本系列原更新于作者的github博客,这里给出链接

上一节我们了解了一个Shader的基本结构,这一节,我们从 Properties 代码块入手,了解Shaderlab的参数组成。

如何声明Properties

常规属性

Properties的属性常用的主要有以下几类: Numbers (数值)、 Colors(颜色) 、 Vectors (向量)、 Textures (纹理),其中,对于数值属性,还提供了Range()设置区间值限定数值范围(注意,属性中没有 Matrices (矩阵))。下面给出一些Shader的属性定义方法,具体的属性值以及默认参数可以参考Unity官方文档ShaderLab: Properties(unity3D/Editor/Data/en/Manual/SL-Properties.html)。

//定义Numbers(数值)和Sliders(区间值)
name ("display name", Range (min, max)) = number
name ("display name", Float) = number
name ("display name", Int) = number //定义Colors(颜色)和Vectors(向量)
//颜色表示为一个四维向量,对应颜色的RGBA通道;每个分量取值为[0,1]
//向量必须是四维向量
name ("display name", Color) = (number,number,number,number)
name ("display name", Vector) = (number,number,number,number) //定义Textures(纹理)
name ("display name", 2D) = "defaulttexture" {}
name ("display name", Cube) = "defaulttexture" {}
name ("display name", 3D) = "defaulttexture" {}

Texture(纹理)

Unity给出了纹理声明时可选的默认默认值:

对于 2D Texture(2维纹理)

内置默认值 (R,G,B,A)
empty string null
"white" 1, 1, 1, 1
"black" 0, 0, 0, 0
"gray" 0.5, 0.5, 0.5, 0.5
"bump" 0.5, 0.5, 1, 0.5
"red" 1, 0, 0, 0

对于Non 2D Texture (非2维纹理,如:Cube, 3D, 2DArray)

默认值是empty string,当他们没有材质指定时,默认使用“gray”

Unity文档还给出了属性的命名规范:

Each property inside the shader

is referenced by name (in Unity, it’s common to start shader property names with underscore).

即名称以下划线开头,首字母大写驼峰命名。

此外,一般纹理都会包含 tiling & offset(缩放和偏移),这会被作为一个float4类型的变量传入cg代码块中,这个变量有一个特别的名称: {TextureName}_ST;同样,纹理还有一个特殊的属性 Texture size (纹理尺寸),这个变量也有一个特别的名称:{TextureName}_TexelSize,它保存了纹理的尺寸信息。下面给出一个例子:

Shader "ShaderName" {
Properties {
_MainTex ("Albedo", 2D) = "white" {}
}
SubShader {
Pass {
CGPROGRAM
sampler2D _MainTex;
float4 _MainTex_ST;
// 其中x,y分量是缩放比,z,w分量是偏移量
float4 _MainTex_TexelSize;
// 其中:
// x/y的值为纹理宽度/高度的倒数
// z/w的值为纹理宽度/高度
ENDCG
}
}
}

还有一种高品质纹理Texture HDR,这里不做展开。

Attributes(属性)

Unity还将C#的Attributes(属性)特性引入Shaderlab。在每个属性之前,我们可以指定一些由方括号包围的标签来具体说明这个属性的显示方式,下面给出几个build-in的标签:

  • [Header(text)]:会在这个标签上方生成一个文本

  • [Toggle]:这个属性只接受数字类型,并且会作为一个勾选项,勾选时为1,否则为0

  • [IntRange]:把参数限制在整数范围

  • [PowerSlider(Value)]:power即幂,也就是指数级的缩放滑动条的疏密程度,靠近Range的左值会拥有更精确的调整范围,Value接受指数等级控制,值为1时相当于普通Range

  • [Enum(List)]:枚举类型,把参数限制下拉列表的可选项中

  • [HideInInspector]:不在Inspector面板显示这个属性

  • [NoScaleOffset]:不显示纹理的缩放/偏移编辑器

  • [Normal]:提示这是一个法线纹理

    标签的详细用法可以参阅官方文档:

    (unity3D/Editor/Data/en/ScriptReference/MaterialPropertyDrawer.html)。

    我们还可以在脚本中重写OnGUI方法定制自己的标签。

Properties怎样提供给Shader

一般来说,属性从3个渠道获得:

  • MaterialPropertyBlock 中设置的Per-Renderer values(逐渲染器值),这通常称为“per-instance”数据

  • 在指定的已渲染对象的 Material 面板设置的值

  • 由Unity的内置渲染或自己的脚本设置的全局Shader属性

    这三个属性的优先级如下:

    per-instance数据优先级最高,然后是材质自身的属性,最后是全局属性,如果三种属性都没有设置,那么Unity会使用默认值

定义Shader属性的目的在于更便捷地使用,下面我们来看看如何在Shaderlab以及Script中使用这些属性。

Properties和Shader

我们可以在CGPROGRAM(CG代码块)中声明同名变量和Shader进行交互

Shaderlab支持插入Cg/HLSLGLSL(不推荐),在以后的学习中,我们以Cg为主。

Properties 声明的参数会作为 Material (材质)的数据按顺序显示在材质面板。

Shader "ShaderName" {
Properties {
_Texture ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1, 1, 1, 1)
_Vector ("Vector", Vector) = (1, 1, 1 ,1)
_Cubemap ("Cubemap", CUBE) = "" {}
}
SubShader {
Pass {
CGPROGRAM
//颜色和向量用float4 / half4 / fixed4存储,精度从高到低
//数值用float / half / fixed存储,精度从高到低
//2D纹理 / 3D纹理 / Cubemap分别用sampler2D / 3D / CUBE存储
sampler2D _Texture;
float4 _Texture_ST;
float4 _Texture_TexelSize;
fixed4 _Color;
float4 _Vector;
samplerCUBE _Cubemap;
ENDCG
}
}
}

​ 此外,我们还可以声明一些变量供Shader的 fixed function 使用,使用时用方括号包围。例如:我们可以通过这种方式设置混合系数(混合系数等标签我们会在以后的章节进行学习):

Shader "ShaderName" {
Properties {
//...
_SrcBlend ("SrcBlend", Int) = 1
_DstBlend ("DstBlend", Int) = 0
}
SubShader {
//...
Pass {
Blend [_SrcBlend] [_DstBlend]
}
//...
}
}

Properties和Script

我们可以通过 MaterialSet 方法修改Properties以实现最基础的交互。

using UnityEngine;

public class TestClass : MonoBehaviour {

	private Material testMaterial = null;

	public Material material {
get {
return testMaterial;
}
} void Start () {
//把这个材质的shader中的name属性值设为1.0
testMaterial.setFloat("name", 1.0);
}
}

最后

这里我给出一份属性的示例:

Shader "MyShaders/ShaderForProperties" {

    Properties {
[NoScaleOffset] _Texture ("Texture", 2D) = "white" {}
_Color ("Color", Color) = (1, 1, 1, 1)
[HideInInspector] _Vector ("Vector", Vector) = (1, 1, 1 ,1)
_Cubemap ("Cubemap", CUBE) = "" {}
[Header(Blend Parameter)] _SrcBlend ("SrcBlend", Int) = 1
_DstBlend ("DstBlend", Int) = 0
} SubShader { Pass {
Blend [_SrcBlend] [_DstBlend] CGPROGRAM sampler2D _Texture;
float4 _Texture_ST;
float4 _Texture_TexelSize;
fixed4 _Color;
float4 _Vector;
samplerCUBE _Cubemap; ENDCG
} } FallBack "Diffuse"
}

下面是对应的属性面板(需要把Shader添加到材质内才会显示属性面板):

1.2:Properties的更多相关文章

  1. JavaSe:Properties文件格式

    Properties文件格式说明 Properties继承自Hashtable,是由一组key-value的集合. 在Java中,常用properties文件作为配置文件.它的格式是什么样的呢? 下图 ...

  2. Code片段 : .properties属性文件操作工具类 & JSON工具类

    摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “贵专” — 泥瓦匠 一.java.util.Properties API & 案例 j ...

  3. Unity3D ShaderLab 语法:Properties

    本篇内容主要介绍Unity ShaderLab 语法:Properties Unity中的整个场景效果的表现,Shader起了至关重要的作用,为了方便我们的学习,unity采用了cg作为着色器语言. ...

  4. Java学习:Properties类

    Java学习:Properties类 学习目标 认识properties文件,理解其含义,会正确创建properties文件. 会使用java.util.Properties类来操作propertie ...

  5. 面试突击74:properties和yml有什么区别?

    properties 和 yml 都是 Spring Boot 支持的两种配置文件,它们可以看作是 Spring Boot 在不同时期的两款"产品".在 Spring Boot 时 ...

  6. 属性类:Properties

    属性是程序中经常出现的形式. 在类集中提供了一种专门的Properties类. public class Propertiesextends Hashtable<Object,Object> ...

  7. Java基础知识强化之IO流笔记70:Properties练习之 如何让猜数字小游戏只能玩5次的案例

    1. 使用Properties完成猜数字小游戏只能玩5次的案例: 2. 代码实现: (1)猜数字游戏GuessNumber: package cn.itcast_08; import java.uti ...

  8. Java基础知识强化之IO流笔记69:Properties练习之 判断文件中是否有指定的键,如果有就修改值的案例

    1. 我有一个文本文件(user.txt),我知道数据是键值对形式的,但是不知道内容是什么. 请写一个程序判断是否有"lisi"这样的键存在,如果有就改变其值为"100& ...

  9. Java基础知识强化之IO流笔记68:Properties和IO流集合使用

    1. Properties和IO流集合使用 这里的集合必须是Properties集合:  public void load(Reader reader):把文件中的数据读取到集合中  public v ...

  10. Java基础知识强化之IO流笔记67:Properties的特殊功能使用

    1. Properties的特殊功能 public Object setProperty(String key,String value):添加元素 public String getProperty ...

随机推荐

  1. PPT领取 | 70+数据科学、架构演进等最佳实践限时放送

    上世纪1950年人工智能被提出,直至2016年AlphaGo战胜世界围棋冠军李世石后,人工智能迅速引起了全球的瞩目,并推动起全球科技的浪潮.自动驾驶.人脸识别.语音交互技术等“一拥而上”,众多AI科技 ...

  2. Nuxt.js调用asyncData

    <template> <div> Index {{ username }} </div> </template> <script> expo ...

  3. python常用模块——collections

    好久没学习了,简单了解下 Ⅰ.namedtuple 1.1 简单回顾一下tuple tuple是一个不可变的可迭代对象 ①可迭代 In [1]: test_tuple = (1,2,3,4,5) In ...

  4. js自定义格式化时间戳的格式

    题目为 : 写一个模块,外部调用这个模块,请求参数是时间戳,模块要求 今天的时间,统一用24小时写作 03:00.15:04 昨天的时间,统一写昨天 昨天之前的时间,但在本周之内的时间,统一用周一.周 ...

  5. html5网页录音

    demo https://xiangyuecn.github.io/Recorder/

  6. JAVA学习笔记 (一、入门及前期准备)

    博主本来只是会一点python,但是换了新公司这边用的java,边学习边总结吧,共勉之. 一.认识 java (1)java分为三类 JavaSE 基础核心 JaveEE web方向(企业版) Jav ...

  7. docker-compose介绍

    docker-compose 常用命令 Commands: build Build or rebuild services bundle Generate a Docker bundle from t ...

  8. spring 初始化

    一.Spring 容器高层视图 Spring 启动时读取应用程序提供的Bean配置信息,并在Spring容器中生成一份相应的Bean配置注册表,然后根据这张注册表实例化Bean,装配号Bean之间的依 ...

  9. Win2008 IIS7.5安装配置PHP7.3.2步骤,及500错误解决

    安装Visual C++运行库 根据 PHP 版本选择 VC++ 版本,缺少 VC++ 运行库会报500错误. php-7.1.28-nts-Win32-VC14-x64.zip   VC14: Vi ...

  10. java iso8859 转utf8

    http://www.it1352.com/110853.html https://blog.csdn.net/RR369_yyh/article/details/77582441 /* 输出 下面这 ...