目的
在项目中,我们经常会通过修改材质球属性,为了达到一些炫酷,甚至不炫酷的效果,这里面有几个注意事项,下面会一一说明,当然这种切属性的方式比较简单,我们通常直接使用setfolat,setcolor等函数就可以直接修改,因为修改的时候,材质球会实例化一次,所以在运行中的修改不会修改正常的材质球资源,
注意
- meshrender.materal的时候,你的材质球就回实例化一份,不会影响你的资源,
- 如果你想在运行的状态下,修改你的材质球资源,就选择共享材质,就可以修改了
- 一般不使用修改材质球shader的方法,一般使用的方式是直接使用两个材质球互相切换,
- 有一些特殊的环境下是必须通过属性修改的,那么我们怎么去使用呢,就强行改shader就可以了,那也是这篇博客主要介绍的东西.
修改RenderingMode
要修改这个地方,我们应该怎么做处理呢,我们首先下载官方的shader包,
打开这个资源包,我们找一个脚本文件叫做StandardShaderGUI.cs
打开之后可以看到官方对这个操作的代码
但是他这里面没有对,我们把这个代码使用在项目中,发现了一个很重要的问题:
我们可以修改他的渲染模式,但是我们无法得到他当前是什么渲染模式,我们把inspector打开debug模式
发现他主要是通过这个float值来判断当前是否改变的,所以我们去get这个值,但是发现如果是通过代码修改的渲染模式,无法修改这个值,所以我们只要加入这个_mode的赋值代码,就可以得到了
下面来看一下具体代码
封装代码
using System;
using UnityEngine;
namespace xxl.才哥牛逼
{
public class FuckStandardShader
{
public Material m_mat;
public enum BlendMode
{
Opaque = 0,
Cutout = 1,
Fade = 2, // Old school alpha-blending mode, fresnel does not affect amount of transparency
Transparent = 3 // Physically plausible transparency mode, implemented as alpha pre-multiply
}
public static BlendMode GetRenderingMode(Material material)
{
return (BlendMode)Enum.ToObject(typeof(BlendMode), material.GetFloat("_Mode"));
}
public static void SetupMaterialWithBlendMode(Material material, BlendMode blendMode)
{
switch (blendMode)
{
case BlendMode.Opaque:
material.SetOverrideTag("RenderType", "");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.DisableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = -1;
material.SetFloat("_Mode", 0);
break;
case BlendMode.Cutout:
material.SetOverrideTag("RenderType", "TransparentCutout");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero);
material.SetInt("_ZWrite", 1);
material.EnableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.AlphaTest;
material.SetFloat("_Mode", 1);
break;
case BlendMode.Fade:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHATEST_ON");
material.EnableKeyword("_ALPHABLEND_ON");
material.DisableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetFloat("_Mode", 2);
break;
case BlendMode.Transparent:
material.SetOverrideTag("RenderType", "Transparent");
material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One);
material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha);
material.SetInt("_ZWrite", 0);
material.DisableKeyword("_ALPHATEST_ON");
material.DisableKeyword("_ALPHABLEND_ON");
material.EnableKeyword("_ALPHAPREMULTIPLY_ON");
material.renderQueue = (int)UnityEngine.Rendering.RenderQueue.Transparent;
material.SetFloat("_Mode", 3);
break;
}
}
}
}
demo使用
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SetRenderingMode : MonoBehaviour
{
private void OnMouseDown()
{
xxl.才哥牛逼.FuckStandardShader.BlendMode v_bm = (xxl.才哥牛逼.FuckStandardShader.BlendMode)UnityEngine.Random.Range(0, 4);
Debug.LogError(v_bm);
xxl.才哥牛逼.FuckStandardShader.SetupMaterialWithBlendMode(GetComponent<MeshRenderer>().material, v_bm);
}
}