您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
291 行
13 KiB
291 行
13 KiB
using System;
|
|
using UnityEditor;
|
|
using UnityEngine;
|
|
using UnityEditor.Experimental.Rendering.LightweightPipeline;
|
|
using UnityEngine.Experimental.Rendering;
|
|
|
|
public class LightweightStandardSimpleLightingGUI : LightweightShaderGUI
|
|
{
|
|
private const float kMinShininessValue = 0.01f;
|
|
private MaterialProperty blendModeProp;
|
|
private MaterialProperty albedoMapProp;
|
|
private MaterialProperty albedoColorProp;
|
|
private MaterialProperty alphaCutoffProp;
|
|
private MaterialProperty specularSourceProp;
|
|
private MaterialProperty glossinessSourceProp;
|
|
private MaterialProperty specularGlossMapProp;
|
|
private MaterialProperty specularColorProp;
|
|
private MaterialProperty shininessProp;
|
|
private MaterialProperty bumpMapProp;
|
|
private MaterialProperty emissionMapProp;
|
|
private MaterialProperty emissionColorProp;
|
|
|
|
private static class Styles
|
|
{
|
|
public static GUIContent[] albedoGlosinessLabels =
|
|
{
|
|
new GUIContent("Base (RGB) Glossiness (A)", "Base Color (RGB) and Glossiness (A)"),
|
|
new GUIContent("Base (RGB)", "Base Color (RGB)")
|
|
};
|
|
|
|
public static GUIContent albedoAlphaLabel = new GUIContent("Base (RGB) Alpha (A)",
|
|
"Base Color (RGB) and Transparency (A)");
|
|
|
|
public static GUIContent[] specularGlossMapLabels =
|
|
{
|
|
new GUIContent("Specular Map (RGB)", "Specular Color (RGB)"),
|
|
new GUIContent("Specular Map (RGB) Glossiness (A)", "Specular Color (RGB) Glossiness (A)")
|
|
};
|
|
|
|
public static GUIContent normalMapText = new GUIContent("Normal Map", "Normal Map");
|
|
public static GUIContent emissionMapLabel = new GUIContent("Emission Map", "Emission Map");
|
|
|
|
public static readonly string[] blendNames = Enum.GetNames(typeof(UpgradeBlendMode));
|
|
public static readonly string[] glossinessSourceNames = Enum.GetNames(typeof(GlossinessSource));
|
|
|
|
public static string renderingModeLabel = "Rendering Mode";
|
|
public static string specularSourceLabel = "Specular";
|
|
public static string glossinessSourceLabel = "Glossiness Source";
|
|
public static string glossinessSource = "Glossiness Source";
|
|
public static string albedoColorLabel = "Base Color";
|
|
public static string albedoMapAlphaLabel = "Base(RGB) Alpha(A)";
|
|
public static string albedoMapGlossinessLabel = "Base(RGB) Glossiness (A)";
|
|
public static string alphaCutoffLabel = "Alpha Cutoff";
|
|
public static string shininessLabel = "Shininess";
|
|
public static string normalMapLabel = "Normal map";
|
|
public static string emissionColorLabel = "Emission Color";
|
|
public static string advancedText = "Advanced Options";
|
|
}
|
|
|
|
public override void FindProperties(MaterialProperty[] properties)
|
|
{
|
|
blendModeProp = FindProperty("_Mode", properties);
|
|
albedoMapProp = FindProperty("_MainTex", properties);
|
|
albedoColorProp = FindProperty("_Color", properties);
|
|
|
|
alphaCutoffProp = FindProperty("_Cutoff", properties);
|
|
specularSourceProp = FindProperty("_SpecSource", properties);
|
|
glossinessSourceProp = FindProperty("_GlossinessSource", properties);
|
|
specularGlossMapProp = FindProperty("_SpecGlossMap", properties);
|
|
specularColorProp = FindProperty("_SpecColor", properties);
|
|
shininessProp = FindProperty("_Shininess", properties);
|
|
bumpMapProp = FindProperty("_BumpMap", properties);
|
|
emissionMapProp = FindProperty("_EmissionMap", properties);
|
|
emissionColorProp = FindProperty("_EmissionColor", properties);
|
|
}
|
|
|
|
public override void ShaderPropertiesGUI(Material material)
|
|
{
|
|
EditorGUI.BeginChangeCheck();
|
|
{
|
|
DoBlendMode();
|
|
|
|
EditorGUILayout.Space();
|
|
DoSpecular();
|
|
|
|
EditorGUILayout.Space();
|
|
m_MaterialEditor.TexturePropertySingleLine(Styles.normalMapText, bumpMapProp);
|
|
|
|
EditorGUILayout.Space();
|
|
DoEmissionArea(material);
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
m_MaterialEditor.TextureScaleOffsetProperty(albedoMapProp);
|
|
if (EditorGUI.EndChangeCheck())
|
|
emissionMapProp.textureScaleAndOffset = albedoMapProp.textureScaleAndOffset; // Apply the main texture scale and offset to the emission texture as well, for Enlighten's sake
|
|
|
|
GUILayout.Label(Styles.advancedText, EditorStyles.boldLabel);
|
|
EditorGUI.indentLevel++;
|
|
m_MaterialEditor.EnableInstancingField();
|
|
EditorGUI.indentLevel--;
|
|
}
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
foreach (var obj in blendModeProp.targets)
|
|
MaterialChanged((Material)obj);
|
|
}
|
|
|
|
EditorGUILayout.Space();
|
|
EditorGUILayout.Space();
|
|
}
|
|
|
|
public override void MaterialChanged(Material material)
|
|
{
|
|
material.shaderKeywords = null;
|
|
SetupMaterialBlendMode(material);
|
|
SetMaterialKeywords(material);
|
|
}
|
|
|
|
private void SetMaterialKeywords(Material material)
|
|
{
|
|
material.shaderKeywords = null;
|
|
SetupMaterialBlendMode(material);
|
|
UpdateMaterialSpecularSource(material);
|
|
CoreUtils.SetKeyword(material, "_NORMALMAP", material.GetTexture("_BumpMap"));
|
|
|
|
// A material's GI flag internally keeps track of whether emission is enabled at all, it's enabled but has no effect
|
|
// or is enabled and may be modified at runtime. This state depends on the values of the current flag and emissive color.
|
|
// The fixup routine makes sure that the material is in the correct state if/when changes are made to the mode or color.
|
|
MaterialEditor.FixupEmissiveFlag(material);
|
|
bool shouldEmissionBeEnabled = (material.globalIlluminationFlags & MaterialGlobalIlluminationFlags.EmissiveIsBlack) == 0;
|
|
CoreUtils.SetKeyword(material, "_EMISSION", shouldEmissionBeEnabled);
|
|
}
|
|
|
|
private void UpdateMaterialSpecularSource(Material material)
|
|
{
|
|
SpecularSource specSource = (SpecularSource)material.GetFloat("_SpecSource");
|
|
if (specSource == SpecularSource.NoSpecular)
|
|
{
|
|
CoreUtils.SetKeyword(material, "_SPECGLOSSMAP", false);
|
|
CoreUtils.SetKeyword(material, "_SPECULAR_COLOR", false);
|
|
CoreUtils.SetKeyword(material, "_GLOSSINESS_FROM_BASE_ALPHA", false);
|
|
}
|
|
else
|
|
{
|
|
GlossinessSource glossSource = (GlossinessSource)material.GetFloat("_GlossinessSource");
|
|
bool hasGlossMap = material.GetTexture("_SpecGlossMap");
|
|
CoreUtils.SetKeyword(material, "_SPECGLOSSMAP", hasGlossMap);
|
|
CoreUtils.SetKeyword(material, "_SPECULAR_COLOR", !hasGlossMap);
|
|
CoreUtils.SetKeyword(material, "_GLOSSINESS_FROM_BASE_ALPHA", glossSource == GlossinessSource.BaseAlpha);
|
|
}
|
|
}
|
|
|
|
public override void AssignNewShaderToMaterial(Material material, Shader oldShader, Shader newShader)
|
|
{
|
|
base.AssignNewShaderToMaterial(material, oldShader, newShader);
|
|
|
|
// Shininess value cannot be zero since it will produce undefined values for cases where pow(0, 0).
|
|
float shininess = material.GetFloat("_Shininess");
|
|
material.SetFloat("_Shininess", Mathf.Clamp(shininess, kMinShininessValue, 1.0f));
|
|
|
|
string oldShaderName = oldShader.name;
|
|
string[] shaderStrings = oldShaderName.Split('/');
|
|
|
|
if (shaderStrings[0].Equals("Legacy Shaders") || shaderStrings[0].Equals("Mobile"))
|
|
{
|
|
ConvertFromLegacy(material, oldShaderName);
|
|
}
|
|
|
|
StandardSimpleLightingUpgrader.UpdateMaterialKeywords(material);
|
|
}
|
|
|
|
private void DoBlendMode()
|
|
{
|
|
int modeValue = (int)blendModeProp.floatValue;
|
|
EditorGUI.BeginChangeCheck();
|
|
modeValue = EditorGUILayout.Popup(Styles.renderingModeLabel, modeValue, Styles.blendNames);
|
|
if (EditorGUI.EndChangeCheck())
|
|
blendModeProp.floatValue = modeValue;
|
|
|
|
UpgradeBlendMode mode = (UpgradeBlendMode)blendModeProp.floatValue;
|
|
|
|
EditorGUILayout.Space();
|
|
|
|
if (mode == UpgradeBlendMode.Opaque)
|
|
{
|
|
int glossSource = (int)glossinessSourceProp.floatValue;
|
|
m_MaterialEditor.TexturePropertySingleLine(Styles.albedoGlosinessLabels[glossSource], albedoMapProp,
|
|
albedoColorProp);
|
|
m_MaterialEditor.TextureScaleOffsetProperty(albedoMapProp);
|
|
}
|
|
else
|
|
{
|
|
m_MaterialEditor.TexturePropertySingleLine(Styles.albedoAlphaLabel, albedoMapProp, albedoColorProp);
|
|
if (mode == UpgradeBlendMode.Cutout)
|
|
m_MaterialEditor.RangeProperty(alphaCutoffProp, "Cutoff");
|
|
}
|
|
}
|
|
|
|
private void DoSpecular()
|
|
{
|
|
EditorGUILayout.Space();
|
|
|
|
SpecularSource specularSource = (SpecularSource)specularSourceProp.floatValue;
|
|
EditorGUI.BeginChangeCheck();
|
|
bool enabled = EditorGUILayout.Toggle(Styles.specularSourceLabel, specularSource == SpecularSource.SpecularTextureAndColor);
|
|
if (EditorGUI.EndChangeCheck())
|
|
specularSourceProp.floatValue = enabled ? (float)SpecularSource.SpecularTextureAndColor : (float)SpecularSource.NoSpecular;
|
|
|
|
SpecularSource specSource = (SpecularSource)specularSourceProp.floatValue;
|
|
if (specSource != SpecularSource.NoSpecular)
|
|
{
|
|
bool hasSpecularMap = specularGlossMapProp.textureValue != null;
|
|
m_MaterialEditor.TexturePropertySingleLine(Styles.specularGlossMapLabels[(int)glossinessSourceProp.floatValue], specularGlossMapProp, hasSpecularMap ? null : specularColorProp);
|
|
|
|
EditorGUI.indentLevel += 2;
|
|
GUI.enabled = hasSpecularMap;
|
|
int glossinessSource = hasSpecularMap ? (int)glossinessSourceProp.floatValue : (int)GlossinessSource.BaseAlpha;
|
|
EditorGUI.BeginChangeCheck();
|
|
glossinessSource = EditorGUILayout.Popup(Styles.glossinessSourceLabel, glossinessSource, Styles.glossinessSourceNames);
|
|
if (EditorGUI.EndChangeCheck())
|
|
glossinessSourceProp.floatValue = glossinessSource;
|
|
GUI.enabled = true;
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
float shininess = EditorGUILayout.Slider(Styles.shininessLabel, shininessProp.floatValue,
|
|
kMinShininessValue, 1.0f);
|
|
if (EditorGUI.EndChangeCheck())
|
|
shininessProp.floatValue = shininess;
|
|
EditorGUI.indentLevel -= 2;
|
|
}
|
|
}
|
|
|
|
void DoEmissionArea(Material material)
|
|
{
|
|
// Emission for GI?
|
|
if (m_MaterialEditor.EmissionEnabledProperty())
|
|
{
|
|
bool hadEmissionTexture = emissionMapProp.textureValue != null;
|
|
|
|
// Texture and HDR color controls
|
|
m_MaterialEditor.TexturePropertyWithHDRColor(Styles.emissionMapLabel, emissionMapProp, emissionColorProp, false);
|
|
|
|
// If texture was assigned and color was black set color to white
|
|
float brightness = emissionColorProp.colorValue.maxColorComponent;
|
|
if (emissionMapProp.textureValue != null && !hadEmissionTexture && brightness <= 0f)
|
|
emissionColorProp.colorValue = Color.white;
|
|
|
|
// LW does not support RealtimeEmissive. We set it to bake emissive and handle the emissive is black right.
|
|
material.globalIlluminationFlags = MaterialGlobalIlluminationFlags.BakedEmissive;
|
|
if (brightness <= 0f)
|
|
material.globalIlluminationFlags |= MaterialGlobalIlluminationFlags.EmissiveIsBlack;
|
|
}
|
|
}
|
|
|
|
private void ConvertFromLegacy(Material material, string oldShaderName)
|
|
{
|
|
UpgradeParams shaderUpgradeParams;
|
|
|
|
if (oldShaderName.Contains("Transp"))
|
|
{
|
|
shaderUpgradeParams.blendMode = UpgradeBlendMode.Alpha;
|
|
shaderUpgradeParams.glosinessSource = GlossinessSource.SpecularAlpha;
|
|
}
|
|
else if (oldShaderName.Contains("Cutout"))
|
|
{
|
|
shaderUpgradeParams.blendMode = UpgradeBlendMode.Cutout;
|
|
shaderUpgradeParams.glosinessSource = GlossinessSource.SpecularAlpha;
|
|
}
|
|
else
|
|
{
|
|
shaderUpgradeParams.blendMode = UpgradeBlendMode.Opaque;
|
|
shaderUpgradeParams.glosinessSource = GlossinessSource.BaseAlpha;
|
|
}
|
|
|
|
if (oldShaderName.Contains("Spec"))
|
|
shaderUpgradeParams.specularSource = SpecularSource.SpecularTextureAndColor;
|
|
else
|
|
shaderUpgradeParams.specularSource = SpecularSource.NoSpecular;
|
|
|
|
material.SetFloat("_Mode", (float)shaderUpgradeParams.blendMode);
|
|
material.SetFloat("_SpecSource", (float)shaderUpgradeParams.specularSource);
|
|
material.SetFloat("_GlossinessSource", (float)shaderUpgradeParams.glosinessSource);
|
|
|
|
if (oldShaderName.Contains("Self-Illumin"))
|
|
{
|
|
material.SetTexture("_EmissionMap", material.GetTexture("_MainTex"));
|
|
material.SetTexture("_MainTex", null);
|
|
material.SetColor("_EmissionColor", Color.white);
|
|
}
|
|
}
|
|
}
|