예제 #1
0
    public override void OnInspectorGUI()
    {
        if (!isVisible)
        {
            return;
        }

        bool     forceUpdate = false;
        Material targetMat   = target as Material;

        string[] originalKeywords = targetMat.shaderKeywords;

        //Set default values when the material is newly created
        if (originalKeywords.Length == 0)
        {
            originalKeywords = defaultKeywords;

            targetMat.shaderKeywords = defaultKeywords;
            EditorUtility.SetDirty(targetMat);
        }

        //Grass type
        int grassType = -1;

        for (int i = 0; i < grassTypeLabels.Length; i++)
        {
            if (originalKeywords.Contains(grassTypeString[i]))
            {
                grassType = i;
                break;
            }
        }
        if (grassType < 0)
        {
            grassType   = defaultGrassType;
            forceUpdate = true;
        }

        //Lighting mode
        int lightingMode = -1;

        for (int i = 0; i < lightingModeLabels.Length; i++)
        {
            if (originalKeywords.Contains(lightingModes[i]))
            {
                lightingMode = i;
                break;
            }
        }
        if (lightingMode < 0)
        {
            lightingMode = defaultLightingMode;
            forceUpdate  = true;
        }

        //Density mode
        var densityMode = GrassEditorUtility.GetDensityMode(targetMat);

        bool ignoreGISpecular     = originalKeywords.Contains("GRASS_IGNORE_GI_SPECULAR");
        bool widthSmoothing       = originalKeywords.Contains("GRASS_WIDTH_SMOOTHING");
        bool heightSmoothing      = originalKeywords.Contains("GRASS_HEIGHT_SMOOTHING");
        bool objectMode           = originalKeywords.Contains("GRASS_OBJECT_MODE");
        bool topViewCompensation  = originalKeywords.Contains("GRASS_TOP_VIEW_COMPENSATION");
        bool surfaceNormal        = originalKeywords.Contains("GRASS_FOLLOW_SURFACE_NORMAL");
        bool useTextureAtlas      = originalKeywords.Contains("GRASS_USE_TEXTURE_ATLAS");
        bool grassRandomDirection = originalKeywords.Contains("GRASS_RANDOM_DIR");
        bool calcGlobalWind       = originalKeywords.Contains("GRASS_CALC_GLOBAL_WIND");

        //Grass painter
        if (Selection.activeObject == null || AssetDatabase.Contains(Selection.activeObject))
        {
            EditorGUILayout.LabelField("To open the grass painter, select a scene object with a grass material.");
            EditorGUILayout.LabelField("For Unity Terrain you can open it from Window > Stix Games > GrassPainter");
        }
        else
        {
            if (GUILayout.Button("Open Grass Painter"))
            {
                GrassPainterWindow.OpenWindow();
            }
        }
        EditorGUILayout.Space();

        EditorGUI.BeginChangeCheck();

        EditorGUILayout.LabelField("Shader Variants", EditorStyles.boldLabel);
        EditorGUILayout.LabelField("Grass Modes", EditorStyles.boldLabel);
        grassType            = EditorGUILayout.Popup("Grass type:", grassType, grassTypeLabels);
        densityMode          = (DensityMode)EditorGUILayout.Popup("Density mode:", (int)densityMode, densityModeLabels);
        grassRandomDirection = GUILayout.Toggle(grassRandomDirection, "Randomize grass orientation");
        EditorGUILayout.Separator();

        EditorGUILayout.LabelField("Grass Lighting", EditorStyles.boldLabel);
        lightingMode     = EditorGUILayout.Popup("Lighting mode:", lightingMode, lightingModeLabels);
        ignoreGISpecular = GUILayout.Toggle(ignoreGISpecular,
                                            new GUIContent("Ignore global specular lighting", "If checked, the specular lighting from the " +
                                                           "global illumination engine will be ignored. " +
                                                           "Skyboxes will no longer reflect on the grass."));
        EditorGUILayout.Separator();

        EditorGUILayout.LabelField("Level of Detail Interpolation", EditorStyles.boldLabel);
        widthSmoothing  = GUILayout.Toggle(widthSmoothing, "Smooth grass width");
        heightSmoothing = GUILayout.Toggle(heightSmoothing, "Smooth grass height");
        EditorGUILayout.Separator();

        EditorGUILayout.LabelField("Object / World Space Modes", EditorStyles.boldLabel);
        objectMode    = GUILayout.Toggle(objectMode, "Object space mode");
        surfaceNormal = GUILayout.Toggle(surfaceNormal, "Follow surface normals");
        EditorGUILayout.Separator();

        EditorGUILayout.LabelField("Other Shader Variants", EditorStyles.boldLabel);
        topViewCompensation = GUILayout.Toggle(topViewCompensation, "Improve viewing grass from above");
        calcGlobalWind      = GUILayout.Toggle(calcGlobalWind, "Use global wind");
        EditorGUILayout.Separator();

        useTextureAtlas = grassType >= 2 && GUILayout.Toggle(useTextureAtlas, "Use texture atlas");
        EditorGUILayout.Separator();

        if (EditorGUI.EndChangeCheck() || forceUpdate)
        {
            Undo.RecordObject(targetMat, "Changed grass shader keywords");

            var keywords = new List <string>();

            keywords.Add(grassTypeString[grassType]);
            keywords.Add(lightingModes[lightingMode]);
            keywords.Add(GrassEditorUtility.DensityModes[(int)densityMode]);

            if (ignoreGISpecular)
            {
                keywords.Add("GRASS_IGNORE_GI_SPECULAR");
            }

            if (widthSmoothing)
            {
                keywords.Add("GRASS_WIDTH_SMOOTHING");
            }

            if (heightSmoothing)
            {
                keywords.Add("GRASS_HEIGHT_SMOOTHING");
            }

            if (objectMode)
            {
                keywords.Add("GRASS_OBJECT_MODE");
            }

            if (topViewCompensation)
            {
                keywords.Add("GRASS_TOP_VIEW_COMPENSATION");
            }

            if (surfaceNormal)
            {
                keywords.Add("GRASS_FOLLOW_SURFACE_NORMAL");
            }

            if (useTextureAtlas)
            {
                keywords.Add("GRASS_USE_TEXTURE_ATLAS");
            }

            if (grassRandomDirection)
            {
                keywords.Add("GRASS_RANDOM_DIR");
            }

            if (calcGlobalWind)
            {
                keywords.Add("GRASS_CALC_GLOBAL_WIND");
            }

            targetMat.shaderKeywords = keywords.ToArray();
            EditorUtility.SetDirty(targetMat);
        }

        EditorGUILayout.LabelField("Shader Settings", EditorStyles.boldLabel);
        serializedObject.Update();
        var theShader = serializedObject.FindProperty("m_Shader");

        if (isVisible && !theShader.hasMultipleDifferentValues && theShader.objectReferenceValue != null)
        {
            EditorGUIUtility.fieldWidth = 64;
            EditorGUI.BeginChangeCheck();

            int grassLabel = 1;
            var properties = GetMaterialProperties(new Object[] { targetMat });
            foreach (var property in properties)
            {
                //Ignore unused grass types
                if ((grassType < 3 && property.name.Contains("01")) ||
                    (grassType < 4 && property.name.Contains("02")) ||
                    (grassType < 5 && property.name.Contains("03")))
                {
                    break;
                }

                // =========== Labels ==================
                if (property.name == "_EdgeLength")
                {
                    EditorGUILayout.LabelField("Performance Settings", EditorStyles.boldLabel);
                }
                if (property.name == "_GrassFadeStart")
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.LabelField("Visual Settings", EditorStyles.boldLabel);
                }
                if (property.name == "_ColorMap")
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.LabelField("Base Textures", EditorStyles.boldLabel);
                }
                if (property.name == "_WindParams")
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.LabelField("Wind Settings", EditorStyles.boldLabel);
                }

                //Grass type label
                if (property.name.Contains("_GrassTex"))
                {
                    EditorGUILayout.Space();
                    EditorGUILayout.LabelField("Grass Type Nr. " + grassLabel, EditorStyles.boldLabel);
                    grassLabel++;
                }

                // ============ Non standard settings =============
                if (property.name == "_CullMode")
                {
                    //Cull Mode is only set by the editor, don't show it in the inspector
                    property.floatValue = grassRandomDirection ? 2 : 0;
                    continue;
                }

                //Max tessellation can only be a int between 1 and 6
                if (property.name == "_MaxTessellation")
                {
                    property.floatValue = EditorGUILayout.IntSlider(property.displayName, (int)property.floatValue,
                                                                    (int)property.rangeLimits.x, (int)property.rangeLimits.y);
                    continue;
                }

                //Max tessellation can only be a int between 1 and 6
                if (property.name == "_LODMax")
                {
                    property.floatValue = EditorGUILayout.IntSlider(property.displayName, (int)property.floatValue,
                                                                    (int)property.rangeLimits.x, (int)property.rangeLimits.y);
                    continue;
                }

                //Hide texture atlas settings if not active
                if (property.name.Contains("_TextureAtlas"))
                {
                    if (useTextureAtlas)
                    {
                        property.floatValue = Math.Max(EditorGUILayout.IntField(property.displayName, (int)property.floatValue), 1);
                    }
                    continue;
                }

                //Wind should only be active when activated
                if (property.name.StartsWith("_Wind"))
                {
                    EditorGUI.BeginDisabledGroup(!calcGlobalWind);
                    DrawProperty(property);
                    EditorGUI.EndDisabledGroup();
                    continue;
                }

                // ============ Standard settings =============
                //Density
                if (property.name.Contains("_Density"))
                {
                    //Vertex density
                    if (densityMode == DensityMode.Vertex || grassType == 0)
                    {
                        continue;
                    }

                    //Texture density
                    if (densityMode == DensityMode.Texture && property.name == "_DensityValues")
                    {
                        continue;
                    }

                    //Density value
                    if (densityMode == DensityMode.Value && property.name == "_Density")
                    {
                        continue;
                    }
                }

                //In simple grass, ignore grass texture
                if ((grassType == 0 || grassType == 1) && property.name.Contains("_GrassTex"))
                {
                    continue;
                }

                //For billboard grass (not randomized direction grass) the subsurface scattering setting is not in use (yet?)
                if (!grassRandomDirection && property.name.Contains("Subsurface"))
                {
                    continue;
                }

                DrawProperty(property);
            }

            if (EditorGUI.EndChangeCheck())
            {
                PropertiesChanged();
            }
        }
    }
