unity中shader Inspector 面板 的ui编写实现方法

一 Properties 类型

首先介绍下shader的属性类型,Properties属性会暴露给unity 的 inspactor面板,相当于程序接口

属性的结构:_CG变量名 (“unity可见的变量名”, 属性类型) = 值
例:_Color (“My Color”, Color) = (1, 1, 1, .5)

属性表

类型说明属性值
Int整型(.1, 2)
Float浮点数.5
Vector四维向量(.5, 1 , 1, 0.5)
Range范围1-2.3的浮点数(1, 2.3)
ColorRGBA颜色(1,1,1,.5)
2D2d贴图, 2d纹理,默认值可以为一个代表默认tint颜色的字符串,可以是空字符串或者”white”,”black”,”gray”,”bump”中的一个”white”{}
3D3d贴图
Cube6面立方贴图”white”{}
Rect矩形贴图”white”{}
二 Shader Inspactor面板

在材质中指定相关的shader后,点击材质就可以在unity的Inspactor面板中查看相关属性并作设置。
每个Shader属性在Inspactor面板里都有自己的UI表现形式。比如range是个滑杆,vector是四个输入框。但也有无法直接实现的。比如shader里是没有bool类型属性的,所以想要实现toggle这类的功能就需要配合宏和inspactor声明,通过声明一个Float参数来实现一个伪bool值。Inspactor面板会提供相应的toggle UI

