1.2:Properties
文章著作权归作者所有。转载请联系作者,并在文中注明出处,给出原文链接。
本系列原更新于作者的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/HLSL和GLSL(不推荐),在以后的学习中,我们以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
我们可以通过 Material 的 Set 方法修改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的更多相关文章
- JavaSe:Properties文件格式
Properties文件格式说明 Properties继承自Hashtable,是由一组key-value的集合. 在Java中,常用properties文件作为配置文件.它的格式是什么样的呢? 下图 ...
- Code片段 : .properties属性文件操作工具类 & JSON工具类
摘要: 原创出处:www.bysocket.com 泥瓦匠BYSocket 希望转载,保留摘要,谢谢! “贵专” — 泥瓦匠 一.java.util.Properties API & 案例 j ...
- Unity3D ShaderLab 语法:Properties
本篇内容主要介绍Unity ShaderLab 语法:Properties Unity中的整个场景效果的表现,Shader起了至关重要的作用,为了方便我们的学习,unity采用了cg作为着色器语言. ...
- Java学习:Properties类
Java学习:Properties类 学习目标 认识properties文件,理解其含义,会正确创建properties文件. 会使用java.util.Properties类来操作propertie ...
- 面试突击74:properties和yml有什么区别?
properties 和 yml 都是 Spring Boot 支持的两种配置文件,它们可以看作是 Spring Boot 在不同时期的两款"产品".在 Spring Boot 时 ...
- 属性类:Properties
属性是程序中经常出现的形式. 在类集中提供了一种专门的Properties类. public class Propertiesextends Hashtable<Object,Object> ...
- Java基础知识强化之IO流笔记70:Properties练习之 如何让猜数字小游戏只能玩5次的案例
1. 使用Properties完成猜数字小游戏只能玩5次的案例: 2. 代码实现: (1)猜数字游戏GuessNumber: package cn.itcast_08; import java.uti ...
- Java基础知识强化之IO流笔记69:Properties练习之 判断文件中是否有指定的键,如果有就修改值的案例
1. 我有一个文本文件(user.txt),我知道数据是键值对形式的,但是不知道内容是什么. 请写一个程序判断是否有"lisi"这样的键存在,如果有就改变其值为"100& ...
- Java基础知识强化之IO流笔记68:Properties和IO流集合使用
1. Properties和IO流集合使用 这里的集合必须是Properties集合: public void load(Reader reader):把文件中的数据读取到集合中 public v ...
- Java基础知识强化之IO流笔记67:Properties的特殊功能使用
1. Properties的特殊功能 public Object setProperty(String key,String value):添加元素 public String getProperty ...
随机推荐
- Kruskal模板
Kruskal模板 struct Edge { int from,to,v; }edge[maxn*10]; int fa[maxn]; int n,m; int find(int x) { retu ...
- CAJ转换成PDF在线方法是什么
做学术性的朋友经常会需要将CAJ文件转换成PDF文件,毕竟CAJ文件只能在CAJ阅读器上显示,但是有很多转换软件并不能很好的完成转换,小编今天就为大家讲解一下CAJ转换成PDF在线方法是什么,大家要认 ...
- ping vs telnet, what is the difference between them and when to use which?
Ping is an ICMP protocol. Basically any system with TCP/IP could respond to ICMP calls if they were ...
- C# string contains 不区分大小写
一种方法是把字符串转成小写/大写,然后包含的字符串也写成小写 /大写 另一种方法是: 1 string title = "STRING"; 2 bool contains = ti ...
- mysql查询两个日期之前相隔的天数
select timestampdiff(SECOND,'2011-09-25 23:23:13','2011-09-26 22:23:11'); 其中SECOND同样可以改为HOUR,MINUTE
- sudo: java 找不到命令
解决方法: :~$ sudo visudo 在secure_path后加上JDK工具的路径,如: :/jdk安装路径/jdk1..0_144/bin 之后就可以使用"sudo java *. ...
- robotframework接口之上传图片
python-requests及robotframework-RequestsLibrary实现multipart/form-data接口上传文件. 如Fiddle抓包截图: 实现如截图: 不要自己在 ...
- 一篇文章彻底弄懂Base64编码原理
在互联网中的每一刻,你可能都在享受着Base64带来的便捷,但对于Base64的基础原理又了解多少?今天这篇博文带领大家了解一下Base64的底层实现. Base64的由来 目前Base64已经成为网 ...
- ElasticSearch 随笔
1.如何用亚马逊S3存储一个ES服务索引.http://t.cn/R0fAJwK 2.ELK实战 - 利用Nginx日志分析API耗时.http://t.cn/R6sgQfU 3.Kibana中的地 ...
- 66.ajax--ajax请求多个url解决办法
ajax请求多个url解决办法 以下四种方法是我找的,我也进行实践过. 测试中有四个请求接口,原本需要13S,用了第三种方法缩减到7S,但是仍不能达到2S以内. 所以仅供参考,待我找到能缩减到2S以内 ...