Exemple #1
0
    // call this to generate the planet texture maps
    bool GeneratePlanetTextureMaps(PG_Planet pgPlanet, string filename)
    {
        // vars for the progress bar
        var currentStep = 1;
        var totalSteps  = 8;

        // update the progress bar
        EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Preparing color map...", (float)currentStep++ / totalSteps);

        // prepare the color map
        var preparedColorMap = PrepareColorMap(pgPlanet);

        if (m_debugMode)
        {
            EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving prepared color map...", 0.0f);

            PG_Tools.SaveAsPNG(preparedColorMap, Application.dataPath + "/Exported/Debug - Prepared Color Map.png");
        }

        // update the progress bar
        EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Preparing height map...", (float)currentStep++ / totalSteps);

        // prepare the height map
        var preparedHeightMap = PrepareHeightMap(pgPlanet);

        if (m_debugMode)
        {
            EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving prepared height map...", 0.0f);

            PG_Tools.SaveAsPNG(preparedHeightMap, Application.dataPath + "/Exported/Debug - Prepared Height Map.png");
        }

        float minimumDifference = 0.0f;
        float maximumDifference = 0.0f;

        byte[] differenceBuffer = null;

        if (pgPlanet.m_surfaceId != 1)
        {
            // scale to power of two
            EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Scaling to power of two...", (float)currentStep++ / totalSteps);

            var bicubicScale = new PG_BicubicScaleElevation();

            var elevation = bicubicScale.Process(preparedHeightMap, m_textureMapWidth, m_textureMapHeight);

            if (m_debugMode)
            {
                EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving bicubic scale map...", 0.0f);

                var contourMap = new PG_ContourMap();

                var tempBuffer = contourMap.Process(elevation, pgPlanet.m_waterElevation);

                PG_Tools.SaveAsEXR(tempBuffer, Application.dataPath + "/Exported/Debug - Bicubic Scale.exr");
            }

            // craters pass
            EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Creating craters...", (float)currentStep++ / totalSteps);

            if (pgPlanet.m_atmosphericDensityId == 0)
            {
                var craters = new PG_Craters();

                elevation = craters.Process(elevation, pgPlanet.m_id, m_craterGain, pgPlanet.m_waterElevation);

                if (m_debugMode)
                {
                    EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving craters map...", 0.0f);

                    var contourMap = new PG_ContourMap();

                    var tempBuffer = contourMap.Process(elevation, pgPlanet.m_waterElevation);

                    PG_Tools.SaveAsEXR(tempBuffer, Application.dataPath + "/Exported/Debug - Craters.exr");
                }
            }

            // at this point we want to save the current elevation buffer to use when calculating the difference map later
            var baseElevationBuffer = elevation;

            // mountains pass
            EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Creating mountains...", (float)currentStep++ / totalSteps);

            if (pgPlanet.m_atmosphericDensityId != 0)
            {
                var mountains = new PG_Mountains();

                elevation = mountains.Process(elevation, pgPlanet.m_id, m_octaves, m_mountainScale, m_mountainLacunarity, m_mountainPersistence, m_mountainGain, pgPlanet.m_waterElevation);

                if (m_debugMode)
                {
                    EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving mountains map...", 0.0f);

                    var contourMap = new PG_ContourMap();

                    var tempBuffer = contourMap.Process(elevation, pgPlanet.m_waterElevation);

                    PG_Tools.SaveAsEXR(tempBuffer, Application.dataPath + "/Exported/Debug - Mountains.exr");
                }
            }

            // hydraulic erosion pass
            var minimumElevation = pgPlanet.m_waterElevation - (pgPlanet.m_waterElevation / 16.0f);

            EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Hydraulic erosion pass...", (float)currentStep++ / totalSteps);

            if (m_doHydraulicErosionPass)
            {
                if (pgPlanet.m_atmosphericDensityId != 0)
                {
                    var hydraulicErosion = new PG_HydraulicErosion();

                    var gravityConstant = m_gravityConstant * pgPlanet.m_gravity;
                    var rainWaterAmount = m_rainWaterAmount * (float)pgPlanet.m_atmosphericDensityId / 3.0f;

                    elevation = hydraulicErosion.Process(elevation, minimumElevation, m_xyScaleToMeters, m_zScaleToMeters, rainWaterAmount, m_sedimentCapacity, gravityConstant, m_frictionConstant, m_evaporationConstant, m_depositionConstant, m_dissolvingConstant, m_stepDeltaTime, m_finalBlurRadius);

                    if (elevation == null)
                    {
                        return(false);
                    }

                    if (m_debugMode)
                    {
                        EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving hydraulic erosion map...", 0.0f);

                        var contourMap = new PG_ContourMap();

                        var tempBuffer = contourMap.Process(elevation, pgPlanet.m_waterElevation);

                        PG_Tools.SaveAsEXR(tempBuffer, Application.dataPath + "/Exported/Debug - Hydraulic Erosion.exr");
                    }
                }
            }

            if (m_debugMode)
            {
                // generate and save the albedo map
                EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving albedo map...", 0.0f);

                var albedoMap = new PG_AlbedoMap();

                var albedoBuffer = albedoMap.Process(elevation, preparedColorMap, pgPlanet.m_waterElevation, pgPlanet.m_waterColor, pgPlanet.m_groundColor);

                PG_Tools.SaveAsPNG(albedoBuffer, Application.dataPath + "/Exported/Debug - Albedo Map.png");

                // generate and save the normal map
                EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving normal map...", 0.0f);

                var normalMap = new PG_NormalMap();

                var normalsBuffer = normalMap.Process(elevation, 256.0f, pgPlanet.m_waterElevation, 1);

                PG_Tools.SaveAsPNG(normalsBuffer, Application.dataPath + "/Exported/Debug - Normal Map.png");

                // generate and save the specular map
                EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving specular map...", 0.0f);

                var waterSpecularColor = new Color(1.0f, 1.0f, 1.0f);

                var specularMap = new PG_SpecularMap();

                var specularBuffer = specularMap.Process(elevation, albedoBuffer, pgPlanet.m_waterElevation, waterSpecularColor, 0.75f, 1);

                PG_Tools.SaveAsPNG(specularBuffer, Application.dataPath + "/Exported/Debug - Specular Map.png", true);

                // generate and save the water mask map
                EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving water mask map...", 0.0f);

                var waterMaskMap = new PG_WaterMaskMap();

                var waterMaskBuffer = waterMaskMap.Process(elevation, pgPlanet.m_waterElevation, 1);

                PG_Tools.SaveAsPNG(waterMaskBuffer, Application.dataPath + "/Exported/Debug - Water Mask Map.png", true);

                // generate and save the elevation map (for the terrain grid)
                EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving elevation map...", 0.0f);

                PG_Tools.SaveAsEXR(elevation, Application.dataPath + "/Exported/Debug - Elevation Map.exr");
            }

            // figure out what our minimum and maximum deltas are
            EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Computing deltas...", (float)currentStep++ / totalSteps);

            minimumDifference = 0;
            maximumDifference = 0;

            for (var y = 0; y < m_textureMapHeight; y++)
            {
                for (var x = 0; x < m_textureMapWidth; x++)
                {
                    var difference = elevation[y, x] - baseElevationBuffer[y, x];

                    if (difference < minimumDifference)
                    {
                        minimumDifference = difference;
                    }

                    if (difference > maximumDifference)
                    {
                        maximumDifference = difference;
                    }
                }
            }

            // rescale float deltas to 0 to 255
            var elevationScale = 255.0f / (maximumDifference - minimumDifference);

            differenceBuffer = new byte[m_textureMapWidth * m_textureMapHeight];

            for (var y = 0; y < m_textureMapHeight; y++)
            {
                for (var x = 0; x < m_textureMapWidth; x++)
                {
                    var difference = (byte)Mathf.RoundToInt((elevation[y, x] - baseElevationBuffer[y, x] - minimumDifference) * elevationScale);

                    differenceBuffer[y * m_textureMapWidth + x] = difference;

                    elevation[y, x] = difference / 255.0f;
                }
            }

            if (m_debugMode)
            {
                EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Saving difference buffer...", 0.0f);

                PG_Tools.SaveAsPNG(elevation, Application.dataPath + "/Exported/" + "Debug - Difference Buffer.png");

                AssetDatabase.Refresh();
            }
        }

        // save the map!
        EditorUtility.DisplayProgressBar("Planet " + (pgPlanet.m_id + 1), "Compressing and saving the planet data...", (float)currentStep++ / totalSteps);

        SavePlanetMap(filename, pgPlanet, preparedHeightMap, preparedColorMap, minimumDifference, maximumDifference, differenceBuffer);

        return(true);
    }
