unity shader 编辑器扩展类 ShaderGUI

这应该unity5才出的新功能了,今天看文档时刚巧看到了,就来尝试了一下。

效果如图:



shader 的编辑器扩展分为2种方法:

  1. 是通过UnityEditor下的ShaderGUI类来实现的,形式比较近似于我们一般对unity编辑器的扩展方式。
  2. 是通过直接在shader代码上通过unity为我们预定义好的一些命令来扩展。

个人比较推荐使用第一种方法,第二种在尝试时发现

①是第二种控件的种类有限。限制还特别多,变量申请的不对的话,有时也不报错,不利于维护。

②是文档里还有错误+没说清楚的地方。

③是第一种方法创建的.cs文件是可以复用到,我们可以只写一个.cs文件,然后跟好几个shader文件进行关联。



先来说说第一种方法:

官方文档:http://docs.unity3d.com/Manual/SL-CustomShaderGUI.html

CS代码如下:

 1 using UnityEngine;
 2 using UnityEditor;
 3 using System;
 4
 5 public class TestShaderGUI : ShaderGUI
 6 {
 7     public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
 8     {
 9         // render the default gui
10         base.OnGUI(materialEditor, properties);
11
12         Material targetMat = materialEditor.target as Material;
13
14         // see if redify is set, and show a checkbox
15         bool CS_BOOL = Array.IndexOf(targetMat.shaderKeywords, "CS_BOOL") != -1;
16
17         EditorGUI.BeginChangeCheck();
18         CS_BOOL = EditorGUILayout.Toggle("CS_BOOL", CS_BOOL);
19
20         if (EditorGUI.EndChangeCheck())
21         {
22             // enable or disable the keyword based on checkbox
23             if (CS_BOOL)
24                 targetMat.EnableKeyword("CS_BOOL");
25             else
26                 targetMat.DisableKeyword("CS_BOOL");
27         }
28     }
29 }

Shader代码:

 1 Shader "MyTest/TestShaderGUI"
 2 {
 3     Properties
 4     {
 5         _MainTex("Texture", 2D) = "white" {}
 6     }
 7     SubShader
 8     {
 9         Tags{ "RenderType" = "Opaque" }
10         LOD 200
11
12         CGPROGRAM
13
14         #pragma surface surf Lambert addshadow
15
16         #pragma shader_feature CS_BOOL
17
18         sampler2D _MainTex;
19
20         struct Input
21         {
22             float2 uv_MainTex;
23         };
24
25         void surf(Input IN, inout SurfaceOutput o)
26         {
27             half4 c = tex2D(_MainTex, IN.uv_MainTex);
28             o.Albedo = c.rgb;
29             o.Alpha = c.a;
30
31             #if CS_BOOL
32             o.Albedo.gb *= 0.5;
33             #endif
34         }
35
36         ENDCG
37     }
38     CustomEditor "TestShaderGUI"
39 }

重点就是 
#pragma shader_feature CS_BOOL 
CustomEditor "TestShaderGUI"

shader_feature 是unity用来在shader中创建编译指令变量的关键字,它的作用与multi_compile几乎是一样的。 
我们通过创建的变量与TestShaderGUI类中创建的控件来相关联,达到传值的目的。 
CustomEditor的作用则是将shader文件与cs文件关联起来。

#pragma shader_feature#pragma multi_compile的问题可以看这里来进行了解,官方文档: 
http://docs.unity3d.com/Manual/SL-MultipleProgramVariants.html

这里说一下我的理解: 
首先#pragma shader_feature#pragma multi_compile的作用其实都是为了给unity所谓的"mega shaders""uber shaders"创建变量的。 
唯一的区别就是没有被使用过的shader_feature变量将不会被编译。 
所以在使用上区别就是在materials的作用范围内用shader_feature,而multi_compile的范围一般则是全局的。 
例如有一种全局变量是multi_compile_fog,则是跟开启雾效相关的。



第二种方法:

官方文档:http://docs.unity3d.com/ScriptReference/MaterialPropertyDrawer.html

Shader代码:

Shader "MyTest/TestShaderGUI"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}

        // 声明需要的控件
        [Toggle(S_BOOL)] _S_BOOL("S_BOOL", Int) = 0
        [Toggle] _MyToggle1("MyToggle1", Float) = 0
        [Toggle(MyToggle2)] _MyToggle2("MyToggle2", Float) = 0
        [KeywordEnum(One, Two, Three)] _MyEnum("MyEnum", Float) = 0
    }
    SubShader
    {
        Tags{ "RenderType" = "Opaque" }
        LOD 200

        CGPROGRAM

        #pragma surface surf Lambert addshadow

        // 创建变量,用来接收控件的值
        #pragma shader_feature S_BOOL
        #pragma shader_feature _MYTOGGLE1_ON
        #pragma shader_feature MyToggle2
        #pragma multi_compile _MYENUM_ONE _MYENUM_TWO _MYENUM_THREE

        sampler2D _MainTex;

        struct Input
        {
            float2 uv_MainTex;
        };

        void surf(Input IN, inout SurfaceOutput o)
        {
            half4 c = tex2D(_MainTex, IN.uv_MainTex);
            o.Albedo = c.rgb;
            o.Alpha = c.a;

            #if S_BOOL
            o.Albedo.gb *= 0.5;
            #endif

            //#if _MYTOGGLE1_ON
            //o.Albedo.gb *= 0.5;
            //#endif

            //#if MyToggle2
            //o.Albedo.gb *= 0.5;
            //#endif

            //#if _MYENUM_ONE
            //o.Albedo.gb *= 0.2;
            //#elif _MYENUM_TWO
            //o.Albedo.gb *= 0.5;
            //#elif _MYENUM_THREE
            //o.Albedo.gb *= 0.7;
            //#endif
        }

        ENDCG
    }
}

