找回密码
 立即注册
查看: 289|回复: 0

Unity Shader 材质属性(Properties)特性整理

[复制链接]
发表于 2022-8-13 15:55 | 显示全部楼层 |阅读模式
标识属性

HDR

指示纹理或颜色属性使用高动态范围 (HDR) 值。
对于纹理属性,如果分配了 LDR 纹理,则 Unity 编辑器会显示警告。对于颜色属性,Unity 编辑器会使用 HDR 拾色器编辑此值。
[HDR] _EmissionColor("Emission Color", Color) = (0,0,0)设置主纹理

[MainTexture]
为材质设置主纹理,可以使用 Material.mainTexture 进行访问。
默认情况下,Unity 将具有属性名称 _MainTex 的纹理视为主纹理。如果纹理具有不同的属性名称,但希望 Unity 将它视为主纹理,请使用此特性。
如果多次使用此特性,则 Unity 会使用第一个属性并忽略后续属性。
注意: 使用此特性设置主纹理时,如果使用纹理串流调试视图模式或自定义调试工具,则该纹理在游戏视图中不可见。
设置主色

[MainColor]
为材质设置主色,可以使用 Material.color 进行访问。
默认情况下,Unity 将具有属性名称 _Color 的颜色视为主色。如果您的颜色具有其他属性 (property) 名称,但您希望 Unity 将这个颜色视为主色,请使用此属性 (attribute)。如果您多次使用此属性 (attribute),则 Unity 会使用第一个属性 (property),而忽略后续属性 (property)。
法线贴图

[Normal]
指示纹理属性需要法线贴图。
如果分配了不兼容的纹理,则 Unity 编辑器会显示警告。
额外功能

Toggle切换开关

用这种方式定义一个宏名,后面随便定义一个类型是float的变量,初始值只能是0或1,0表示关闭,1表示开启
当开关开启,shader关键词会被设定为:"property name" + "_ON",必须大写
[Toggle] _Invert ("Invert color?", Float) = 0或者重新指定一个shader关键词,括号内为shader关键词
[Toggle(_TEX_ON)] _Toggle("Enable Main Texture",Float)=0然后要在pass中用pragma定义这个宏
具体使用参考Shader变种(Variants)[1]
#pragma shader_feature _TEX_ON用这个宏的开关来改变使用的代码块
#ifdef  _TEX_ON
        return half4(diffuse*TexColor.rgb,1);
#endif枚举属性值

Shader面板上常用的一些内置枚举UI - 知乎 (zhihu.com)
ON和OFF会显示在Inspector面板上,选择对应的选项,_Enum变量(和其他Properties变量一样需要在后面定义)就会使0或1
在后续的使用中,由于GPU不适合处理分支,应该尽量避免使用switch和if语句,用step或sign函数来替代
[Enum(ON, 0, OFF, 1)] _Enum("Test Enum", float) = 1枚举关键字

shader关键词格式为:"property name" + 下划线 + “枚举名称”,必须大写
[KeywordEnum(None, Add, Multiply)] _Overlay ("Overlay mode", Float) = 0取消显示纹理的偏移

[NoScaleOffset]面板中隐藏属性

[HideInInspector]
告知 Unity 编辑器在 Inspector 中隐藏此属性。
面板相关

小标题

[Header(MainTex)]插入空行

[Space]
// 在材质面板插入多行空行,括号内为空行数
[Space(50)]参考资料

ShaderLab:定义材质属性 - Unity 手册 (unity3d.com)
在Unity Shader中自定义材质面板 - 知乎 (zhihu.com)

<hr/>1.Shader变种(Variants)

在#pragma后面加上multi_compile和shader_feature,即可指定一些用来开启或关闭某些shader代码片段的关键词
这样shader会被编译成许多不同的版本,称为shader variants
比如开启_A _B _C这三个关键词
#pragma multi_compile _A _B _C
#ifdef _A
// 如果开启了_A执行这里的代码
#endif
#ifndef _B
// 如果没开启_B执行这里的代码
#else
// compile this code if B is enabled
#endif
#if defined(_A) || defined(_C)
// _A 或_C只要开启其中一个就会执行这里的代码
// 必须使用很长的"#if defined()"
// || = or, && = and
// 这几个关键词必须是在一个multi_compile语句中定义的
// 几乎不可能会同时定义,所以&&基本是用不到的
#endif
// There's also #elif, for an else if statement.
Shader Feature
和multi_compile基本一样,但是没被使用到的变体不会被包含到最后的build中
因此如果要在运行时开启或关闭这些关键词,在build中可能就没有对应的shader
变种的数量
#pragma multi_compile _A _B _C #pragma multi_compile _D _E #pragma shader_feature _F _G 如果像这样定义三行,会产生3x2x2个变体,定义的变种越多,最后的build中产生的变体越多,需要的编译时间也越长

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 13:45 , Processed in 0.088735 second(s), 26 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表