using UnityEngine; using UnityEditor; //using UnityEditorInternal; using System.Linq; using System.Collections.Generic; public class LuxURPParticlesCustomShaderGUI : ShaderGUI { List m_RenderersUsingThisMaterial = new List(); //private static ReorderableList vertexStreamList; private bool showVertexSteamArea = false; public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] properties) { base.OnGUI(materialEditor, properties); Material material = materialEditor.target as Material; var blendMode = material.GetInt("_Blend"); switch (blendMode) { case 0: // Alpha material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.DisableKeyword("_ALPHAMODULATE_ON"); material.DisableKeyword("_ADDITIVE"); break; case 1: // Premultiply material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); material.EnableKeyword("_ALPHAPREMULTIPLY_ON"); material.DisableKeyword("_ALPHAMODULATE_ON"); material.DisableKeyword("_ADDITIVE"); break; case 2: // Additive: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.One); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.One); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.DisableKeyword("_ALPHAMODULATE_ON"); material.EnableKeyword("_ADDITIVE"); break; case 3: // Multiply: material.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.DstColor); material.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.Zero); material.DisableKeyword("_ALPHAPREMULTIPLY_ON"); material.EnableKeyword("_ALPHAMODULATE_ON"); material.DisableKeyword("_ADDITIVE"); break; } var colorMode = material.GetInt("_ColorMode"); switch (colorMode) { case 0: //ColorMode.Multiply: material.DisableKeyword("_COLOROVERLAY_ON"); material.DisableKeyword("_COLORCOLOR_ON"); material.DisableKeyword("_COLORADDSUBDIFF_ON"); break; case 1: //ColorMode.Additive: material.DisableKeyword("_COLOROVERLAY_ON"); material.DisableKeyword("_COLORCOLOR_ON"); material.EnableKeyword("_COLORADDSUBDIFF_ON"); material.SetVector("_BaseColorAddSubDiff", new Vector4(1.0f, 0.0f, 0.0f, 0.0f)); break; case 2: //ColorMode.Subtractive: material.DisableKeyword("_COLOROVERLAY_ON"); material.DisableKeyword("_COLORCOLOR_ON"); material.EnableKeyword("_COLORADDSUBDIFF_ON"); material.SetVector("_BaseColorAddSubDiff", new Vector4(-1.0f, 0.0f, 0.0f, 0.0f)); break; case 3: //ColorMode.Overlay: material.DisableKeyword("_COLORCOLOR_ON"); material.DisableKeyword("_COLORADDSUBDIFF_ON"); material.EnableKeyword("_COLOROVERLAY_ON"); break; case 4: //ColorMode.Color: material.DisableKeyword("_COLOROVERLAY_ON"); material.DisableKeyword("_COLORADDSUBDIFF_ON"); material.EnableKeyword("_COLORCOLOR_ON"); break; case 5: //ColorMode.Difference: material.DisableKeyword("_COLOROVERLAY_ON"); material.DisableKeyword("_COLORCOLOR_ON"); material.EnableKeyword("_COLORADDSUBDIFF_ON"); material.SetVector("_BaseColorAddSubDiff", new Vector4(-1.0f, 1.0f, 0.0f, 0.0f)); break; } // Setup Specular if(material.GetFloat("_EnableSpecGloss") == 1.0f) { material.EnableKeyword("_SPECGLOSSMAP"); material.DisableKeyword("_SPECULAR_COLOR"); } else { material.DisableKeyword("_SPECGLOSSMAP"); material.EnableKeyword("_SPECULAR_COLOR"); } // Remap Distortion Strength material.SetFloat("_DistortionStrengthScaled", material.GetFloat("_DistortionStrength") * 0.1f); // Remap Camera Fade Strength var CameraFade = material.GetVector("_CameraFadeParamsRaw"); // clamp values if (CameraFade.x < 0.0f) { CameraFade.x = 0.0f; } if (CameraFade.y < 0.0f) { CameraFade.y = 0.0f; } material.SetVector("_CameraFadeParamsRaw", CameraFade); material.SetVector("_CameraFadeParams", new Vector2(CameraFade.x, 1.0f / (CameraFade.y - CameraFade.x) )); // Set _PERVERTEX_SAMPLEOFFSET Keyword if needed if( material.GetFloat("_SampleOffset") > 0.0f && material.GetFloat("_PerVertexShadows") == 1.0f ) { material.EnableKeyword("_PERVERTEX_SAMPLEOFFSET"); } else { material.DisableKeyword("_PERVERTEX_SAMPLEOFFSET"); } //if (GUILayout.Button("Check Vertex Streams")) //{ CheckVertexStreams(material, materialEditor); //} // Needed to make the Selection Outline work if (material.HasProperty("_MainTex") && material.HasProperty("_BaseMap") ) { // Alpha might be stored in the Mask Map bool copyMaskMap = false; if(material.HasProperty("_AlphaFromMaskMap") && material.HasProperty("_MaskMap")) { if (material.GetFloat("_AlphaFromMaskMap") == 1.0) { copyMaskMap = true; } } if (copyMaskMap) { if (material.GetTexture("_MaskMap") != null) { material.SetTexture("_MainTex", material.GetTexture("_MaskMap")); } } else { if (material.GetTexture("_BaseMap") != null) { material.SetTexture("_MainTex", material.GetTexture("_BaseMap")); } } } } public void CheckVertexStreams (Material material, MaterialEditor materialEditor) { if (GUILayout.Button("Check Vertex Streams")) { showVertexSteamArea = true; } if(showVertexSteamArea) { m_RenderersUsingThisMaterial.Clear(); ParticleSystemRenderer[] renderers = UnityEngine.Object.FindObjectsOfType(typeof(ParticleSystemRenderer)) as ParticleSystemRenderer[]; foreach (ParticleSystemRenderer renderer in renderers) { if (renderer.sharedMaterial == material) m_RenderersUsingThisMaterial.Add(renderer); } // Build the list of expected vertex streams List streams = new List(); streams.Add(ParticleSystemVertexStream.Position); // Lit shader! streams.Add(ParticleSystemVertexStream.Normal); streams.Add(ParticleSystemVertexStream.Color); streams.Add(ParticleSystemVertexStream.UV); if( material.GetFloat("_ApplyNormal") == 1.0f) streams.Add(ParticleSystemVertexStream.Tangent); if( material.GetFloat("_FlipbookBlending") == 1.0f) { streams.Add(ParticleSystemVertexStream.UV2); streams.Add(ParticleSystemVertexStream.AnimBlend); } // In case we use per vertex shadows and _SampleOffset > 0 we need velocity if( material.GetFloat("_SampleOffset") > 0.0f && material.GetFloat("_PerVertexShadows") == 1.0f ) { streams.Add(ParticleSystemVertexStream.Velocity); } // Display a warning if any renderers have incorrect vertex streams string Warnings = ""; List rendererStreams = new List(); foreach (ParticleSystemRenderer renderer in renderers) { renderer.GetActiveVertexStreams(rendererStreams); if (!rendererStreams.SequenceEqual(streams)) Warnings += "- " + renderer.name + "\n"; } if (!string.IsNullOrEmpty(Warnings)) { EditorGUILayout.HelpBox("The following Particle System Renderers are using this material with incorrect Vertex Streams:\n" + Warnings, MessageType.Error, true); // Set the streams on all systems using this material if (GUILayout.Button("Fix Vertex Streams")) { Undo.RecordObjects(renderers.Where(r => r != null).ToArray(), "Fix Vertex Streams"); foreach (ParticleSystemRenderer renderer in renderers) { renderer.SetActiveVertexStreams(streams); } showVertexSteamArea = false; } } else { Debug.Log("All renderers have proper vertex streams."); showVertexSteamArea = false; } } EditorGUILayout.Space(); } }