原链接:http://lib.csdn.net/article/unity3d/41995

时间: 2024-10-22 11:55:36

unity shader 编辑器扩展类 ShaderGUI的相关文章

Thinkphp编辑器扩展类kindeditor使用方法

一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp网站项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们复制到你的网站项目的ThinkPHP\Lib\ORG\Net 文件夹下. 2,editor文件夹是kindeditor的核心包.将其复制到你项目的Public文件夹下(和入口文件同级的那个Public),并在Public下再建立一个Upload文件夹,用于存放使用编辑器上传的图片. 3,KeditorAction.clas

Thinkphp编辑器扩展类kindeditor用法

一, 使用前的准备. 使用前请确认你已经建立好了一个Thinkphp站点项目. 1,Keditor.class.php和JSON.class.php 是编辑器扩展类文件,将他们拷贝到你的站点项目的ThinkPHP\Lib\ORG\Net 目录下. 2,editor目录是kindeditor的核心包.将其拷贝到你项目的Public目录下(和入口文件同级的那个Public),并在Public下再建立一个Upload目录.用于存放使用编辑器上传的图片. 3,KeditorAction.class.ph

Unity编辑器扩展chapter1

Unity编辑器扩展chapter1 unity通过提供EditorScript API 的方式为我们提供了方便强大的编辑器扩展途径.学好这一部分可以使我们学会编写一些工具来提高效率,甚至可以自制一些小的插件应用的项目工程中去,达到复用的目的.今天首先创建一个新场景生成的菜单项,生成的场景已经绑定好需要的游戏对象及脚本. Tips:1.官方API 2.编辑器扩展脚本都需放在Editor文件夹下,Editor的层级和数目没有要求 EditorUtil.cs :编辑器扩展类,向外部提供编辑器扩展方法

Unity 编辑器扩展 场景视图内控制对象

http://blog.csdn.net/akof1314/article/details/38129031 假设有一个敌人生成器类,其中有个属性range用来表示敌人生成的范围区域大小,那么可以用OnDrawGizmos函数来绘制它在场景视图所代表的区域大小,便于开发调试.这个敌人生成器类,类似如下: 12345678910111213141516171819   using UnityEngine;using System.Collections; public class EnemySpa

Unity编辑器扩展Texture显示选择框

学习NGUI插件的时候,突然间有一个问题为什么它这些属性可以通过弹出窗口来选中呢? 而我自己写的组件只能使用手动拖放的方式=.=. Unity开发了组件Inspector视图扩展API,如果我们要写插件方便别人来使用,使用编辑器扩展API让我们的组件显示的更华丽,使用方便 Texture弹出选择框选中图片赋值: 1个组件对应1个Edit扩展器,继承Editor必须让入Editor文件夹下 MyComponent: using UnityEngine; using System.Collectio

[cb]Unity Editor Toolbar 编辑器扩展

1.Apply to Prefab [把改动应用到Prefab] if (GUILayout.Button("Apply Collider To Prefab")) { PrefabUtility.ReplacePrefab(simActor.Preview, PrefabUtility.GetPrefabParent(simActor.Preview), ReplacePrefabOptions.ConnectToPrefab); }     2.Current SceneView

unity shader序列帧动画代码,顺便吐槽一下unity shader系统

http://www.cnblogs.com/hellohuan/archive/2014/01/10/3512784.html 一.看到UNITY论坛里有些人求unity shader序列帧动画,写shader我擅长啊,就顺势写了个CG的shader.代码很简单,就是变换UV采样序列帧贴图,美术配置行数列数以及变换速度. Shader "HELLOHUAN/Hello_Sequence" { Properties { _Color ("Main Color", C

《Unity Shader 与 计算机图形学》第二章

提示:本篇将会非常长~ 本系列文章分为 硬件 编程入门 工程实践 上一篇 主要介绍了GPU的特征工作原理 以及渲染的底层流程 其实对于新架构而言还有所不同 Shader描述了如何渲染物体的信息,包括: Texture Setup.纹理设置 Material Property.材质设置 Render State.渲染状态 Blend Setup.混合设置 Pixel Shader.像素着色 Vertex Shader.定点着色 Render Target Setup 渲染目标设置 Shader并不

Unity Shader入门精要学习笔记 - 第4章 学习 Shader 所需的数学基础

摘录自 冯乐乐的<Unity Shader入门精要> 笛卡尔坐标系 1)二维笛卡尔坐标系 在游戏制作中,我们使用的数学绝大部分都是计算位置.距离.角度等变量.而这些计算大部分都是在笛卡尔坐标系下进行的. 一个二维的笛卡尔坐标系包含了两个部分的信息: 一个特殊的位置,即原点,它是整个坐标系的中心. 两条过原点的互相垂直的矢量,即X轴和Y轴.这些坐标轴也被称为是该坐标的矢量. OpenGL 和 DirectX 使用了不同的二维笛卡尔坐标系.如下图所示: 2)三维笛卡尔坐标系 在三维笛卡尔坐标系中,