Exemplo n.º 1
0
        void RenderVegetationNow(VegetationSystemPro vegetationSystemPro, ShadowMaskCreator shadowMaskCreator)
        {
            Shader overrideShader = Shader.Find("AwesomeTechnologies/Shadows/ShadowHeight");
            List <VegetationCell> processCellList = new List <VegetationCell>();

            vegetationSystemPro.VegetationCellQuadTree.Query(shadowMaskCreator.AreaRect, processCellList);
            for (int i = 0; i <= vegetationSystemPro.VegetationPackageProList.Count - 1; i++)
            {
                for (int j = 0; j <= vegetationSystemPro.VegetationPackageProList[i].VegetationInfoList.Count - 1; j++)
                {
                    VegetationItemInfoPro vegetationItemInfoPro =
                        vegetationSystemPro.VegetationPackageProList[i].VegetationInfoList[j];

                    if (!RenderVegetationType(vegetationItemInfoPro.VegetationType, shadowMaskCreator))
                    {
                        continue;
                    }
                    for (int k = 0; k <= processCellList.Count - 1; k++)
                    {
                        if (j % 10 == 0)
                        {
                            EditorUtility.DisplayProgressBar("Render vegetation item: " + vegetationItemInfoPro.Name,
                                                             "Render cell " + k + "/" + (processCellList.Count - 1),
                                                             k / ((float)processCellList.Count - 1));
                        }

                        VegetationCell vegetationCell   = processCellList[k];
                        string         vegetationItemID = vegetationItemInfoPro.VegetationItemID;

                        vegetationSystemPro.SpawnVegetationCell(vegetationCell, vegetationItemID);

                        NativeList <MatrixInstance> vegetationInstanceList =
                            vegetationSystemPro.GetVegetationItemInstances(vegetationCell, vegetationItemID);

                        VegetationItemModelInfo vegetationItemModelInfo =
                            vegetationSystemPro.GetVegetationItemModelInfo(vegetationItemID);

                        for (int l = 0; l <= vegetationItemModelInfo.VegetationMeshLod0.subMeshCount - 1; l++)
                        {
                            vegetationItemModelInfo.VegetationMaterialsLOD0[l].SetFloat(CullFarStart, 50000);
                            vegetationItemModelInfo.VegetationMaterialsLOD0[l].SetFloat(CullFarDistance, 20);
                        }

                        for (int l = 0; l <= vegetationItemModelInfo.VegetationMeshLod0.subMeshCount - 1; l++)
                        {
                            Material tempMaterial = new Material(vegetationItemModelInfo.VegetationMaterialsLOD0[l]);
                            tempMaterial.shader = overrideShader;
                            tempMaterial.SetPass(0);
                            for (int m = 0; m <= vegetationInstanceList.Length - 1; m++)
                            {
                                Graphics.DrawMeshNow(vegetationItemModelInfo.VegetationMeshLod0, vegetationInstanceList[m].Matrix);
                            }
                            DestroyImmediate(tempMaterial);
                        }
                    }
                    EditorUtility.ClearProgressBar();
                }
            }
        }
Exemplo n.º 2
0
        bool RenderVegetationType(VegetationType vegetationType, ShadowMaskCreator shadowMaskCreator)
        {
            switch (vegetationType)
            {
            case VegetationType.Grass:
                return(false);

            case VegetationType.Plant:
                return(false);

            case VegetationType.Tree:
                return(shadowMaskCreator.IncludeTrees);

            case VegetationType.Objects:
                return(false);

            case VegetationType.LargeObjects:
                return(shadowMaskCreator.IncludeLargeObjects);
            }
            return(false);
        }
