Unity渲染教程(九):复杂材质

这篇博客详细介绍了如何在Unity中为自定义着色器创建一个类似标准着色器的GUI界面,包括显示Albedo、法线贴图、金属质感、光滑度以及发射等材质属性。通过使用ShaderGUI类,可以实现对材质属性的管理和自定义显示,同时支持光滑度来源的切换和发射颜色的HDR配置,提供类似于标准着色器的用户体验。
摘要由CSDN通过智能技术生成

同样的着色器,不同的贴图

用户界面

到目前为止,我们一直都为我们的材质使用Unity默认的材质监视器,它很耐用,但是Unity的标准着色器长得非常不一样。仿照着标准着色器,让我们一起来为我们自己的着色器创建一个自定义监视器吧。

我们默认的监视器和标准着色器监视器

着色器GUI

我们可以通过添加一个继承UnityEditor.ShaderGUI的类创建一个自定义监视器。因为它是一个编辑器类,所以应该把脚本文件放到Editor文件夹下。

usingUnityEngine;

usingUnityEditor;

publicclassMyLightingShaderGUI : ShaderGUI {

}

我们不需要继承MaterialEditor吗?

Unity 4.1支持通过继承MaterialEditor自定义材质监视器,你也可以依旧这样做,但是ShaderGUI在5.0版本中是作为备选被加入的,它的创建与Substance材质有一些关系。Unity为标准着色器使用ShaderGUI,所以我们也使用它。

要使用一个自定义GUI,你需要向着色器加入CustomEditor指令,紧跟着一个字符串,字符串包含要使用的GUI类的名字。

Shader"Custom/My First Lighting Shader"{

CustomEditor"MyLightingShaderGUI"

}

ShaderGUI类能放入命名空间吗?

可以。你需要在着色器中指定完全限定的类名。

CustomEditor"MyNamespace.MyShaderGUI"

为了替换默认监视器,我们需要重写ShaderGUI.OnGUI方法,该方法有两个参数,第一个参数是MaterialEditor的引用,这个对象管理当前被选材质的监视器;第二个参数是包含材质属性的数组。

publicclassMyLightingShaderGUI : ShaderGUI {

publicoverridevoidOnGUI (

MaterialEditor editor, MaterialProperty[] properties

) {

}

}

在这个方法内部,我们已经创建了我们自己的GUI。因为我们还什么都没做,所以监视器还是空的。

创建一个标签

标准着色器GUI被分成两部分,一部分针对主要贴图,另一部分针对次要贴图。我们会在我们的GUI中采用相同的布局。为了保持代码整洁,我们会为GUI不同的部分采用单独的方法。我们从主要部分以及其标签入手。

publicoverridevoidOnGUI (               MaterialEditor editor, MaterialProperty[] properties     ) {

DoMain();

}

voidDoMain() {

GUILayout.Label("Main Maps");

}

主要贴图标签

GUILayout是如何工作的?

UnityEditor是用Unity的立即模式UI创建的,这是Unity老的UI系统,在当今基于画布的系统之前,它也用于游戏内UI。

立即模式UI的基础是GUI类,它包含创建UI小工具的方法。你需要利用矩形来精确定位每个元素。GUILayout类提供了相同的功能,但是它会使用简单布局系统自动定位小工具。

除此之外,EditorGUI类和EditorGUILayout类提供了针对编辑器UI的小工具和特征的访问。

标准着色器有一个粗体标签,所以我们也想要一个粗体标签,通过向标签添加GUI样式就可以实现,这样一来就是EditorStyles.boldLabel。

GUILayout.Label("Main Maps", EditorStyles.boldLabel);

粗体标签.

显示Albedo

为了显示我们材质的属性,我们需要在我们的方法中访问它们。我们会把OnGUI的参数传递到其他所有方法中,但是这会导致大量重复代码。我们不这么做,我们把它们放到域中。

MaterialEditor editor;

MaterialProperty[] properties;

publicoverridevoidOnGUI (               MaterialEditor editor, MaterialProperty[] properties     ) {

this.editor = editor;

this.properties = properties;

DoMain();

}

每次OnGUI被调用时我们都需要拷贝引用吗?

当一个新的ShaderGUI实例被创建时,MaterialEditor会做出决定。目前来讲,这会在一个材质被选了的时候发生,就像你可能预期的那样。但是它也可能在撤销会重做动作执行的时候发生。这意味着你不能继续依赖ShaderGUI实例了。每次,它都会是一个新的对象实例,你可以把OnGUI想成它好像是一个静态方法,尽管它并不是。

Albedo贴图在标准着色器中第一次展现。这是主要纹理,它的属性在属性数组的某一位置设置,它的数组下标取决于我们着色器中定义属性的顺序。但是通过名称查找的鲁棒性更强一些。ShaderGUI包括FindProperty方法,它就是干这件事的,通过给定名称和属性数组找到对应结果。

voidDoMain () {

GUILayout.Label("Main Maps", EditorStyles.boldLabel);

MaterialProperty mainTex = FindProperty("_MainTex", properties);

}

除了纹理属性之外,我们也需要定义标签的内容,这可以通过GUIContent实现,它是一个简单的容器类。

MaterialProperty mainTex = FindProperty("_MainTex", properties);

GUIContent albedoLabel =newGUIContent("Albedo");

但是我们已经在我们的着色器中为主要纹理Albedo命名了,我们只能使用已定义好的名称,我们可以通过属性访问到。

GUIContent albedoLabel =newGUIContent(mainTex.displayName);

为了创建那些小的纹理小工具,我们必须依赖我们已经引用的编辑器,它具有许多绘制这样小工具的方法。

MaterialProperty mainTex = FindProperty("_MainTex", properties);

GUIContent albedoLabel =newGUIContent(mainTex.displayName);

editor.TexturePropertySingleLine(albedoLabel, mainTex);

Albedo贴图

这就是看起来像标准着色器的开始!但是当你鼠标经过属性标签时,那个监视器还有提示信息,在Albedo贴图的情况中,上面写着Albedo (RGB)和Transparency (A)。

我们也可以加一个提示信息,很简单,只要向标签内容中添加就可以了。因为我们还不支持透明度,我们就只使用Albedo(RGB)。

GUIContent albedoLabel =

newGUIContent(mainTex.displayName,"Albedo (RGB)");

带提示信息的Albedo

TexturePropertySingleLine方法有可以与多个(最多三个)属性作用的变体,第一个应该是纹理,但是其他可能就是别的什么了,它们都会被放在一行中,我们可以用这来显示纹理旁边的取色工具。

MaterialProperty tint = FindProperty("_Tint", properties);

editor.TexturePropertySingleLine(albedoLabel, mainTex, tint);

Albedo贴图和取色

让我们直接跳到主要部分的底部,那是显示主要纹理贴砖和偏移量的位置,这可以通过

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码农老K

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值