629 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			629 lines
		
	
	
		
			28 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
|  | using UnityEngine; | |||
|  | using UnityEditorInternal; | |||
|  | using System.Linq; | |||
|  | using System.Collections.Generic; | |||
|  | using UnityEngine.Rendering; | |||
|  | using UnityEngine.Rendering.Universal; | |||
|  | 
 | |||
|  | namespace UnityEditor.Rendering.Universal.ShaderGUI | |||
|  | { | |||
|  |     /// <summary> | |||
|  |     /// Editor script for the particle material inspector. | |||
|  |     /// </summary> | |||
|  |     public static class ParticleGUI | |||
|  |     { | |||
|  |         /// <summary> | |||
|  |         /// The available color modes. | |||
|  |         /// Controls how the Particle color and the Material color blend together. | |||
|  |         /// </summary> | |||
|  |         public enum ColorMode | |||
|  |         { | |||
|  |             /// <summary> | |||
|  |             /// Use this to select multiply mode. | |||
|  |             /// </summary> | |||
|  |             Multiply, | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// Use this to select additive mode. | |||
|  |             /// </summary> | |||
|  |             Additive, | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// Use this to select subtractive mode. | |||
|  |             /// </summary> | |||
|  |             Subtractive, | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// Use this to select overlay mode. | |||
|  |             /// </summary> | |||
|  |             Overlay, | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// Use this to select color mode. | |||
|  |             /// </summary> | |||
|  |             Color, | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// Use this to select difference mode. | |||
|  |             /// </summary> | |||
|  |             Difference | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Container for the text and tooltips used to display the shader. | |||
|  |         /// </summary> | |||
|  |         public static class Styles | |||
|  |         { | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip color mode. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent colorMode = EditorGUIUtility.TrTextContent("Color Mode", | |||
|  |                 "Controls how the Particle color and the Material color blend together."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip flip-book blending. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent flipbookMode = EditorGUIUtility.TrTextContent("Flip-Book Blending", | |||
|  |                 "Blends the frames in a flip-book together in a smooth animation."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip soft particles. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent softParticlesEnabled = EditorGUIUtility.TrTextContent("Soft Particles", | |||
|  |                 "Makes particles fade out when they get close to intersecting with the surface of other geometry in the depth buffer."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip soft particles surface fade. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent softParticlesFadeText = EditorGUIUtility.TrTextContent("Surface Fade"); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip soft particles near fade distance. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent softParticlesNearFadeDistanceText = | |||
|  |                 EditorGUIUtility.TrTextContent("Near", | |||
|  |                     "The distance from the other surface where the particle is completely transparent."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip soft particles far fade distance. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent softParticlesFarFadeDistanceText = | |||
|  |                 EditorGUIUtility.TrTextContent("Far", | |||
|  |                     "The distance from the other surface where the particle is completely opaque."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip camera fading. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent cameraFadingEnabled = EditorGUIUtility.TrTextContent("Camera Fading", | |||
|  |                 "Makes particles fade out when they get close to the camera."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip camera fading distance. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent cameraFadingDistanceText = EditorGUIUtility.TrTextContent("Distance"); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip camera fading near distance. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent cameraNearFadeDistanceText = | |||
|  |                 EditorGUIUtility.TrTextContent("Near", | |||
|  |                     "The distance from the camera where the particle is completely transparent."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip camera fading far distance. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent cameraFarFadeDistanceText = | |||
|  |                 EditorGUIUtility.TrTextContent("Far", "The distance from the camera where the particle is completely opaque."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip distortion. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent distortionEnabled = EditorGUIUtility.TrTextContent("Distortion", | |||
|  |                 "Creates a distortion effect by making particles perform refraction with the objects drawn before them."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip distortion strength. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent distortionStrength = EditorGUIUtility.TrTextContent("Strength", | |||
|  |                 "Controls how much the Particle distorts the background. "); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip distortion blend. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent distortionBlend = EditorGUIUtility.TrTextContent("Blend", | |||
|  |                 "Controls how visible the distortion effect is. At 0, there’s no visible distortion. At 1, only the distortion effect is visible, not the background."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip for vertex streams. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent VertexStreams = EditorGUIUtility.TrTextContent("Vertex Streams", | |||
|  |                 "List detailing the expected layout of data sent to the shader from the particle system."); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for position vertex stream. | |||
|  |             /// </summary> | |||
|  |             public static string streamPositionText = "Position (POSITION.xyz)"; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for normal vertex stream. | |||
|  |             /// </summary> | |||
|  |             public static string streamNormalText = "Normal (NORMAL.xyz)"; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for color vertex stream. | |||
|  |             /// </summary> | |||
|  |             public static string streamColorText = "Color (COLOR.xyzw)"; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for color instanced vertex stream. | |||
|  |             /// </summary> | |||
|  |             public static string streamColorInstancedText = "Color (INSTANCED0.xyzw)"; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for UV vertex stream. | |||
|  |             /// </summary> | |||
|  |             public static string streamUVText = "UV (TEXCOORD0.xy)"; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for UV2 vertex stream. | |||
|  |             /// </summary> | |||
|  |             public static string streamUV2Text = "UV2 (TEXCOORD0.zw)"; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for AnimBlend Texcoord1 vertex stream. | |||
|  |             /// </summary> | |||
|  |             public static string streamAnimBlendText = "AnimBlend (TEXCOORD1.x)"; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for AnimBlend Instanced1 vertex stream. | |||
|  |             /// </summary> | |||
|  |             public static string streamAnimFrameText = "AnimFrame (INSTANCED1.x)"; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for tangent vertex stream. | |||
|  |             /// </summary> | |||
|  |             public static string streamTangentText = "Tangent (TANGENT.xyzw)"; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The text and tooltip for the vertex stream fix now GUI. | |||
|  |             /// </summary> | |||
|  |             public static GUIContent streamApplyToAllSystemsText = EditorGUIUtility.TrTextContent("Fix Now", | |||
|  |                 "Apply the vertex stream layout to all Particle Systems using this material"); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The string for applying custom vertex streams from material. | |||
|  |             /// </summary> | |||
|  |             public static string undoApplyCustomVertexStreams = L10n.Tr("Apply custom vertex streams from material"); | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The vertex stream icon. | |||
|  |             /// </summary> | |||
|  |             public static GUIStyle vertexStreamIcon = new GUIStyle(); | |||
|  |         } | |||
|  | 
 | |||
|  |         private static ReorderableList vertexStreamList; | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Container for the properties used in the <c>ParticleGUI</c> editor script. | |||
|  |         /// </summary> | |||
|  |         public struct ParticleProperties | |||
|  |         { | |||
|  |             // Surface Option Props | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for color mode. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty colorMode; | |||
|  | 
 | |||
|  | 
 | |||
|  |             // Advanced Props | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for flip-book blending. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty flipbookMode; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for soft particles enabled. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty softParticlesEnabled; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for camera fading. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty cameraFadingEnabled; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for distortion enabled. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty distortionEnabled; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for soft particles near fade distance. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty softParticlesNearFadeDistance; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for soft particles far fade distance. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty softParticlesFarFadeDistance; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for camera fading near distance. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty cameraNearFadeDistance; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for camera fading far distance. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty cameraFarFadeDistance; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for distortion blend. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty distortionBlend; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// The MaterialProperty for distortion strength. | |||
|  |             /// </summary> | |||
|  |             public MaterialProperty distortionStrength; | |||
|  | 
 | |||
|  |             /// <summary> | |||
|  |             /// Constructor for the <c>ParticleProperties</c> container struct. | |||
|  |             /// </summary> | |||
|  |             /// <param name="properties"></param> | |||
|  |             public ParticleProperties(MaterialProperty[] properties) | |||
|  |             { | |||
|  |                 // Surface Option Props | |||
|  |                 colorMode = BaseShaderGUI.FindProperty("_ColorMode", properties, false); | |||
|  | 
 | |||
|  |                 // Advanced Props | |||
|  |                 flipbookMode = BaseShaderGUI.FindProperty("_FlipbookBlending", properties); | |||
|  |                 softParticlesEnabled = BaseShaderGUI.FindProperty("_SoftParticlesEnabled", properties); | |||
|  |                 cameraFadingEnabled = BaseShaderGUI.FindProperty("_CameraFadingEnabled", properties); | |||
|  |                 distortionEnabled = BaseShaderGUI.FindProperty("_DistortionEnabled", properties, false); | |||
|  |                 softParticlesNearFadeDistance = BaseShaderGUI.FindProperty("_SoftParticlesNearFadeDistance", properties); | |||
|  |                 softParticlesFarFadeDistance = BaseShaderGUI.FindProperty("_SoftParticlesFarFadeDistance", properties); | |||
|  |                 cameraNearFadeDistance = BaseShaderGUI.FindProperty("_CameraNearFadeDistance", properties); | |||
|  |                 cameraFarFadeDistance = BaseShaderGUI.FindProperty("_CameraFarFadeDistance", properties); | |||
|  |                 distortionBlend = BaseShaderGUI.FindProperty("_DistortionBlend", properties, false); | |||
|  |                 distortionStrength = BaseShaderGUI.FindProperty("_DistortionStrength", properties, false); | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Sets up the material with correct keywords based on the color mode. | |||
|  |         /// </summary> | |||
|  |         /// <param name="material">The material to use.</param> | |||
|  |         public static void SetupMaterialWithColorMode(Material material) | |||
|  |         { | |||
|  |             var colorMode = (ColorMode)material.GetFloat("_ColorMode"); | |||
|  | 
 | |||
|  |             switch (colorMode) | |||
|  |             { | |||
|  |                 case ColorMode.Multiply: | |||
|  |                     material.DisableKeyword("_COLOROVERLAY_ON"); | |||
|  |                     material.DisableKeyword("_COLORCOLOR_ON"); | |||
|  |                     material.DisableKeyword("_COLORADDSUBDIFF_ON"); | |||
|  |                     break; | |||
|  |                 case ColorMode.Overlay: | |||
|  |                     material.DisableKeyword("_COLORCOLOR_ON"); | |||
|  |                     material.DisableKeyword("_COLORADDSUBDIFF_ON"); | |||
|  |                     material.EnableKeyword("_COLOROVERLAY_ON"); | |||
|  |                     break; | |||
|  |                 case ColorMode.Color: | |||
|  |                     material.DisableKeyword("_COLOROVERLAY_ON"); | |||
|  |                     material.DisableKeyword("_COLORADDSUBDIFF_ON"); | |||
|  |                     material.EnableKeyword("_COLORCOLOR_ON"); | |||
|  |                     break; | |||
|  |                 case 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; | |||
|  |                 case 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 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; | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Draws the fading options GUI. | |||
|  |         /// </summary> | |||
|  |         /// <param name="material">The material to use.</param> | |||
|  |         /// <param name="materialEditor">The material editor to use.</param> | |||
|  |         /// <param name="properties">The particle properties to use.</param> | |||
|  |         public static void FadingOptions(Material material, MaterialEditor materialEditor, ParticleProperties properties) | |||
|  |         { | |||
|  |             // Z write doesn't work with fading | |||
|  |             bool hasZWrite = (material.GetFloat("_ZWrite") > 0.0f); | |||
|  |             if (!hasZWrite) | |||
|  |             { | |||
|  |                 // Soft Particles | |||
|  |                 { | |||
|  |                     materialEditor.ShaderProperty(properties.softParticlesEnabled, Styles.softParticlesEnabled); | |||
|  |                     if (properties.softParticlesEnabled.floatValue >= 0.5f) | |||
|  |                     { | |||
|  |                         UniversalRenderPipelineAsset urpAsset = UniversalRenderPipeline.asset; | |||
|  |                         if (urpAsset != null && !urpAsset.supportsCameraDepthTexture) | |||
|  |                         { | |||
|  |                             GUIStyle warnStyle = new GUIStyle(GUI.skin.label); | |||
|  |                             warnStyle.fontStyle = FontStyle.BoldAndItalic; | |||
|  |                             warnStyle.wordWrap = true; | |||
|  |                             EditorGUILayout.HelpBox("Soft Particles require depth texture. Please enable \"Depth Texture\" in the Universal Render Pipeline settings.", MessageType.Warning); | |||
|  |                         } | |||
|  | 
 | |||
|  |                         EditorGUI.indentLevel++; | |||
|  |                         BaseShaderGUI.TwoFloatSingleLine(Styles.softParticlesFadeText, | |||
|  |                             properties.softParticlesNearFadeDistance, | |||
|  |                             Styles.softParticlesNearFadeDistanceText, | |||
|  |                             properties.softParticlesFarFadeDistance, | |||
|  |                             Styles.softParticlesFarFadeDistanceText, | |||
|  |                             materialEditor); | |||
|  |                         EditorGUI.indentLevel--; | |||
|  |                     } | |||
|  |                 } | |||
|  | 
 | |||
|  |                 // Camera Fading | |||
|  |                 { | |||
|  |                     materialEditor.ShaderProperty(properties.cameraFadingEnabled, Styles.cameraFadingEnabled); | |||
|  |                     if (properties.cameraFadingEnabled.floatValue >= 0.5f) | |||
|  |                     { | |||
|  |                         EditorGUI.indentLevel++; | |||
|  |                         BaseShaderGUI.TwoFloatSingleLine(Styles.cameraFadingDistanceText, | |||
|  |                             properties.cameraNearFadeDistance, | |||
|  |                             Styles.cameraNearFadeDistanceText, | |||
|  |                             properties.cameraFarFadeDistance, | |||
|  |                             Styles.cameraFarFadeDistanceText, | |||
|  |                             materialEditor); | |||
|  |                         EditorGUI.indentLevel--; | |||
|  |                     } | |||
|  |                 } | |||
|  | 
 | |||
|  |                 // Distortion | |||
|  |                 if (properties.distortionEnabled != null) | |||
|  |                 { | |||
|  |                     materialEditor.ShaderProperty(properties.distortionEnabled, Styles.distortionEnabled); | |||
|  |                     if (properties.distortionEnabled.floatValue >= 0.5f) | |||
|  |                     { | |||
|  |                         EditorGUI.indentLevel++; | |||
|  |                         materialEditor.ShaderProperty(properties.distortionStrength, Styles.distortionStrength); | |||
|  |                         materialEditor.ShaderProperty(properties.distortionBlend, Styles.distortionBlend); | |||
|  |                         EditorGUI.indentLevel--; | |||
|  |                     } | |||
|  |                 } | |||
|  | 
 | |||
|  |                 EditorGUI.showMixedValue = false; | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Draws the vertex streams area. | |||
|  |         /// </summary> | |||
|  |         /// <param name="material">The material to use.</param> | |||
|  |         /// <param name="renderers">List of particle system renderers.</param> | |||
|  |         /// <param name="useLighting">Marks whether the renderers uses lighting or not.</param> | |||
|  |         public static void DoVertexStreamsArea(Material material, List<ParticleSystemRenderer> renderers, bool useLighting = false) | |||
|  |         { | |||
|  |             EditorGUILayout.Space(); | |||
|  |             // Display list of streams required to make this shader work | |||
|  |             bool useNormalMap = false; | |||
|  |             bool useFlipbookBlending = (material.GetFloat("_FlipbookBlending") > 0.0f); | |||
|  |             if (material.HasProperty("_BumpMap")) | |||
|  |                 useNormalMap = material.GetTexture("_BumpMap"); | |||
|  | 
 | |||
|  |             bool useGPUInstancing = ShaderUtil.HasProceduralInstancing(material.shader); | |||
|  |             if (useGPUInstancing && renderers.Count > 0) | |||
|  |             { | |||
|  |                 if (!renderers[0].enableGPUInstancing || renderers[0].renderMode != ParticleSystemRenderMode.Mesh) | |||
|  |                     useGPUInstancing = false; | |||
|  |             } | |||
|  | 
 | |||
|  |             // Build the list of expected vertex streams | |||
|  |             List<ParticleSystemVertexStream> streams = new List<ParticleSystemVertexStream>(); | |||
|  |             List<string> streamList = new List<string>(); | |||
|  | 
 | |||
|  |             streams.Add(ParticleSystemVertexStream.Position); | |||
|  |             streamList.Add(Styles.streamPositionText); | |||
|  | 
 | |||
|  |             if (useLighting || useNormalMap) | |||
|  |             { | |||
|  |                 streams.Add(ParticleSystemVertexStream.Normal); | |||
|  |                 streamList.Add(Styles.streamNormalText); | |||
|  |                 if (useNormalMap) | |||
|  |                 { | |||
|  |                     streams.Add(ParticleSystemVertexStream.Tangent); | |||
|  |                     streamList.Add(Styles.streamTangentText); | |||
|  |                 } | |||
|  |             } | |||
|  | 
 | |||
|  |             streams.Add(ParticleSystemVertexStream.Color); | |||
|  |             streamList.Add(useGPUInstancing ? Styles.streamColorInstancedText : Styles.streamColorText); | |||
|  |             streams.Add(ParticleSystemVertexStream.UV); | |||
|  |             streamList.Add(Styles.streamUVText); | |||
|  | 
 | |||
|  |             List<ParticleSystemVertexStream> instancedStreams = new List<ParticleSystemVertexStream>(streams); | |||
|  | 
 | |||
|  |             if (useGPUInstancing) | |||
|  |             { | |||
|  |                 instancedStreams.Add(ParticleSystemVertexStream.AnimFrame); | |||
|  |                 streamList.Add(Styles.streamAnimFrameText); | |||
|  |             } | |||
|  |             else if (useFlipbookBlending && !useGPUInstancing) | |||
|  |             { | |||
|  |                 streams.Add(ParticleSystemVertexStream.UV2); | |||
|  |                 streamList.Add(Styles.streamUV2Text); | |||
|  |                 streams.Add(ParticleSystemVertexStream.AnimBlend); | |||
|  |                 streamList.Add(Styles.streamAnimBlendText); | |||
|  |             } | |||
|  | 
 | |||
|  |             vertexStreamList = new ReorderableList(streamList, typeof(string), false, true, false, false); | |||
|  | 
 | |||
|  |             vertexStreamList.drawHeaderCallback = (Rect rect) => | |||
|  |             { | |||
|  |                 EditorGUI.LabelField(rect, Styles.VertexStreams); | |||
|  |             }; | |||
|  | 
 | |||
|  |             vertexStreamList.DoLayoutList(); | |||
|  | 
 | |||
|  |             // Display a warning if any renderers have incorrect vertex streams | |||
|  |             string Warnings = ""; | |||
|  |             List<ParticleSystemVertexStream> rendererStreams = new List<ParticleSystemVertexStream>(); | |||
|  |             foreach (ParticleSystemRenderer renderer in renderers) | |||
|  |             { | |||
|  |                 renderer.GetActiveVertexStreams(rendererStreams); | |||
|  | 
 | |||
|  |                 bool streamsValid; | |||
|  |                 if (useGPUInstancing && renderer.renderMode == ParticleSystemRenderMode.Mesh && renderer.supportsMeshInstancing) | |||
|  |                     streamsValid = CompareVertexStreams(rendererStreams, instancedStreams); | |||
|  |                 else | |||
|  |                     streamsValid = CompareVertexStreams(rendererStreams, streams); | |||
|  | 
 | |||
|  |                 if (!streamsValid) | |||
|  |                     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(Styles.streamApplyToAllSystemsText, EditorStyles.miniButton, GUILayout.ExpandWidth(true))) | |||
|  |                 { | |||
|  |                     Undo.RecordObjects(renderers.Where(r => r != null).ToArray(), Styles.undoApplyCustomVertexStreams); | |||
|  | 
 | |||
|  |                     foreach (ParticleSystemRenderer renderer in renderers) | |||
|  |                     { | |||
|  |                         if (useGPUInstancing && renderer.renderMode == ParticleSystemRenderMode.Mesh && renderer.supportsMeshInstancing) | |||
|  |                             renderer.SetActiveVertexStreams(instancedStreams); | |||
|  |                         else | |||
|  |                             renderer.SetActiveVertexStreams(streams); | |||
|  |                     } | |||
|  |                 } | |||
|  |             } | |||
|  |         } | |||
|  | 
 | |||
|  |         private static bool CompareVertexStreams(IEnumerable<ParticleSystemVertexStream> a, IEnumerable<ParticleSystemVertexStream> b) | |||
|  |         { | |||
|  |             var differenceA = a.Except(b); | |||
|  |             var differenceB = b.Except(a); | |||
|  |             var difference = differenceA.Union(differenceB).Distinct(); | |||
|  |             if (!difference.Any()) | |||
|  |                 return true; | |||
|  |             // If normals are the only difference, ignore them, because the default particle streams include normals, to make it easy for users to switch between lit and unlit | |||
|  |             if (difference.Count() == 1) | |||
|  |             { | |||
|  |                 if (difference.First() == ParticleSystemVertexStream.Normal) | |||
|  |                     return true; | |||
|  |             } | |||
|  |             return false; | |||
|  |         } | |||
|  | 
 | |||
|  |         /// <summary> | |||
|  |         /// Sets up the keywords for the material and shader. | |||
|  |         /// </summary> | |||
|  |         /// <param name="material">The material to use.</param> | |||
|  |         public static void SetMaterialKeywords(Material material) | |||
|  |         { | |||
|  |             // Setup particle + material color blending | |||
|  |             SetupMaterialWithColorMode(material); | |||
|  |             // Is the material transparent, this is set in BaseShaderGUI | |||
|  |             bool isTransparent = material.GetTag("RenderType", false) == "Transparent"; | |||
|  |             // Z write doesn't work with distortion/fading | |||
|  |             bool hasZWrite = (material.GetFloat("_ZWrite") > 0.0f); | |||
|  | 
 | |||
|  |             // Flipbook blending | |||
|  |             if (material.HasProperty("_FlipbookBlending")) | |||
|  |             { | |||
|  |                 var useFlipbookBlending = (material.GetFloat("_FlipbookBlending") > 0.0f); | |||
|  |                 CoreUtils.SetKeyword(material, "_FLIPBOOKBLENDING_ON", useFlipbookBlending); | |||
|  |             } | |||
|  |             // Soft particles | |||
|  |             var useSoftParticles = false; | |||
|  |             if (material.HasProperty("_SoftParticlesEnabled")) | |||
|  |             { | |||
|  |                 useSoftParticles = (material.GetFloat("_SoftParticlesEnabled") > 0.0f && isTransparent); | |||
|  |                 if (useSoftParticles) | |||
|  |                 { | |||
|  |                     var softParticlesNearFadeDistance = material.GetFloat("_SoftParticlesNearFadeDistance"); | |||
|  |                     var softParticlesFarFadeDistance = material.GetFloat("_SoftParticlesFarFadeDistance"); | |||
|  |                     // clamp values | |||
|  |                     if (softParticlesNearFadeDistance < 0.0f) | |||
|  |                     { | |||
|  |                         softParticlesNearFadeDistance = 0.0f; | |||
|  |                         material.SetFloat("_SoftParticlesNearFadeDistance", 0.0f); | |||
|  |                     } | |||
|  | 
 | |||
|  |                     if (softParticlesFarFadeDistance < 0.0f) | |||
|  |                     { | |||
|  |                         softParticlesFarFadeDistance = 0.0f; | |||
|  |                         material.SetFloat("_SoftParticlesFarFadeDistance", 0.0f); | |||
|  |                     } | |||
|  |                     // set keywords | |||
|  |                     material.SetVector("_SoftParticleFadeParams", | |||
|  |                         new Vector4(softParticlesNearFadeDistance, | |||
|  |                             1.0f / (softParticlesFarFadeDistance - softParticlesNearFadeDistance), 0.0f, 0.0f)); | |||
|  |                 } | |||
|  |                 else | |||
|  |                 { | |||
|  |                     material.SetVector("_SoftParticleFadeParams", new Vector4(0.0f, 0.0f, 0.0f, 0.0f)); | |||
|  |                 } | |||
|  |                 CoreUtils.SetKeyword(material, "_SOFTPARTICLES_ON", useSoftParticles); | |||
|  |             } | |||
|  |             // Camera fading | |||
|  |             var useCameraFading = false; | |||
|  |             if (material.HasProperty("_CameraFadingEnabled") && isTransparent) | |||
|  |             { | |||
|  |                 useCameraFading = (material.GetFloat("_CameraFadingEnabled") > 0.0f); | |||
|  |                 if (useCameraFading) | |||
|  |                 { | |||
|  |                     var cameraNearFadeDistance = material.GetFloat("_CameraNearFadeDistance"); | |||
|  |                     var cameraFarFadeDistance = material.GetFloat("_CameraFarFadeDistance"); | |||
|  |                     // clamp values | |||
|  |                     if (cameraNearFadeDistance < 0.0f) | |||
|  |                     { | |||
|  |                         cameraNearFadeDistance = 0.0f; | |||
|  |                         material.SetFloat("_CameraNearFadeDistance", 0.0f); | |||
|  |                     } | |||
|  | 
 | |||
|  |                     if (cameraFarFadeDistance < 0.0f) | |||
|  |                     { | |||
|  |                         cameraFarFadeDistance = 0.0f; | |||
|  |                         material.SetFloat("_CameraFarFadeDistance", 0.0f); | |||
|  |                     } | |||
|  |                     // set keywords | |||
|  |                     material.SetVector("_CameraFadeParams", | |||
|  |                         new Vector4(cameraNearFadeDistance, 1.0f / (cameraFarFadeDistance - cameraNearFadeDistance), | |||
|  |                             0.0f, 0.0f)); | |||
|  |                 } | |||
|  |                 else | |||
|  |                 { | |||
|  |                     material.SetVector("_CameraFadeParams", new Vector4(0.0f, Mathf.Infinity, 0.0f, 0.0f)); | |||
|  |                 } | |||
|  |             } | |||
|  |             // Distortion | |||
|  |             if (material.HasProperty("_DistortionEnabled")) | |||
|  |             { | |||
|  |                 var useDistortion = (material.GetFloat("_DistortionEnabled") > 0.0f) && isTransparent; | |||
|  |                 CoreUtils.SetKeyword(material, "_DISTORTION_ON", useDistortion); | |||
|  |                 if (useDistortion) | |||
|  |                     material.SetFloat("_DistortionStrengthScaled", material.GetFloat("_DistortionStrength") * 0.1f); | |||
|  |             } | |||
|  | 
 | |||
|  |             var useFading = (useSoftParticles || useCameraFading) && !hasZWrite; | |||
|  |             CoreUtils.SetKeyword(material, "_FADING_ON", useFading); | |||
|  |         } | |||
|  |     } | |||
|  | } // namespace UnityEditor |