2023-12-15 00:08:02 +08:00
#if UNITY_EDITOR
// Disable 'obsolete' warnings
#pragma warning disable 0618
#pragma warning disable 0612
2023-10-20 19:31:12 +08:00
using System ;
using UnityEngine ;
2023-12-15 00:08:02 +08:00
namespace UnityEditor
2023-10-20 19:31:12 +08:00
{
2023-12-15 00:08:02 +08:00
public class BakeryShaderGUI : ShaderGUI
2023-10-20 19:31:12 +08:00
{
private enum WorkflowMode
{
Specular ,
Metallic ,
Dielectric
}
public enum BlendMode
{
Opaque ,
Cutout ,
2023-12-15 00:08:02 +08:00
Fade , // Old school alpha-blending mode, fresnel does not affect amount of transparency
2023-10-20 19:31:12 +08:00
Transparent // Physically plausible transparency mode, implemented as alpha pre-multiply
}
public enum SmoothnessMapChannel
{
SpecularMetallicAlpha ,
AlbedoAlpha ,
}
private static class Styles
{
2023-12-15 00:08:02 +08:00
public static GUIStyle optionsButton = "PaneOptions" ;
2023-10-20 19:31:12 +08:00
public static GUIContent uvSetLabel = new GUIContent ( "UV Set" ) ;
2023-12-15 00:08:02 +08:00
public static GUIContent [ ] uvSetOptions = new GUIContent [ ] { new GUIContent ( "UV channel 0" ) , new GUIContent ( "UV channel 1" ) } ;
2023-10-20 19:31:12 +08:00
2023-12-15 00:08:02 +08:00
public static string emptyTootip = "" ;
2023-10-20 19:31:12 +08:00
public static GUIContent albedoText = new GUIContent ( "Albedo" , "Albedo (RGB) and Transparency (A)" ) ;
public static GUIContent alphaCutoffText = new GUIContent ( "Alpha Cutoff" , "Threshold for alpha cutoff" ) ;
public static GUIContent specularMapText = new GUIContent ( "Specular" , "Specular (RGB) and Smoothness (A)" ) ;
public static GUIContent metallicMapText = new GUIContent ( "Metallic" , "Metallic (R) and Smoothness (A)" ) ;
public static GUIContent smoothnessText = new GUIContent ( "Smoothness" , "Smoothness value" ) ;
public static GUIContent smoothnessScaleText = new GUIContent ( "Smoothness" , "Smoothness scale factor" ) ;
public static GUIContent smoothnessMapChannelText = new GUIContent ( "Source" , "Smoothness texture and channel" ) ;
public static GUIContent highlightsText = new GUIContent ( "Specular Highlights" , "Specular Highlights" ) ;
public static GUIContent reflectionsText = new GUIContent ( "Reflections" , "Glossy Reflections" ) ;
public static GUIContent normalMapText = new GUIContent ( "Normal Map" , "Normal Map" ) ;
public static GUIContent heightMapText = new GUIContent ( "Height Map" , "Height Map (G)" ) ;
public static GUIContent occlusionText = new GUIContent ( "Occlusion" , "Occlusion (G)" ) ;
2023-12-15 00:08:02 +08:00
public static GUIContent emissionText = new GUIContent ( "Emission" , "Emission (RGB)" ) ;
2023-10-20 19:31:12 +08:00
public static GUIContent detailMaskText = new GUIContent ( "Detail Mask" , "Mask for Secondary Maps (A)" ) ;
public static GUIContent detailAlbedoText = new GUIContent ( "Detail Albedo x2" , "Albedo (RGB) multiplied by 2" ) ;
public static GUIContent detailNormalMapText = new GUIContent ( "Normal Map" , "Normal Map" ) ;
2023-12-15 00:08:02 +08:00
public static string whiteSpaceString = " " ;
2023-10-20 19:31:12 +08:00
public static string primaryMapsText = "Main Maps" ;
public static string secondaryMapsText = "Secondary Maps" ;
public static string forwardText = "Forward Rendering Options" ;
public static string renderingMode = "Rendering Mode" ;
2023-12-15 00:08:02 +08:00
public static GUIContent emissiveWarning = new GUIContent ( "Emissive value is animated but the material has not been configured to support emissive. Please make sure the material itself has some amount of emissive." ) ;
public static GUIContent emissiveColorWarning = new GUIContent ( "Ensure emissive color is non-black for emission to have effect." ) ;
2023-10-20 19:31:12 +08:00
public static readonly string [ ] blendNames = Enum . GetNames ( typeof ( BlendMode ) ) ;
2023-12-15 00:08:02 +08:00
public static string bakeryText = "Bakery Options" ;
public static GUIContent doubleSidedLabel = new GUIContent ( "Double-sided" , "Render both sides of triangles." ) ;
public static GUIContent vertexLMLabel = new GUIContent ( "Allow Vertex Lightmaps" , "Allows this material to use vertex lightmaps, if present." ) ;
public static GUIContent vertexLMdirLabel = new GUIContent ( "Enable VertexLM directional" , "Enables directional vertex lightmaps." ) ;
public static GUIContent vertexLMSHLabel = new GUIContent ( "Enable VertexLM SH" , "Enables SH vertex lightmaps." ) ;
public static GUIContent vertexLMMaskLabel = new GUIContent ( "Enable VertexLM Shadowmask" , "Enables per-vertex shadowmasks." ) ;
public static GUIContent rnmLabel = new GUIContent ( "Allow RNM Lightmaps" , "Allows this material to use RNM lightmaps, if present." ) ;
public static GUIContent shLabel = new GUIContent ( "Allow SH Lightmaps" , "Allows this material to use SH lightmaps, if present." ) ;
public static GUIContent monoshLabel = new GUIContent ( "Enable MonoSH" , "Makes this material treat directional maps as MonoSH." ) ;
public static GUIContent shnLabel = new GUIContent ( "Non-linear SH" , "This option can enhance contrast (closer to ground truth), but it makes the shader a bit slower." ) ;
public static GUIContent specLabel = new GUIContent ( "Enable Lightmap Specular" , "Enables baked specular for all directional modes." ) ;
2024-02-05 21:16:08 +08:00
public static GUIContent specOcclusionLabel = new GUIContent ( "Use Lightmap Specular as Reflection Occlusion" , "Uses baked specular as a mask for reflection probes." ) ;
2023-12-15 00:08:02 +08:00
public static GUIContent bicubicLabel = new GUIContent ( "Force Bicubic Filter" , "Enables bicubic filtering for all lightmaps (color/shadowmask/direction/etc) used in the material." ) ;
public static GUIContent pshnLabel = new GUIContent ( "Non-linear Light Probe SH" , "Prevents negative values in light probes. This is recommended when baking probes in L1 mode. Can slow down the shader a bit." ) ;
public static GUIContent volLabel = new GUIContent ( "Enable Volumes" , "Enable usages of BakeryVolumes" ) ;
public static GUIContent volLabelRot = new GUIContent ( "Support Volume Rotation" , "Normally volumes can only be repositioned or rescaled at runtime. With this checkbox volume's rotation matrix will also be used. Volumes must have a similar checkbox enabled." ) ;
public static GUIContent volLabel0 = new GUIContent ( "Volume 0" ) ;
public static GUIContent volLabel1 = new GUIContent ( "Volume 1" ) ;
public static GUIContent volLabel2 = new GUIContent ( "Volume 2" ) ;
public static GUIContent volLabelMask = new GUIContent ( "Volume mask" ) ;
2023-10-20 19:31:12 +08:00
}
MaterialProperty blendMode = null ;
MaterialProperty albedoMap = null ;
MaterialProperty albedoColor = null ;
MaterialProperty alphaCutoff = null ;
MaterialProperty specularMap = null ;
MaterialProperty specularColor = null ;
MaterialProperty metallicMap = null ;
MaterialProperty metallic = null ;
MaterialProperty smoothness = null ;
MaterialProperty smoothnessScale = null ;
MaterialProperty smoothnessMapChannel = null ;
MaterialProperty highlights = null ;
MaterialProperty reflections = null ;
MaterialProperty bumpScale = null ;
MaterialProperty bumpMap = null ;
MaterialProperty occlusionStrength = null ;
MaterialProperty occlusionMap = null ;
MaterialProperty heigtMapScale = null ;
MaterialProperty heightMap = null ;
MaterialProperty emissionColorForRendering = null ;
MaterialProperty emissionMap = null ;
MaterialProperty detailMask = null ;
MaterialProperty detailAlbedoMap = null ;
MaterialProperty detailNormalMapScale = null ;
MaterialProperty detailNormalMap = null ;
MaterialProperty uvSetSecondary = null ;
2023-12-15 00:08:02 +08:00
MaterialProperty enableDoubleSided = null ;
MaterialProperty enableDoubleSidedOn = null ;
MaterialProperty enableVertexLM = null ;
MaterialProperty enableVertexLMdir = null ;
MaterialProperty enableVertexLMSH = null ;
MaterialProperty enableVertexLMmask = null ;
MaterialProperty enableSH = null ;
MaterialProperty enableMonoSH = null ;
MaterialProperty enableSHN = null ;
MaterialProperty enableRNM = null ;
MaterialProperty enableSpec = null ;
2024-02-05 21:16:08 +08:00
MaterialProperty enableSpecOcclusion = null ;
2023-12-15 00:08:02 +08:00
MaterialProperty enableBicubic = null ;
MaterialProperty enablePSHN = null ;
MaterialProperty enableVolumes = null ;
MaterialProperty enableVolumeRot = null ;
MaterialProperty volume0 = null ;
MaterialProperty volume1 = null ;
MaterialProperty volume2 = null ;
MaterialProperty volumeMask = null ;
MaterialProperty volumeMin = null ;
MaterialProperty volumeInvSize = null ;
BakeryVolume assignedVolume = null ;
2023-10-20 19:31:12 +08:00
MaterialEditor m_MaterialEditor ;
WorkflowMode m_WorkflowMode = WorkflowMode . Specular ;
2023-12-15 00:08:02 +08:00
ColorPickerHDRConfig m_ColorPickerHDRConfig = new ColorPickerHDRConfig ( 0f , 99f , 1 / 99f , 3f ) ;
2023-10-20 19:31:12 +08:00
bool m_FirstTimeApply = true ;
public void FindProperties ( MaterialProperty [ ] props )
{
blendMode = FindProperty ( "_Mode" , props ) ;
albedoMap = FindProperty ( "_MainTex" , props ) ;
albedoColor = FindProperty ( "_Color" , props ) ;
alphaCutoff = FindProperty ( "_Cutoff" , props ) ;
specularMap = FindProperty ( "_SpecGlossMap" , props , false ) ;
specularColor = FindProperty ( "_SpecColor" , props , false ) ;
metallicMap = FindProperty ( "_MetallicGlossMap" , props , false ) ;
metallic = FindProperty ( "_Metallic" , props , false ) ;
if ( specularMap ! = null & & specularColor ! = null )
m_WorkflowMode = WorkflowMode . Specular ;
else if ( metallicMap ! = null & & metallic ! = null )
m_WorkflowMode = WorkflowMode . Metallic ;
else
m_WorkflowMode = WorkflowMode . Dielectric ;
smoothness = FindProperty ( "_Glossiness" , props ) ;
smoothnessScale = FindProperty ( "_GlossMapScale" , props , false ) ;
smoothnessMapChannel = FindProperty ( "_SmoothnessTextureChannel" , props , false ) ;
highlights = FindProperty ( "_SpecularHighlights" , props , false ) ;
reflections = FindProperty ( "_GlossyReflections" , props , false ) ;
bumpScale = FindProperty ( "_BumpScale" , props ) ;
bumpMap = FindProperty ( "_BumpMap" , props ) ;
heigtMapScale = FindProperty ( "_Parallax" , props ) ;
heightMap = FindProperty ( "_ParallaxMap" , props ) ;
occlusionStrength = FindProperty ( "_OcclusionStrength" , props ) ;
occlusionMap = FindProperty ( "_OcclusionMap" , props ) ;
emissionColorForRendering = FindProperty ( "_EmissionColor" , props ) ;
emissionMap = FindProperty ( "_EmissionMap" , props ) ;
detailMask = FindProperty ( "_DetailMask" , props ) ;
detailAlbedoMap = FindProperty ( "_DetailAlbedoMap" , props ) ;
detailNormalMapScale = FindProperty ( "_DetailNormalMapScale" , props ) ;
detailNormalMap = FindProperty ( "_DetailNormalMap" , props ) ;
uvSetSecondary = FindProperty ( "_UVSec" , props ) ;
2023-12-15 00:08:02 +08:00
enableDoubleSided = FindProperty ( "_BAKERY_2SIDED" , props ) ;
enableDoubleSidedOn = FindProperty ( "_BAKERY_2SIDEDON" , props ) ;
enableVertexLM = FindProperty ( "_BAKERY_VERTEXLM" , props ) ;
enableVertexLMdir = FindProperty ( "_BAKERY_VERTEXLMDIR" , props ) ;
enableVertexLMSH = FindProperty ( "_BAKERY_VERTEXLMSH" , props ) ;
enableVertexLMmask = FindProperty ( "_BAKERY_VERTEXLMMASK" , props ) ;
enableSH = FindProperty ( "_BAKERY_SH" , props ) ;
enableMonoSH = FindProperty ( "_BAKERY_MONOSH" , props ) ;
enableSHN = FindProperty ( "_BAKERY_SHNONLINEAR" , props ) ;
enableRNM = FindProperty ( "_BAKERY_RNM" , props ) ;
enableSpec = FindProperty ( "_BAKERY_LMSPEC" , props ) ;
2024-02-05 21:16:08 +08:00
enableSpecOcclusion = FindProperty ( "_BAKERY_LMSPECOCCLUSION" , props ) ;
2023-12-15 00:08:02 +08:00
enableBicubic = FindProperty ( "_BAKERY_BICUBIC" , props ) ;
enablePSHN = FindProperty ( "_BAKERY_PROBESHNONLINEAR" , props ) ;
try
{
enableVolumes = FindProperty ( "_BAKERY_VOLUME" , props ) ;
enableVolumeRot = FindProperty ( "_BAKERY_VOLROTATION" , props ) ;
volume0 = FindProperty ( "_Volume0" , props ) ;
volume1 = FindProperty ( "_Volume1" , props ) ;
volume2 = FindProperty ( "_Volume2" , props ) ;
volumeMask = FindProperty ( "_VolumeMask" , props ) ;
volumeMin = FindProperty ( "_VolumeMin" , props ) ;
volumeInvSize = FindProperty ( "_VolumeInvSize" , props ) ;
}
catch
{
}
2023-10-20 19:31:12 +08:00
}
public override void OnGUI ( MaterialEditor materialEditor , MaterialProperty [ ] props )
{
FindProperties ( props ) ; // MaterialProperties can be animated so we do not cache them but fetch them every event to ensure animated values are updated correctly
m_MaterialEditor = materialEditor ;
Material material = materialEditor . target as Material ;
2023-12-15 00:08:02 +08:00
// Make sure that needed keywords are set up if we're switching some existing
2023-10-20 19:31:12 +08:00
// material to a standard shader.
if ( m_FirstTimeApply )
{
2023-12-15 00:08:02 +08:00
SetMaterialKeywords ( material , m_WorkflowMode ) ;
2023-10-20 19:31:12 +08:00
m_FirstTimeApply = false ;
}
ShaderPropertiesGUI ( material ) ;
}
public void ShaderPropertiesGUI ( Material material )
{
// Use default labelWidth
EditorGUIUtility . labelWidth = 0f ;
// Detect any changes to the material
EditorGUI . BeginChangeCheck ( ) ;
{
BlendModePopup ( ) ;
// Primary properties
GUILayout . Label ( Styles . primaryMapsText , EditorStyles . boldLabel ) ;
DoAlbedoArea ( material ) ;
DoSpecularMetallicArea ( ) ;
2023-12-15 00:08:02 +08:00
m_MaterialEditor . TexturePropertySingleLine ( Styles . normalMapText , bumpMap , bumpMap . textureValue ! = null ? bumpScale : null ) ;
2023-10-20 19:31:12 +08:00
m_MaterialEditor . TexturePropertySingleLine ( Styles . heightMapText , heightMap , heightMap . textureValue ! = null ? heigtMapScale : null ) ;
m_MaterialEditor . TexturePropertySingleLine ( Styles . occlusionText , occlusionMap , occlusionMap . textureValue ! = null ? occlusionStrength : null ) ;
DoEmissionArea ( material ) ;
2023-12-15 00:08:02 +08:00
m_MaterialEditor . TexturePropertySingleLine ( Styles . detailMaskText , detailMask ) ;
2023-10-20 19:31:12 +08:00
EditorGUI . BeginChangeCheck ( ) ;
m_MaterialEditor . TextureScaleOffsetProperty ( albedoMap ) ;
if ( EditorGUI . EndChangeCheck ( ) )
2023-12-15 00:08:02 +08:00
{
2023-10-20 19:31:12 +08:00
emissionMap . textureScaleAndOffset = albedoMap . textureScaleAndOffset ; // Apply the main texture scale and offset to the emission texture as well, for Enlighten's sake
2023-12-15 00:08:02 +08:00
}
2023-10-20 19:31:12 +08:00
EditorGUILayout . Space ( ) ;
// Secondary properties
GUILayout . Label ( Styles . secondaryMapsText , EditorStyles . boldLabel ) ;
m_MaterialEditor . TexturePropertySingleLine ( Styles . detailAlbedoText , detailAlbedoMap ) ;
m_MaterialEditor . TexturePropertySingleLine ( Styles . detailNormalMapText , detailNormalMap , detailNormalMapScale ) ;
m_MaterialEditor . TextureScaleOffsetProperty ( detailAlbedoMap ) ;
m_MaterialEditor . ShaderProperty ( uvSetSecondary , Styles . uvSetLabel . text ) ;
// Third properties
GUILayout . Label ( Styles . forwardText , EditorStyles . boldLabel ) ;
if ( highlights ! = null )
m_MaterialEditor . ShaderProperty ( highlights , Styles . highlightsText ) ;
if ( reflections ! = null )
m_MaterialEditor . ShaderProperty ( reflections , Styles . reflectionsText ) ;
2023-12-15 00:08:02 +08:00
GUILayout . Label ( Styles . bakeryText , EditorStyles . boldLabel ) ;
m_MaterialEditor . ShaderProperty ( enableDoubleSidedOn , Styles . doubleSidedLabel ) ;
enableDoubleSided . floatValue = enableDoubleSidedOn . floatValue > 0 ? 0 : 2 ;
m_MaterialEditor . ShaderProperty ( enableVertexLM , Styles . vertexLMLabel ) ;
if ( enableVertexLM . floatValue > 0 )
{
m_MaterialEditor . ShaderProperty ( enableVertexLMdir , Styles . vertexLMdirLabel ) ;
//if (enableVertexLMdir.floatValue > 0) enableVertexLMSH.floatValue = 0;
}
if ( enableVertexLM . floatValue > 0 )
{
m_MaterialEditor . ShaderProperty ( enableVertexLMSH , Styles . vertexLMSHLabel ) ;
//if (enableVertexLMSH.floatValue > 0) enableVertexLMdir.floatValue = 0;
}
if ( enableVertexLM . floatValue > 0 )
{
m_MaterialEditor . ShaderProperty ( enableVertexLMmask , Styles . vertexLMMaskLabel ) ;
}
m_MaterialEditor . ShaderProperty ( enableRNM , Styles . rnmLabel ) ;
m_MaterialEditor . ShaderProperty ( enableSH , Styles . shLabel ) ;
m_MaterialEditor . ShaderProperty ( enableMonoSH , Styles . monoshLabel ) ;
if ( enableSH . floatValue > 0 | | enableMonoSH . floatValue > 0 | | enableVertexLMSH . floatValue > 0 )
m_MaterialEditor . ShaderProperty ( enableSHN , Styles . shnLabel ) ;
m_MaterialEditor . ShaderProperty ( enableSpec , Styles . specLabel ) ;
2024-02-05 21:16:08 +08:00
if ( enableSpec . floatValue > 0 )
{
m_MaterialEditor . ShaderProperty ( enableSpecOcclusion , Styles . specOcclusionLabel ) ;
}
2023-12-15 00:08:02 +08:00
m_MaterialEditor . ShaderProperty ( enableBicubic , Styles . bicubicLabel ) ;
m_MaterialEditor . ShaderProperty ( enablePSHN , Styles . pshnLabel ) ;
try
{
m_MaterialEditor . ShaderProperty ( enableVolumes , Styles . volLabel ) ;
if ( enableVolumes . floatValue > 0 )
{
var prevAssignedVolume = assignedVolume ;
assignedVolume = EditorGUILayout . ObjectField ( volume0 . textureValue = = null ? "Assign volume" : "Assign different volume" , assignedVolume , typeof ( BakeryVolume ) , true ) as BakeryVolume ;
if ( prevAssignedVolume ! = assignedVolume )
{
volume0 . textureValue = assignedVolume . bakedTexture0 ;
volume1 . textureValue = assignedVolume . bakedTexture1 ;
volume2 . textureValue = assignedVolume . bakedTexture2 ;
volumeMask . textureValue = assignedVolume . bakedMask ;
var b = assignedVolume . bounds ;
volumeMin . vectorValue = b . min ;
volumeInvSize . vectorValue = new Vector3 ( 1.0f / b . size . x , 1.0f / b . size . y , 1.0f / b . size . z ) ;
assignedVolume = null ;
}
if ( volume0 . textureValue ! = null )
{
if ( GUILayout . Button ( "Unset volume" ) )
{
volume0 . textureValue = null ;
volume1 . textureValue = null ;
volume2 . textureValue = null ;
volumeMask . textureValue = null ;
volumeMin . vectorValue = Vector3 . zero ;
volumeInvSize . vectorValue = Vector3 . one * 1000001 ;
}
}
EditorGUILayout . LabelField ( "Current Volume: " + ( volume0 . textureValue = = null ? "<none or global>" : volume0 . textureValue . name . Substring ( 0 , volume0 . textureValue . name . Length - 1 ) ) ) ;
EditorGUI . BeginDisabledGroup ( true ) ;
m_MaterialEditor . TexturePropertySingleLine ( Styles . volLabel0 , volume0 ) ;
m_MaterialEditor . TexturePropertySingleLine ( Styles . volLabel1 , volume1 ) ;
m_MaterialEditor . TexturePropertySingleLine ( Styles . volLabel2 , volume2 ) ;
m_MaterialEditor . TexturePropertySingleLine ( Styles . volLabelMask , volumeMask ) ;
var bmin4 = volumeMin . vectorValue ;
var bmin = new Vector3 ( bmin4 . x , bmin4 . y , bmin4 . z ) ;
var invSize = volumeInvSize . vectorValue ;
var bmax = new Vector3 ( 1.0f / invSize . x + bmin . x , 1.0f / invSize . y + bmin . y , 1.0f / invSize . z + bmin . z ) ;
EditorGUILayout . LabelField ( "Min: " + bmin ) ;
EditorGUILayout . LabelField ( "Max: " + bmax ) ;
EditorGUI . EndDisabledGroup ( ) ;
m_MaterialEditor . ShaderProperty ( enableVolumeRot , Styles . volLabelRot ) ;
}
}
catch
{
}
EditorGUILayout . Space ( ) ;
2023-10-20 19:31:12 +08:00
}
if ( EditorGUI . EndChangeCheck ( ) )
{
foreach ( var obj in blendMode . targets )
MaterialChanged ( ( Material ) obj , m_WorkflowMode ) ;
}
}
internal void DetermineWorkflow ( MaterialProperty [ ] props )
{
if ( FindProperty ( "_SpecGlossMap" , props , false ) ! = null & & FindProperty ( "_SpecColor" , props , false ) ! = null )
m_WorkflowMode = WorkflowMode . Specular ;
else if ( FindProperty ( "_MetallicGlossMap" , props , false ) ! = null & & FindProperty ( "_Metallic" , props , false ) ! = null )
m_WorkflowMode = WorkflowMode . Metallic ;
else
m_WorkflowMode = WorkflowMode . Dielectric ;
}
public override void AssignNewShaderToMaterial ( Material material , Shader oldShader , Shader newShader )
{
// _Emission property is lost after assigning Standard shader to the material
// thus transfer it before assigning the new shader
if ( material . HasProperty ( "_Emission" ) )
{
material . SetColor ( "_EmissionColor" , material . GetColor ( "_Emission" ) ) ;
}
base . AssignNewShaderToMaterial ( material , oldShader , newShader ) ;
if ( oldShader = = null | | ! oldShader . name . Contains ( "Legacy Shaders/" ) )
{
SetupMaterialWithBlendMode ( material , ( BlendMode ) material . GetFloat ( "_Mode" ) ) ;
return ;
}
BlendMode blendMode = BlendMode . Opaque ;
if ( oldShader . name . Contains ( "/Transparent/Cutout/" ) )
{
blendMode = BlendMode . Cutout ;
}
else if ( oldShader . name . Contains ( "/Transparent/" ) )
{
// NOTE: legacy shaders did not provide physically based transparency
// therefore Fade mode
blendMode = BlendMode . Fade ;
}
material . SetFloat ( "_Mode" , ( float ) blendMode ) ;
DetermineWorkflow ( MaterialEditor . GetMaterialProperties ( new Material [ ] { material } ) ) ;
MaterialChanged ( material , m_WorkflowMode ) ;
}
void BlendModePopup ( )
{
EditorGUI . showMixedValue = blendMode . hasMixedValue ;
var mode = ( BlendMode ) blendMode . floatValue ;
EditorGUI . BeginChangeCheck ( ) ;
mode = ( BlendMode ) EditorGUILayout . Popup ( Styles . renderingMode , ( int ) mode , Styles . blendNames ) ;
if ( EditorGUI . EndChangeCheck ( ) )
{
m_MaterialEditor . RegisterPropertyChangeUndo ( "Rendering Mode" ) ;
blendMode . floatValue = ( float ) mode ;
}
EditorGUI . showMixedValue = false ;
}
void DoAlbedoArea ( Material material )
{
m_MaterialEditor . TexturePropertySingleLine ( Styles . albedoText , albedoMap , albedoColor ) ;
if ( ( ( BlendMode ) material . GetFloat ( "_Mode" ) = = BlendMode . Cutout ) )
{
m_MaterialEditor . ShaderProperty ( alphaCutoff , Styles . alphaCutoffText . text , MaterialEditor . kMiniTextureFieldLabelIndentLevel + 1 ) ;
}
}
void DoEmissionArea ( Material material )
{
2023-12-15 00:08:02 +08:00
bool showHelpBox = ! HasValidEmissiveKeyword ( material ) ;
bool hadEmissionTexture = emissionMap . textureValue ! = null ;
// Texture and HDR color controls
m_MaterialEditor . TexturePropertyWithHDRColor ( Styles . emissionText , emissionMap , emissionColorForRendering , m_ColorPickerHDRConfig , false ) ;
// If texture was assigned and color was black set color to white
float brightness = emissionColorForRendering . colorValue . maxColorComponent ;
if ( emissionMap . textureValue ! = null & & ! hadEmissionTexture & & brightness < = 0f )
emissionColorForRendering . colorValue = Color . white ;
2023-10-20 19:31:12 +08:00
// Emission for GI?
2023-12-15 00:08:02 +08:00
m_MaterialEditor . LightmapEmissionProperty ( MaterialEditor . kMiniTextureFieldLabelIndentLevel + 1 ) ;
if ( showHelpBox )
2023-10-20 19:31:12 +08:00
{
2023-12-15 00:08:02 +08:00
EditorGUILayout . HelpBox ( Styles . emissiveWarning . text , MessageType . Warning ) ;
2023-10-20 19:31:12 +08:00
}
}
void DoSpecularMetallicArea ( )
{
bool hasGlossMap = false ;
if ( m_WorkflowMode = = WorkflowMode . Specular )
{
hasGlossMap = specularMap . textureValue ! = null ;
m_MaterialEditor . TexturePropertySingleLine ( Styles . specularMapText , specularMap , hasGlossMap ? null : specularColor ) ;
}
else if ( m_WorkflowMode = = WorkflowMode . Metallic )
{
hasGlossMap = metallicMap . textureValue ! = null ;
m_MaterialEditor . TexturePropertySingleLine ( Styles . metallicMapText , metallicMap , hasGlossMap ? null : metallic ) ;
}
bool showSmoothnessScale = hasGlossMap ;
if ( smoothnessMapChannel ! = null )
{
int smoothnessChannel = ( int ) smoothnessMapChannel . floatValue ;
if ( smoothnessChannel = = ( int ) SmoothnessMapChannel . AlbedoAlpha )
showSmoothnessScale = true ;
}
int indentation = 2 ; // align with labels of texture properties
m_MaterialEditor . ShaderProperty ( showSmoothnessScale ? smoothnessScale : smoothness , showSmoothnessScale ? Styles . smoothnessScaleText : Styles . smoothnessText , indentation ) ;
+ + indentation ;
if ( smoothnessMapChannel ! = null )
m_MaterialEditor . ShaderProperty ( smoothnessMapChannel , Styles . smoothnessMapChannelText , indentation ) ;
}
public static void SetupMaterialWithBlendMode ( Material material , BlendMode blendMode )
{
switch ( blendMode )
{
case BlendMode . Opaque :
2023-12-15 00:08:02 +08:00
material . SetOverrideTag ( "RenderType" , "Opaque" ) ;
2023-10-20 19:31:12 +08:00
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 ;
break ;
case BlendMode . Cutout :
2023-12-15 00:08:02 +08:00
material . SetOverrideTag ( "RenderType" , "TransparentCutout" ) ;
2023-10-20 19:31:12 +08:00
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 ;
break ;
case BlendMode . Fade :
2023-12-15 00:08:02 +08:00
material . SetOverrideTag ( "RenderType" , "Transparent" ) ;
2023-10-20 19:31:12 +08:00
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 ;
break ;
case BlendMode . Transparent :
2023-12-15 00:08:02 +08:00
material . SetOverrideTag ( "RenderType" , "Transparent" ) ;
2023-10-20 19:31:12 +08:00
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 ;
break ;
}
}
static SmoothnessMapChannel GetSmoothnessMapChannel ( Material material )
{
int ch = ( int ) material . GetFloat ( "_SmoothnessTextureChannel" ) ;
if ( ch = = ( int ) SmoothnessMapChannel . AlbedoAlpha )
return SmoothnessMapChannel . AlbedoAlpha ;
else
return SmoothnessMapChannel . SpecularMetallicAlpha ;
}
2023-12-15 00:08:02 +08:00
static bool ShouldEmissionBeEnabled ( Material mat , Color color )
{
var realtimeEmission = ( mat . globalIlluminationFlags & MaterialGlobalIlluminationFlags . RealtimeEmissive ) > 0 ;
return color . maxColorComponent > 0.1f / 255.0f | | realtimeEmission ;
}
2023-10-20 19:31:12 +08:00
static void SetMaterialKeywords ( Material material , WorkflowMode workflowMode )
{
// Note: keywords must be based on Material value not on MaterialProperty due to multi-edit & material animation
// (MaterialProperty value might come from renderer material property block)
SetKeyword ( material , "_NORMALMAP" , material . GetTexture ( "_BumpMap" ) | | material . GetTexture ( "_DetailNormalMap" ) ) ;
if ( workflowMode = = WorkflowMode . Specular )
SetKeyword ( material , "_SPECGLOSSMAP" , material . GetTexture ( "_SpecGlossMap" ) ) ;
else if ( workflowMode = = WorkflowMode . Metallic )
SetKeyword ( material , "_METALLICGLOSSMAP" , material . GetTexture ( "_MetallicGlossMap" ) ) ;
SetKeyword ( material , "_PARALLAXMAP" , material . GetTexture ( "_ParallaxMap" ) ) ;
SetKeyword ( material , "_DETAIL_MULX2" , material . GetTexture ( "_DetailAlbedoMap" ) | | material . GetTexture ( "_DetailNormalMap" ) ) ;
2023-12-15 00:08:02 +08:00
bool shouldEmissionBeEnabled = ShouldEmissionBeEnabled ( material , material . GetColor ( "_EmissionColor" ) ) ;
2023-10-20 19:31:12 +08:00
SetKeyword ( material , "_EMISSION" , shouldEmissionBeEnabled ) ;
if ( material . HasProperty ( "_SmoothnessTextureChannel" ) )
{
SetKeyword ( material , "_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A" , GetSmoothnessMapChannel ( material ) = = SmoothnessMapChannel . AlbedoAlpha ) ;
}
2023-12-15 00:08:02 +08:00
// Setup lightmap emissive flags
MaterialGlobalIlluminationFlags flags = material . globalIlluminationFlags ;
if ( ( flags & ( MaterialGlobalIlluminationFlags . BakedEmissive | MaterialGlobalIlluminationFlags . RealtimeEmissive ) ) ! = 0 )
{
flags & = ~ MaterialGlobalIlluminationFlags . EmissiveIsBlack ;
if ( ! shouldEmissionBeEnabled )
flags | = MaterialGlobalIlluminationFlags . EmissiveIsBlack ;
material . globalIlluminationFlags = flags ;
}
}
bool HasValidEmissiveKeyword ( Material material )
{
// Material animation might be out of sync with the material keyword.
// So if the emission support is disabled on the material, but the property blocks have a value that requires it, then we need to show a warning.
// (note: (Renderer MaterialPropertyBlock applies its values to emissionColorForRendering))
bool hasEmissionKeyword = material . IsKeywordEnabled ( "_EMISSION" ) ;
if ( ! hasEmissionKeyword & & ShouldEmissionBeEnabled ( material , emissionColorForRendering . colorValue ) )
return false ;
else
return true ;
2023-10-20 19:31:12 +08:00
}
static void MaterialChanged ( Material material , WorkflowMode workflowMode )
{
SetupMaterialWithBlendMode ( material , ( BlendMode ) material . GetFloat ( "_Mode" ) ) ;
SetMaterialKeywords ( material , workflowMode ) ;
}
static void SetKeyword ( Material m , string keyword , bool state )
{
if ( state )
m . EnableKeyword ( keyword ) ;
else
m . DisableKeyword ( keyword ) ;
}
}
2023-12-15 00:08:02 +08:00
}
#endif