Exemplo n.º 3
0
        public override void OnInspectorGUI()
        {
            HelpTopic = "vegetation-shadow-mask-creator";
            ShowLogo  = false;

            ShadowMaskCreator   shadowMaskCreator   = (ShadowMaskCreator)target;
            VegetationSystemPro vegetationSystemPro = shadowMaskCreator.gameObject.GetComponent <VegetationSystemPro>();

            if (!vegetationSystemPro)
            {
                {
                    EditorGUILayout.HelpBox("Add this component to a GameObject with a VegetationSystemPro component.",
                                            MessageType.Error);
                    return;
                }
            }

            base.OnInspectorGUI();

            if (vegetationSystemPro)
            {
                GUILayout.BeginVertical("box");
                shadowMaskCreator.AreaRect = EditorGUILayout.RectField("Area", shadowMaskCreator.AreaRect);
                EditorGUILayout.HelpBox(
                    "You can snap the area to any added terrain, total world area or manually setting the area for generation.",
                    MessageType.Info);
                GUILayout.EndVertical();


                GUILayout.BeginVertical("box");
                GUILayout.BeginHorizontal();
                string[] terrains = new string[vegetationSystemPro.VegetationStudioTerrainList.Count];
                for (int i = 0; i <= vegetationSystemPro.VegetationStudioTerrainList.Count - 1; i++)
                {
                    terrains[i] = vegetationSystemPro.VegetationStudioTerrainObjectList[i].name;
                }

                _selectedTerrainIndex = EditorGUILayout.Popup("Select terrain", _selectedTerrainIndex, terrains);
                if (GUILayout.Button("Snap to terrain", GUILayout.Width(120)))
                {
                    IVegetationStudioTerrain iVegetationStudioTerrain =
                        vegetationSystemPro.VegetationStudioTerrainList[_selectedTerrainIndex];
                    Bounds bounds = iVegetationStudioTerrain.TerrainBounds;
                    shadowMaskCreator.AreaRect = RectExtension.CreateRectFromBounds(bounds);
                }

                GUILayout.EndHorizontal();

                if (GUILayout.Button("Snap to world area"))
                {
                    shadowMaskCreator.AreaRect =
                        RectExtension.CreateRectFromBounds(vegetationSystemPro.VegetationSystemBounds);
                }

                EditorGUILayout.HelpBox(
                    "You can snap the area to any added terrain, total world area or manually setting the rect.",
                    MessageType.Info);

                GUILayout.EndVertical();

                GUILayout.BeginVertical("box");
                EditorGUILayout.LabelField("Settings", LabelStyle);
                shadowMaskCreator.ShadowMaskQuality =
                    (ShadowMaskQuality)EditorGUILayout.EnumPopup("Mask resolution",
                                                                 shadowMaskCreator.ShadowMaskQuality);
                EditorGUILayout.HelpBox(
                    "Pixel resolution of the shadow mask. Low = 1024x1024, Normal = 2048x2048, High = 4096x4096 and Ultra = 8192x8192",
                    MessageType.Info);

                GUILayout.EndVertical();

                GUILayout.BeginVertical("box");
                EditorGUILayout.LabelField("Included vegetation", LabelStyle);
                shadowMaskCreator.IncludeTrees        = EditorGUILayout.Toggle("Include Trees", shadowMaskCreator.IncludeTrees);
                shadowMaskCreator.IncludeLargeObjects = EditorGUILayout.Toggle("Include Large Objects", shadowMaskCreator.IncludeLargeObjects);
                GUILayout.EndVertical();

                if (GUILayout.Button("Generate shadow mask"))
                {
                    GenerateVegetationShadowMask(vegetationSystemPro);
                }
            }
        }