Inspactor UI 定义方法
Properties
{
	//在inspactor面板中隐藏该属性
    [HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0
    //材质输入框,包含uv输入框
    _MainTex ("Texture", 2D) = "white" {}
    //该材质不会现实uv设置框
    [NoScaleOffset] _MainTex1 ("Texture", 2D) = "white" {}
    //该材质需要输入法线贴图
    [Normal] _Normal ("Normal", 2D) = "white" {}
    //该材质需要高动态范围HDR纹理
    [HDR] _HDR ("HDR", 2D) = "white" {}
    // 在UI中将一个float/vector属性指定为sRGB值(就像颜色一样),并且可能需要根据使用的颜色空间进行转换
    [Gamma] _Vector("Vector", Vector) = (1, 1, 1, 1) 
    //颜色输入框,分量值为r,g,b,a
    _Color ("Target Color", Color) = (1, 1, 1, 1) 
    //值为0-1的滑杆  Range(0, 1)里面的位数决定滑杆的颗粒度。
    _Range ("Range", Range(0, 1)) = 0.01
    //指数滑杆
    [PowerSlider(3.0)] _Brightness ("Brightness", Range (0.01, 1)) = 0.1
    //整数输入框
    _Int("Int", Int) = 1
    // 四维向量,分量值为x,y,z,w
    _Vector("Vector", Vector) = (1, 1, 1, 1) 
}
toggle勾选框

shader中没有bool类型,相关功能是靠float类型实现的。值得一提的是在shader中对比两个float是否相等是不可靠的。有可能会发生1.0 != 1.00 != 1/1的情况。所以最好使用相关函数帮助处理。详情请查看shader内置函数。

toggle勾选框
 Properties
 {
    //声明开关
    [Toggle] _Toggle("_Toggle", Float) = 1.0
 }
fixed4 frag (v2f i) : SV_Target
{
	//使用
	if(_Toggle){
          col = fixed4(1,0,0,1);
    }else{
          col = fixed4(0,1,0,1);
    }
}
MaterialToggle开关勾选框

Material布尔开关勾选框定义一个值为为1or0。该值可以在c#中通过material.setkey来控制

Properties{
   [HideInInspector] _WorkflowMode("WorkflowMode", Float) = 1.0
   // bool开关
   [MaterialToggle] _Toggle("Enable", Float) = 1
}
fixed4 frag (v2f i) : SV_Target
            {
                fixed4 col = tex2D(_MainTex, i.uv);
                // 作相应处理
                if(_Toggle==0){
                    col = fixed4(1,0,0,1);
                }else{
                    col = fixed4(0,1,0,1);
                }

Material宏开关勾选框

宏开关勾选框。勾选框的值是一个定义好的宏。宏不仅可以在pass中的任意位置使用,还可以在c#中通过material.setkey来控制

//第一步 声明开关
Properties{
	//声明ui开关:MaterialToggle,显示名为"Enable",值类型为Float,shader中使用的bool值:_TEX_ON
	[MaterialToggle(_TEX_ON)] _Toggle("Enable", Float) = 0
}
//第二步 声明宏
Pass{
   CGPROGRAM
   #pragma vertex vert
   #pragma fragment frag
   // 声明bool宏:_TEX_ON。 这个_TEX_ON宏不仅可以在pass中使用,还可以在c#中通过Material.setKey使用
   #pragma multi_compile _TEX_ON
// 第三步 在pass中的任意处使用
	//动态声明变量
	#if _TEX_ON
	sampler2D _MainTex;
    fixed4 _TargetColor;
	#endif
	fixed4 frag (v2f i) : SV_Target
    {
    	fixed4 col = tex2D(_MainTex, i.uv);
    	//动态处理代码片段
        #if _TEX_ON
            col = fixed4(1,0,0,1);
        #else
			col = fixed4(0,1,0,1);
		#endif
    };
    

下拉框

枚举属性会在inspactor面板下生成下拉框,值为浮点类型

使用unity内置的枚举

使用诸如blend 、cull 的内置属性生成下拉框。返回相应的foat值

Properties
{
		// 声明Unity内置的枚举类
		[Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("Src Blend Mode", Float) = 1
		[Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("Dst Blend Mode", Float) = 1
		[Enum(UnityEngine.Rendering.CullMode)] _Cull ("Cull Mode", Float) = 1
		[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest ("ZTest", Float) = 0
}
SubShader
{
		//使用枚举
		Tags { "Queue"="Transparent" "RenderType"="Transparent" }
		Blend [_SrcBlend] [_DstBlend]
		Cull [_Cull]
		ZTest [_ZTest]
		ZWrite [_ZWrite]
}
使用自定义枚举
Properties
{
	// 自定义枚举的名称数值对,最多支持7对
	[Enum(Off, 0, On, 1)] _Cull("ZWrite", Float) = 0
}
SubShader
{
	Cull [_Cull]
}	
使用关键字枚举
Properties
{
		// 声明枚举
		// 关键词格式为:"name" + _ + "枚举名称",必须大写。最多支持9个
		[KeywordEnum(None, A, B)] _Opt ("Opt mode", Float) = 0
}
SubShader
{
	// 声明枚举关键字
	#pragma multi_compile _Opt_NONE _Opt_A _Opt_B
	fixed4 frag (v2f i) : SV_Target
	{
		fixed4 secCol = tex2D(_SecondTex, i.uv.zw);
		// 使用关键字枚举
		#if _Opt_NONE 
			col += secCol;
		#elif _Opt_A 
			col *= secCol;
		#endif
		return col;
	}
}	

使用cs脚本扩展shader面板ui

使用cs脚本也可以控制shader gui
首先建立shader gui的edtor脚本

using System;
using UnityEngine;
using UnityEditor;

public class MyShaderGUI : ShaderGUI
{
    public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties)
    {
        // 渲染shader自带的ui
        base.OnGUI(materialEditor, properties);
		// 当前关联的材质
        Material targetMat = materialEditor.target as Material;
		// 定义勾选框变量
        bool CS_BOOL = Array.IndexOf(targetMat.shaderKeywords, "CS_BOOL") != -1;
		// 发生改变后
        EditorGUI.BeginChangeCheck();
        CS_BOOL = EditorGUILayout.Toggle("CS_BOOL", CS_BOOL);

        if (EditorGUI.EndChangeCheck())
        {
            //控制shader中的变量
            if (CS_BOOL)
                targetMat.EnableKeyword("CS_BOOL");
            else
                targetMat.DisableKeyword("CS_BOOL");
        }
    }
}

然后在shader中引用edtor脚本和shader变量

Shader "Custom/MyShaderGUI"
{
    Properties
    {
        _MainTex("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags{ "RenderType" = "Opaque" }
        LOD 200
        CGPROGRAM
        #pragma surface surf Lambert addshadow
        // 创建被cs脚本引用的宏
        #pragma shader_feature CS_BOOL
        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;
			// 使用 脚本宏控制bool变量
            #if CS_BOOL
            o.Albedo.a = 0;
            #endif
        }
        ENDCG
    }
    // 关联gui cs脚本
    CustomEditor "MyShaderGUI"
}
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

千年奇葩

从来没受过打赏,这玩意好吃吗?

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

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

打赏作者

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

抵扣说明:

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

余额充值