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 ...
随机推荐
- 第三周学习java第四章学习总结及体会!
第三周java 2第四章的学习总结: 一.主要内容(类与对象): 1.类: 2.构造方法与对象的创建: 3.类与程序的基本结构: 4.参数传值: 5.对象的组合: 6.实例成员与类成员: 7.方法重载 ...
- bootstrap网格设置等高度
<!DOCTYPE html><html> <head> <meta charset="utf-8" /> <title> ...
- pip3更新后install package出现ImportError: cannot import name 'main'
linux下pip3更新后,install包出现main不能导入的情况: bear@bear:~/eclipse-workspace/Python-toolbox$ pip3 install pycr ...
- ReactJS antd 环境中项目上传图片后压缩(lrz的使用)
lrz说明 ( github地址 :https://github.com/think2011/localResizeIMG ) 用于:在客户端压缩好要上传的图片可以节省带宽更快的发送给后端,特别适合在 ...
- 解决loadrunner录制时 Request Connection: Remote Server @ 0.0.0.0:80 (Service=?) NOT PROXIED! (REASON: Unable to connect to remote server: rc = -1 , le = 0)问题
环境为win7+ie8+loadrunner11,录制脚本回放查看Recoding log 出现如下错误:[Net An. Error ( 7f8:1340)] Request Connecti ...
- 337A
#include <stdio.h> #include <stdlib.h> #define MAXSIZE 60 int comp_inc(const void *first ...
- DAX/PowerBI系列 - 关于时间系列 - 时间相关数值比较 - 用非自带函数
DAX/PowerBI系列 - 关于时间系列 - 时间相关数值比较 - 用非自带函数 文末有彩蛋,解决蛋疼问题 难度: ★★☆☆☆(2星) 适用范围: ★★★☆☆(3星) 概况: 基于时间的汇总可能是 ...
- ubuntu 16.04 国内仓库地址
deb http://mirrors.aliyun.com/ubuntu xenial maindeb http://mirrors.aliyun.com/ubuntu xenial universe ...
- python迭代-如何实现反向迭代
如何实现反向迭代 问题举例 实现一个连续浮点数发生器FloatRange,根据给定范围(start, end)和步进值(step) 产生一系列连续的浮点数,如FloatRange(3.0, 4.0, ...
- python selenium处理windows窗口
selenium本身处理不了windows窗口,需要借助,PyAutoit包 与autoit工具 这里以文件上传窗口为例: 1.安装python pyauto包 pip install PyAutoi ...