Exemplo n.º 4
0
        private void GenerateVegetationShadowMask(VegetationSystemPro vegetationSystem)
        {
            string path = EditorUtility.SaveFilePanelInProject("Save mask background", "", "png",
                                                               "Please enter a file name to save the mask background to");

            if (path.Length != 0)
            {
                ShadowMaskCreator shadowMaskCreator = (ShadowMaskCreator)target;

                //Terrain selectedTerrain = vegetationSystem.currentTerrain;
                //if (selectedTerrain == null) return;

                GameObject cameraObject = new GameObject {
                    name = "Mask Background camera"
                };

                int    textureResolution = shadowMaskCreator.GetShadowMaskQualityPixelResolution(shadowMaskCreator.ShadowMaskQuality);
                Shader heightShader      = Shader.Find("AwesomeTechnologies/Shadows/ShadowHeight");

                RenderTexture rtDown =
                    new RenderTexture(textureResolution, textureResolution, 24, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear)
                {
                    wrapMode         = TextureWrapMode.Clamp,
                    filterMode       = FilterMode.Trilinear,
                    autoGenerateMips = false
                };

                RenderTexture rtUp =
                    new RenderTexture(textureResolution, textureResolution, 24, RenderTextureFormat.RFloat, RenderTextureReadWrite.Linear)
                {
                    wrapMode         = TextureWrapMode.Clamp,
                    filterMode       = FilterMode.Trilinear,
                    autoGenerateMips = false
                };

                Camera backgroundCamera = cameraObject.AddComponent <Camera>();
                backgroundCamera.targetTexture = rtDown;

                backgroundCamera.clearFlags       = CameraClearFlags.Color;
                backgroundCamera.backgroundColor  = Color.black;
                backgroundCamera.orthographic     = true;
                backgroundCamera.orthographicSize = shadowMaskCreator.AreaRect.size.x / 2f;
                backgroundCamera.farClipPlane     = 20000;
                backgroundCamera.cullingMask      = 1 << shadowMaskCreator.InvisibleLayer;
                backgroundCamera.SetReplacementShader(heightShader, "");

                cameraObject.transform.position = new Vector3(shadowMaskCreator.AreaRect.x, 0, shadowMaskCreator.AreaRect.y) +
                                                  new Vector3(shadowMaskCreator.AreaRect.size.x / 2f, 1000,
                                                              shadowMaskCreator.AreaRect.size.y / 2f);
                cameraObject.transform.rotation = Quaternion.Euler(90, 0, 0);

                RenderTexture.active = rtDown;


                Graphics.SetRenderTarget(rtDown);
                GL.Viewport(new Rect(0, 0, rtDown.width, rtDown.height));
                GL.Clear(true, true, new Color(0, 0, 0, 0), 1f);

                GL.PushMatrix();
                GL.LoadProjectionMatrix(backgroundCamera.projectionMatrix);
                GL.modelview = backgroundCamera.worldToCameraMatrix;
                GL.PushMatrix();
                RenderVegetationNow(vegetationSystem, shadowMaskCreator);

                GL.PopMatrix();
                GL.PopMatrix();


                cameraObject.transform.position = new Vector3(shadowMaskCreator.AreaRect.x, 0, shadowMaskCreator.AreaRect.y) +
                                                  new Vector3(shadowMaskCreator.AreaRect.size.x / 2f, -1000,
                                                              shadowMaskCreator.AreaRect.size.y / 2f);
                cameraObject.transform.rotation = Quaternion.Euler(-90, 0, 0);
                RenderTexture.active            = rtUp;
                backgroundCamera.targetTexture  = rtUp;


                Graphics.SetRenderTarget(rtUp);
                GL.Viewport(new Rect(0, 0, rtUp.width, rtUp.height));
                GL.Clear(true, true, new Color(0, 0, 0, 0), 1f);

                GL.PushMatrix();
                GL.LoadProjectionMatrix(backgroundCamera.projectionMatrix);
                GL.modelview = backgroundCamera.worldToCameraMatrix;
                GL.PushMatrix();
                RenderVegetationNow(vegetationSystem, shadowMaskCreator);

                GL.PopMatrix();
                GL.PopMatrix();

                EditorUtility.DisplayProgressBar("Create shadow mask", "Render vegetation", 0f);
                RenderTexture.active = null;

                ShadowMapData[] outputHeights      = new ShadowMapData[textureResolution * textureResolution];
                ComputeBuffer   outputHeightBuffer = new ComputeBuffer(textureResolution * textureResolution, 8);

                ComputeShader decodeShader       = (ComputeShader)Resources.Load("DecodeShadowHeight");
                int           decodeKernelHandle = decodeShader.FindKernel("CSMain");
                decodeShader.SetTexture(decodeKernelHandle, "InputDown", rtDown);
                decodeShader.SetTexture(decodeKernelHandle, "InputUp", rtUp);
                decodeShader.SetBuffer(decodeKernelHandle, "OutputHeightBuffer", outputHeightBuffer);
                decodeShader.SetInt("TextureResolution", textureResolution);
                decodeShader.Dispatch(decodeKernelHandle, textureResolution / 8, textureResolution / 8, 1);
                outputHeightBuffer.GetData(outputHeights);
                outputHeightBuffer.Dispose();

                EditorUtility.DisplayProgressBar("Create shadow mask", "Calculate heights", 0.33f);
                Texture2D outputTexture = new Texture2D(textureResolution, textureResolution, TextureFormat.RGBA32, true);
                Color32[] outputColors  = new Color32[outputHeights.Length];

                float minTerrainHeight = vegetationSystem.VegetationSystemBounds.min.y;

                for (int x = 0; x <= textureResolution - 1; x++)
                {
                    for (int y = 0; y <= textureResolution - 1; y++)
                    {
                        int i = x + y * textureResolution;

                        float xNormalized = (float)x / textureResolution;
                        float yNormalized = (float)y / textureResolution;

                        float terrainHeight = sampleTerrainHeight(xNormalized, yNormalized, shadowMaskCreator.AreaRect);

                        float vegetationHeightUp = outputHeights[i].BottomHeight - minTerrainHeight;
                        float relativeHeightUp   = Mathf.Clamp((vegetationHeightUp - terrainHeight) * 4, 0, 255);

                        float vegetationHeightDown = outputHeights[i].TopHeight - minTerrainHeight;
                        float relativeHeightDown   = Mathf.Clamp((vegetationHeightDown - terrainHeight) * 4, 0, 255);

                        if (relativeHeightUp > relativeHeightDown)
                        {
                            relativeHeightUp = relativeHeightDown;
                        }

                        outputColors[i].a = 255;
                        outputColors[i].r = (byte)relativeHeightDown;
                        outputColors[i].g = 0;
                        outputColors[i].b = 0;
                    }
                }

                outputTexture.SetPixels32(outputColors);
                outputTexture.Apply();

                backgroundCamera.targetTexture = null;
                DestroyImmediate(rtDown);
                DestroyImmediate(rtUp);

                SaveTexture(outputTexture, path);
                DestroyImmediate(cameraObject);
                DestroyImmediate(outputTexture);
                GC.Collect();

                EditorUtility.DisplayProgressBar("Create shadow mask", "importing asset", 0.66f);
                string assetPath = path;
                var    tImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
                if (tImporter != null)
                {
                    tImporter.textureType    = TextureImporterType.Default;
                    tImporter.filterMode     = FilterMode.Point;
                    tImporter.maxTextureSize = 8192;
                    tImporter.SaveAndReimport();
                }
                EditorUtility.ClearProgressBar();
            }
        }