Exemple #2
0
    public void AsyncProcess(byte[] bytes)
    {
        var progressStepSize = 0.5f / 12.0f;

        m_progress += progressStepSize;

        // decompress the planet data
        using (var memoryStream = new MemoryStream(bytes))
        {
            using (var gZipStream = new GZipStream(memoryStream, CompressionMode.Decompress, false))
            {
                var binaryReader = new BinaryReader(gZipStream);

                var version = binaryReader.ReadInt32();

                if (version != c_versionNumber)
                {
                    m_abort = true;
                }
                else
                {
                    m_minimumElevation = binaryReader.ReadSingle();
                    m_waterElevation   = binaryReader.ReadSingle();
                    m_snowElevation    = binaryReader.ReadSingle();

                    var r = binaryReader.ReadSingle();
                    var g = binaryReader.ReadSingle();
                    var b = binaryReader.ReadSingle();

                    m_waterColor = new Color(r, g, b);

                    r = binaryReader.ReadSingle();
                    g = binaryReader.ReadSingle();
                    b = binaryReader.ReadSingle();

                    m_groundColor = new Color(r, g, b);

                    r = binaryReader.ReadSingle();
                    g = binaryReader.ReadSingle();
                    b = binaryReader.ReadSingle();

                    m_snowColor = new Color(r, g, b);

                    var preparedMapWidth  = binaryReader.ReadInt32();
                    var preparedMapHeight = binaryReader.ReadInt32();

                    m_preparedHeightMap = new float[preparedMapHeight, preparedMapWidth];

                    for (var y = 0; y < preparedMapHeight; y++)
                    {
                        for (var x = 0; x < preparedMapWidth; x++)
                        {
                            m_preparedHeightMap[y, x] = binaryReader.ReadSingle();
                        }
                    }

                    m_preparedColorMap = new Color[preparedMapHeight, preparedMapWidth];

                    for (var y = 0; y < preparedMapHeight; y++)
                    {
                        for (var x = 0; x < preparedMapWidth; x++)
                        {
                            r = binaryReader.ReadSingle();
                            g = binaryReader.ReadSingle();
                            b = binaryReader.ReadSingle();

                            m_preparedColorMap[y, x] = new Color(r, g, b);
                        }
                    }

                    if (m_planet.IsGasGiant())
                    {
                        m_textureMapWidth  = c_gasGiantTextureMapWidth;
                        m_textureMapHeight = c_gasGiantTextureMapHeight;
                    }
                    else
                    {
                        m_textureMapWidth  = c_nonGasGiantTextureMapWidth;
                        m_textureMapHeight = c_nonGasGiantTextureMapHeight;

                        m_minimumDifference = binaryReader.ReadSingle();
                        m_maximumDifference = binaryReader.ReadSingle();

                        var differenceBufferSize = m_textureMapWidth * m_textureMapHeight;

                        m_differenceBuffer = new byte[differenceBufferSize];

                        gZipStream.Read(m_differenceBuffer, 0, differenceBufferSize);
                    }
                }
            }
        }

        // gas giant or not?
        if (m_planet.IsGasGiant())
        {
            // yes - do color bicubic scale
            m_progress += progressStepSize;

            var bicubicScaleColor = new PG_BicubicScaleColor();

            m_albedoMap = bicubicScaleColor.Process(m_preparedColorMap, m_textureMapWidth, m_textureMapHeight);

            // do color gaussian blur (this becomes our albedo map)
            m_progress += progressStepSize;

            var gaussianBlurColor = new PG_GaussianBlurColor();

            m_albedoMap = gaussianBlurColor.Process(m_albedoMap, c_xBlurRadiusGasGiant, c_yBlurRadiusGasGiant);

            // do elevation bicubic scale
            m_progress += progressStepSize;

            var bicubicScaleElevation = new PG_BicubicScaleElevation();

            m_elevation = bicubicScaleElevation.Process(m_preparedHeightMap, m_textureMapWidth, m_textureMapHeight);

            // do elevation gaussian blur
            m_progress += progressStepSize;

            var gaussianBlurElevation = new PG_GaussianBlurElevation();

            m_elevation = gaussianBlurElevation.Process(m_elevation, c_xBlurRadiusGasGiant, c_yBlurRadiusGasGiant);

            // build specular map
            m_progress += progressStepSize;

            m_specularMap = new Color[m_textureMapHeight, m_textureMapWidth];

            for (var y = 0; y < m_textureMapHeight; y++)
            {
                for (var x = 0; x < m_textureMapWidth; x++)
                {
                    var elevation = m_elevation[y, x];

                    m_specularMap[y, x] = new Color(elevation, elevation, elevation, 0.25f);
                }
            }

            // build water mask map
            m_progress += progressStepSize;

            m_waterMaskMap = new Color[4, 4];

            for (var y = 0; y < 4; y++)
            {
                for (var x = 0; x < 4; x++)
                {
                    m_waterMaskMap[y, x] = Color.black;
                }
            }

            // build normal map
            m_progress += progressStepSize;

            m_normalMap = new Color[4, 4];

            var defaultNormal = new Color(0.5f, 0.5f, 1.0f);

            for (var y = 0; y < 4; y++)
            {
                for (var x = 0; x < 4; x++)
                {
                    m_normalMap[y, x] = defaultNormal;
                }
            }
        }
        else
        {
            // do elevation bicubic scale
            m_progress += progressStepSize;

            var bicubicScaleElevation = new PG_BicubicScaleElevation();

            m_elevation = bicubicScaleElevation.Process(m_preparedHeightMap, m_textureMapWidth, m_textureMapHeight);

            // do craters
            m_progress += progressStepSize;

            if (m_planet.m_atmosphereDensityId == 0)
            {
                var craters = new PG_Craters();

                m_elevation = craters.Process(m_elevation, m_planet.m_id, 0.1f, m_waterElevation);
            }

            // factor in elevation difference map
            m_progress += progressStepSize;

            m_maximumElevation = 0.0f;

            var elevationScale = (m_maximumDifference - m_minimumDifference) / 255.0f;

            for (var y = 0; y < m_textureMapHeight; y++)
            {
                for (var x = 0; x < m_textureMapWidth; x++)
                {
                    var difference = m_differenceBuffer[y * m_textureMapWidth + x];

                    m_elevation[y, x] += (difference * elevationScale) + m_minimumDifference;

                    m_maximumElevation = Mathf.Max(m_maximumElevation, m_elevation[y, x]);
                }
            }

            // build albedo map
            m_progress += progressStepSize;

            var albedoMap = new PG_AlbedoMap();

            m_albedoMap = albedoMap.Process(m_elevation, m_preparedColorMap, m_waterElevation, m_waterColor, m_groundColor);

            // build specular map
            m_progress += progressStepSize;

            var waterSpecularColor = m_planet.IsMolten() ? new Color(0.75f, 0.125f, 0.125f) : new Color(1.0f, 1.0f, 1.0f);

            var waterSpecularPower = m_planet.IsMolten() ? 0.4f : 0.75f;

            var specularMap = new PG_SpecularMap();

            m_specularMap = specularMap.Process(m_elevation, m_albedoMap, m_waterElevation, waterSpecularColor, waterSpecularPower, 4);

            // build water mask map
            m_progress += progressStepSize;

            var waterMaskMap = new PG_WaterMaskMap();

            m_waterMaskMap = waterMaskMap.Process(m_elevation, m_waterElevation, 4);

            // build normal map
            m_progress += progressStepSize;

            var normalMap = new PG_NormalMap();

            m_normalMap = normalMap.Process(m_elevation, c_normalScale, m_waterElevation, 2);
        }

        // get albedo pixels
        m_progress += progressStepSize;

        m_albedoPixels = new Color[m_textureMapWidth * m_textureMapHeight];

        var index = 0;

        for (var y = 0; y < m_textureMapHeight; y++)
        {
            for (var x = 0; x < m_textureMapWidth; x++)
            {
                m_albedoPixels[index++] = m_albedoMap[y, x];
            }
        }

        // get specular pixels
        m_progress += progressStepSize;

        var textureMapWidth  = m_specularMap.GetLength(1);
        var textureMapHeight = m_specularMap.GetLength(0);

        m_specularPixels = new Color[textureMapWidth * textureMapHeight];

        index = 0;

        for (var y = 0; y < textureMapHeight; y++)
        {
            for (var x = 0; x < textureMapWidth; x++)
            {
                m_specularPixels[index++] = m_specularMap[y, x];
            }
        }

        // get water mask pixels
        m_progress += progressStepSize;

        textureMapWidth  = m_waterMaskMap.GetLength(1);
        textureMapHeight = m_waterMaskMap.GetLength(0);

        m_waterMaskPixels = new Color[textureMapWidth * textureMapHeight];

        index = 0;

        for (var y = 0; y < textureMapHeight; y++)
        {
            for (var x = 0; x < textureMapWidth; x++)
            {
                m_waterMaskPixels[index++] = m_waterMaskMap[y, x];
            }
        }

        // get normal pixels
        m_progress += progressStepSize;

        textureMapWidth  = m_normalMap.GetLength(1);
        textureMapHeight = m_normalMap.GetLength(0);

        m_normalPixels = new Color[textureMapWidth * textureMapHeight];

        index = 0;

        for (var y = 0; y < textureMapHeight; y++)
        {
            for (var x = 0; x < textureMapWidth; x++)
            {
                m_normalPixels[index++] = new Color(0.0f, m_normalMap[y, x].g, 0.0f, m_normalMap[y, x].r);
            }
        }

        m_step = 20;
    }