예제 #2
0
    private void TextureSettings()
    {
        if (grassObject == null)
        {
            EditorGUILayout.LabelField("No grass object selected. Select a grass object in the scene Hierarchy.");
            return;
        }

        EditorGUILayout.LabelField("Current object: " + grassObject.name);
        EditorGUILayout.Space();

        if (GrassEditorUtility.GetDensityMode(grassMaterial) != DensityMode.Texture)
        {
            EditorGUILayout.LabelField("The grass material is not in texture density mode.", EditorStyles.boldLabel);
            if (GUILayout.Button("Change material to texture density"))
            {
                GrassEditorUtility.SetDensityMode(grassMaterial, DensityMode.Texture);
            }

            EditorGUILayout.Space();
        }

        if (grassMaterial.GetTexture("_Density") == null)
        {
            EditorGUILayout.LabelField("Create new texture", EditorStyles.boldLabel);
            EditorGUILayout.Space();

            textureSize = EditorGUILayout.IntField("Texture Size", textureSize);

            if (GUILayout.Button("Create texture"))
            {
                //Select the path and return on cancel
                string path = EditorUtility.SaveFilePanelInProject("Create density texture", "newDensityTexture", "png",
                                                                   "Choose where to save the new density texture");

                if (path == null)
                {
                    return;
                }

                //Create the new texture and save it at the selected path
                GrassPainter.Texture = new Texture2D(textureSize, textureSize, TextureFormat.ARGB32, false, true);

                Color[] colors = new Color[textureSize * textureSize];
                for (int i = 0; i < colors.Length; i++)
                {
                    colors[i] = new Color(0, 0, 0, 0);
                }

                GrassPainter.Texture.SetPixels(colors);
                GrassPainter.Texture.Apply();

                File.WriteAllBytes(path, GrassPainter.Texture.EncodeToPNG());

                //Import and load the new texture
                AssetDatabase.ImportAsset(path);
                var importer = (TextureImporter)AssetImporter.GetAtPath(path);
                importer.wrapMode       = TextureWrapMode.Clamp;
                importer.isReadable     = true;
                importer.maxTextureSize = textureSize;
#if UNITY_5_5_OR_NEWER
                importer.sRGBTexture        = false;
                importer.textureCompression = TextureImporterCompression.Uncompressed;
                importer.SetPlatformTextureSettings(new TextureImporterPlatformSettings
                {
                    format     = TextureImporterFormat.ARGB32,
                    overridden = true,
                });
#else
                importer.linearTexture = true;
                importer.textureFormat = TextureImporterFormat.ARGB32;
#endif
                AssetDatabase.ImportAsset(path);

                GrassPainter.Texture = AssetDatabase.LoadAssetAtPath(path, typeof(Texture2D)) as Texture2D;

                //Set texture to material
                grassMaterial.SetTexture("_Density", GrassPainter.Texture);
            }

            EditorGUILayout.Space();
        }
    }