コード例 #1
0
ファイル: ImageConstruct.cs プロジェクト: psarras/Image-Tools
        public static Bitmap CreateMarbleTexture(Bitmap img, double firstLevel, double preserveLevel)
        {
            Bitmap sourceImage = ImageUtil.convert(img, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

            Texturer myFilter = new Texturer(new MarbleTexture(), firstLevel, preserveLevel); //Needs Expand

            return(myFilter.Apply(sourceImage));
        }
コード例 #2
0
        //apply couds texture to smudge the image
        private static Bitmap Texturize(Bitmap image)
        {
            IRandomNumberGenerator generator = new GaussianGenerator(-.25f, 0.3f);

            // create filter
            Texturer filter = new Texturer(new CloudsTexture(), generator.Next(), .995);//.98

            // apply the filter
            return(filter.Apply(image));
        }
コード例 #3
0
        public static byte[] ApplyFilter(byte[] imageBytes, ImageProcessingFilters filter, ImageFormat format = null)
        {
            IFilter baseFilter = null;

            switch (filter)
            {
            case ImageProcessingFilters.Default:
                return(imageBytes);

            case ImageProcessingFilters.GrayscaleBT709:
                baseFilter = new GrayscaleBT709();
                break;

            case ImageProcessingFilters.GrayscaleRMY:
                baseFilter = new GrayscaleRMY();
                break;

            case ImageProcessingFilters.GrayscaleY:
                baseFilter = new GrayscaleY();
                break;

            case ImageProcessingFilters.BayerFilter:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new ExtractChannel(RGB.B));
                ((FiltersSequence)baseFilter).Add(new BayerFilter());
                break;

            /*
             * case ImageProcessingFilters.ImageWarp:
             * baseFilter = new ImageWarp(
             * break;
             * */
            case ImageProcessingFilters.Channel_Red:
                baseFilter = new ExtractChannel(RGB.R);
                break;

            case ImageProcessingFilters.Channel_Green:
                baseFilter = new ExtractChannel(RGB.G);
                break;

            case ImageProcessingFilters.Channel_Blue:
                baseFilter = new ExtractChannel(RGB.B);
                break;

            case ImageProcessingFilters.WaterWave:
                baseFilter = new WaterWave();
                ((WaterWave)baseFilter).HorizontalWavesCount     = 10;
                ((WaterWave)baseFilter).HorizontalWavesAmplitude = 5;
                ((WaterWave)baseFilter).VerticalWavesCount       = 3;
                ((WaterWave)baseFilter).VerticalWavesAmplitude   = 15;
                break;

            case ImageProcessingFilters.Sepia:
                baseFilter = new Sepia();
                break;

            case ImageProcessingFilters.BrightnessCorrection:
                baseFilter = new BrightnessCorrection(-50);
                break;

            case ImageProcessingFilters.ContrastCorrection:
                baseFilter = new ContrastCorrection(15);
                break;

            case ImageProcessingFilters.SaturationCorrection1:
                baseFilter = new SaturationCorrection(-0.5f);
                break;

            case ImageProcessingFilters.SaturationCorrection2:
                baseFilter = new SaturationCorrection(-.25f);
                break;

            case ImageProcessingFilters.SaturationCorrection3:
                baseFilter = new SaturationCorrection(+0.5f);
                break;

            case ImageProcessingFilters.Invert:
                baseFilter = new Invert();
                break;

            case ImageProcessingFilters.Blur:
                baseFilter = new Blur();
                break;

            case ImageProcessingFilters.RotateChannels:
                baseFilter = new RotateChannels();
                break;

            case ImageProcessingFilters.RotateChannels2:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new RotateChannels());
                ((FiltersSequence)baseFilter).Add(new RotateChannels());
                break;

            case ImageProcessingFilters.AdditiveNoise:
                IRandomNumberGenerator generator = new UniformGenerator(new Range(-50, 50));
                baseFilter = new AdditiveNoise(generator);
                break;

            case ImageProcessingFilters.GammaCorrection:
                baseFilter = new GammaCorrection(0.5);
                break;

            case ImageProcessingFilters.HistogramEqualization:
                baseFilter = new HistogramEqualization();
                break;

            case ImageProcessingFilters.OrderedDithering:
                byte[,] matrix = new byte[4, 4]
                {
                    { 95, 233, 127, 255 },
                    { 159, 31, 191, 63 },
                    { 111, 239, 79, 207 },
                    { 175, 47, 143, 15 }
                };
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new GrayscaleBT709());
                ((FiltersSequence)baseFilter).Add(new OrderedDithering(matrix));
                break;

            case ImageProcessingFilters.Pixallete:
                baseFilter = new Pixellate();
                break;

            case ImageProcessingFilters.SimplePosterization:
                baseFilter = new SimplePosterization();
                break;

            case ImageProcessingFilters.Texturer_Textile:
                baseFilter = new Texturer(new AForge.Imaging.Textures.TextileTexture(), 0.3, 0.7);
                break;

            case ImageProcessingFilters.Texturer_Cloud:
                baseFilter = new Texturer(new AForge.Imaging.Textures.CloudsTexture(), 0.3, 0.7);
                break;

            case ImageProcessingFilters.Texturer_Marble:
                baseFilter = new Texturer(new AForge.Imaging.Textures.MarbleTexture(), 0.3, 0.7);
                break;

            case ImageProcessingFilters.Texturer_Wood:
                baseFilter = new Texturer(new AForge.Imaging.Textures.WoodTexture(), 0.3, 0.7);
                break;

            case ImageProcessingFilters.Texturer_Labyrinth:
                baseFilter = new Texturer(new AForge.Imaging.Textures.LabyrinthTexture(), 0.3, 0.7);
                break;

            case ImageProcessingFilters.SobelEdgeDetector:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new ExtractChannel(RGB.R));
                ((FiltersSequence)baseFilter).Add(new SobelEdgeDetector());
                break;

            case ImageProcessingFilters.SobelEdgeDetectorInvert:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new ExtractChannel(RGB.R));
                ((FiltersSequence)baseFilter).Add(new SobelEdgeDetector());
                ((FiltersSequence)baseFilter).Add(new Invert());
                break;

            case ImageProcessingFilters.SobelEdgeDetectorSepia:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new ExtractChannel(RGB.R));
                ((FiltersSequence)baseFilter).Add(new SobelEdgeDetector());
                ((FiltersSequence)baseFilter).Add(new GrayscaleToRGB());
                ((FiltersSequence)baseFilter).Add(new Sepia());
                break;

            case ImageProcessingFilters.SobelEdgeDetectorSepiaCanvas:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new ExtractChannel(RGB.R));
                ((FiltersSequence)baseFilter).Add(new SobelEdgeDetector());
                ((FiltersSequence)baseFilter).Add(new GrayscaleToRGB());
                ((FiltersSequence)baseFilter).Add(new Sepia());
                ((FiltersSequence)baseFilter).Add(new SimplePosterization());
                ((FiltersSequence)baseFilter).Add(new Texturer(new AForge.Imaging.Textures.TextileTexture(), 0.3, 0.7));
                break;

            case ImageProcessingFilters.Drawing:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new GrayscaleBT709());
                ((FiltersSequence)baseFilter).Add(new SobelEdgeDetector());
                ((FiltersSequence)baseFilter).Add(new Invert());
                ((FiltersSequence)baseFilter).Add(new SimplePosterization());
                break;

            case ImageProcessingFilters.DrawingSepia:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new GrayscaleBT709());
                ((FiltersSequence)baseFilter).Add(new SobelEdgeDetector());
                ((FiltersSequence)baseFilter).Add(new Invert());
                ((FiltersSequence)baseFilter).Add(new SimplePosterization());
                ((FiltersSequence)baseFilter).Add(new GrayscaleToRGB());
                ((FiltersSequence)baseFilter).Add(new Sepia());
                break;

            case ImageProcessingFilters.OilCanvas:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new SimplePosterization());
                ((FiltersSequence)baseFilter).Add(new Texturer(new AForge.Imaging.Textures.TextileTexture(), 0.3, 0.7));
                break;

            case ImageProcessingFilters.OilCanvasGray:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new SimplePosterization());
                ((FiltersSequence)baseFilter).Add(new Texturer(new AForge.Imaging.Textures.TextileTexture(), 0.3, 0.7));
                ((FiltersSequence)baseFilter).Add(new GrayscaleBT709());
                break;

            case ImageProcessingFilters.OilCanvasSepia:
                baseFilter = new FiltersSequence();
                ((FiltersSequence)baseFilter).Add(new SimplePosterization());
                ((FiltersSequence)baseFilter).Add(new Texturer(new AForge.Imaging.Textures.TextileTexture(), 0.3, 0.7));
                ((FiltersSequence)baseFilter).Add(new Sepia());
                break;
            }

            if (baseFilter == null)
            {
                return(null);
            }

            return(ApplyFilter(imageBytes, baseFilter, format));
        }
コード例 #4
0
ファイル: ChunkController.cs プロジェクト: einargizz/pgworld
	void Start () {
		noise = new PerlinNoise();
		noise.baseOctave = noiseBaseOctave;
		noise.weights = noiseWeights;
		noise.Init();

		chunkResolution = (int)Math.Pow(2, chunkExponent) + 1;
		chunkWidth = chunkResolution * chunkScale;

		chunks = new Hashtable();
		heightmapQueue = Queue.Synchronized(new Queue());

		reverseThermalEroder = new ThermalTerrainErosion();
		reverseThermalEroder.talus = this.reverseErosionTalus;
		reverseThermalEroder.strength = this.reverseErosionStrength;
		reverseThermalEroder.reverse = true;
		reverseThermalEroder.reverseTalusCutoff = this.reverseErosionReverseTalusCutoff ;
		reverseThermalEroder.iterations = this.reverseErosionIterations;

		thermalEroder = new ThermalTerrainErosion();
		thermalEroder.talus = this.thermalErosionTalus;
		thermalEroder.strength = this.thermalErosionStrength;
		thermalEroder.reverse = false;
		thermalEroder.iterations = this.thermalErosionIterations;

		hydraulicEroder = new HydraulicTerrainErosion();
		hydraulicEroder.rainfallAmount = hydraulicErosionRainfallAmount; // kr
		hydraulicEroder.evaporationRatio = hydraulicErosionEvaporationRatio; // ke
		hydraulicEroder.sedimentCapacity = hydraulicErosionSedimentCapacity; // kc
		hydraulicEroder.soilSolubility = hydraulicErosionSoilSolubility; // ks
		hydraulicEroder.rainAltitude = hydraulicErosionRainAltitude;
		hydraulicEroder.rainFalloff = hydraulicErosionRainFalloff;
		hydraulicEroder.iterations = hydraulicErosionIterations;

		texturer = new Texturer();
		texturer.slopeValue = slopeValue;
		texturer.mountainPeekHeight = mountainPeekHeight;
		texturer.waterHeight = waterHeight;
		splats = new SplatPrototype[diffuses.Length];

		for (var i = 0; i < diffuses.Length; i++) {
			splats[i] = new SplatPrototype();
			splats[i].texture = diffuses[i];
			splats[i].normalMap = normals[i];
			splats[i].tileSize = new Vector2(5, 5);
		}

		ensureChunk(new ChunkCoord(0, 0), false);
		ensureChunk(new ChunkCoord(-1, -1), true);
		ensureChunk(new ChunkCoord(0, -1), true);
		ensureChunk(new ChunkCoord(-1, 0), true);
	}
コード例 #5
0
        public static Bitmap FilterImage(Bitmap img, int filter)
        {
            Bitmap sourceImage = img;

            sourceImage = ImageUtil.convert(sourceImage, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            IFilter myFilter;
            Bitmap  filteredImage = sourceImage;

            if (filter == Filters.filters["Greyscale"])
            {
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                filteredImage = sourceImage;
            }
            else if (filter == Filters.filters["Sepia"])
            {
                myFilter      = new Sepia();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["Invert"])
            {
                sourceImage   = ImageUtil.convert(sourceImage, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                myFilter      = new Invert();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["RotateChannel"])
            {
                myFilter      = new RotateChannels();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["Threshold"])
            {
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new Threshold();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["FloydFilter"])
            {
                FloydSteinbergColorDithering myReduction = new FloydSteinbergColorDithering();
                filteredImage = myReduction.Apply(sourceImage);
            }
            else if (filter == Filters.filters["OrderedDithering"])
            {
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new OrderedDithering();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["Sharpen"])
            {
                myFilter      = new Sharpen();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["DifferenceEdgeDetector"])
            {
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new DifferenceEdgeDetector();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["HomogenityEdgeDetector"])
            {
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new HomogenityEdgeDetector();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["Sobel"])
            {
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new SobelEdgeDetector();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["Jitter"])
            {
                myFilter      = new Jitter(); //Needs Expand
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["OilPainting"])
            {
                sourceImage   = ImageUtil.convert(sourceImage, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                myFilter      = new OilPainting(); //Needs Expand
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["TextureFiltering"])
            {
                sourceImage   = ImageUtil.convert(sourceImage, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                myFilter      = new Texturer(new TextileTexture(), 1.0, 0.8); //Needs Expand
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["Median"])
            {
                sourceImage   = ImageUtil.convert(sourceImage, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                myFilter      = new Median();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["Mean"])
            {
                myFilter      = new Mean();
                filteredImage = myFilter.Apply(sourceImage);
            }
            else if (filter == Filters.filters["Blur"])
            {
                myFilter      = new GaussianBlur();
                filteredImage = myFilter.Apply(sourceImage);
            }

            //Console.Write(filteredImage.PixelFormat.ToString());
            //Console.Write(sourceImage.PixelFormat.ToString());
            filteredImage = ImageUtil.convert(filteredImage, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            return(filteredImage);
        }
コード例 #6
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Bitmap sourceImage = null;

            DA.GetData(0, ref sourceImage);
            string filter = "";

            DA.GetData(1, ref filter);


            sourceImage = ImageUtilities.convert(sourceImage, System.Drawing.Imaging.PixelFormat.Format32bppArgb);

            IFilter myFilter;
            Bitmap  filteredImage = sourceImage;

            //Grayscale.CommonAlgorithms.Y.Apply
            switch (filter)
            {
            case "Greyscale":
                Console.Write("Applying: " + filter);
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                filteredImage = sourceImage;
                break;

            case "Sepia":
                Console.Write("Applying: " + filter);
                myFilter      = new Sepia();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "Invert":
                Console.Write("Applying: " + filter);
                sourceImage   = ImageUtilities.convert(sourceImage, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                myFilter      = new Invert();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "RotateChannel":
                Console.Write("Applying: " + filter);
                myFilter      = new RotateChannels();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "Threshold":     //Need Extended Version
                Console.Write("Applying: " + filter);
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new Threshold();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "FloydFilter":
                Console.Write("Applying: " + filter);
                //sourceImage = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                //myFilter = new FloydSteinbergColorDithering();
                FloydSteinbergColorDithering myReduction = new FloydSteinbergColorDithering();
                filteredImage = myReduction.Apply(sourceImage);
                //filteredImage = myFilter.Apply(sourceImage);
                break;

            case "OrderedDithering":
                Console.Write("Applying: " + filter);
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new OrderedDithering();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "Sharpen":
                Console.Write("Applying: " + filter);
                myFilter      = new Sharpen();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "DifferenceEdgeDetector":
                Console.Write("Applying: " + filter);
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new DifferenceEdgeDetector();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "HomogenityEdgeDetector":
                Console.Write("Applying: " + filter);
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new HomogenityEdgeDetector();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "Sobel":
                Console.Write("Applying: " + filter);
                sourceImage   = Grayscale.CommonAlgorithms.RMY.Apply(sourceImage);
                myFilter      = new SobelEdgeDetector();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "Jitter":
                Console.Write("Applying: " + filter);
                myFilter      = new Jitter(); //Needs Expand
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "OilPainting":
                Console.Write("Applying: " + filter);
                myFilter      = new OilPainting(); //Needs Expand
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "TextureFiltering":
                Console.Write("Applying: " + filter);
                sourceImage   = ImageUtilities.convert(sourceImage, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                myFilter      = new Texturer(new TextileTexture(), 1.0, 0.8); //Needs Expand
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "Median":
                Console.Write("Applying: " + filter);
                myFilter      = new Median();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "Mean":
                Console.Write("Applying: " + filter);
                myFilter      = new Mean();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            case "Blur":     //Need Extended Version
                Console.Write("Applying: " + filter);
                myFilter      = new GaussianBlur();
                filteredImage = myFilter.Apply(sourceImage);
                break;

            default:
                Console.Write("No Filter");
                break;
            }

            Console.Write(filteredImage.PixelFormat.ToString());
            Console.Write(sourceImage.PixelFormat.ToString());
            filteredImage = ImageUtilities.convert(filteredImage, System.Drawing.Imaging.PixelFormat.Format32bppArgb);



            DA.SetData(0, filteredImage);
        }
コード例 #7
0
 public TexturerFilter()
 {
     texturer = new Texturer(new TextileTexture(), 1.0, 0.8);
 }
コード例 #8
0
ファイル: ChunkController.cs プロジェクト: sjl/pgworld
    void Start()
    {
        noise = new PerlinNoise ();
        noise.baseOctave = noiseBaseOctave;
        noise.weights = noiseWeights;
        noise.Init ();

        chunkResolution = (int)Math.Pow (2, chunkExponent) + 1;
        chunkWidth = chunkResolution * chunkScale;

        chunks = new Hashtable ();
        heightmapQueue = Queue.Synchronized (new Queue ());

        reverseThermalEroder = new ThermalTerrainErosion ();
        reverseThermalEroder.talus = this.reverseErosionTalus;
        reverseThermalEroder.strength = this.reverseErosionStrength;
        reverseThermalEroder.reverse = true;
        reverseThermalEroder.reverseTalusCutoff = this.reverseErosionReverseTalusCutoff;
        reverseThermalEroder.iterations = this.reverseErosionIterations;

        hydraulicEroder = new HydraulicTerrainErosion ();
        hydraulicEroder.rainfallAmount = hydraulicErosionRainfallAmount; // kr
        hydraulicEroder.evaporationRatio = hydraulicErosionEvaporationRatio; // ke
        hydraulicEroder.sedimentCapacity = hydraulicErosionSedimentCapacity; // kc
        hydraulicEroder.soilSolubility = hydraulicErosionSoilSolubility; // ks
        hydraulicEroder.rainAltitude = hydraulicErosionRainAltitude;
        hydraulicEroder.rainFalloff = hydraulicErosionRainFalloff;
        hydraulicEroder.iterations = hydraulicErosionIterations;

        thermalEroder = new ThermalTerrainErosion ();
        thermalEroder.talus = this.thermalErosionTalus;
        thermalEroder.strength = this.thermalErosionStrength;
        thermalEroder.reverse = false;
        thermalEroder.iterations = this.thermalErosionIterations;

        texturer = new Texturer();
        texturer.Init();
        texturer.slopeValue = slopeValue;
        texturer.mountainPeekStart = mountainPeekStart;
        texturer.mountainPeekHeight = mountainPeekHeight;
        texturer.waterHeight = waterHeight;
        texturer.shoreHeight = shoreHeight;
        splats = new SplatPrototype[diffuses.Length];

        texturer.treeHeightFactor = treeHeightFactor;
        texturer.treeStrength = treeStrength;
        treeProto = new TreePrototype[treePrefab.Length];
        for (var i = 0; i < treePrefab.Length; i++) {
            treeProto[i] = new TreePrototype();
            treeProto[i].bendFactor = 0;
            treeProto[i].prefab = treePrefab[i];
        }

        grassPlacer = new GrassPlacement();
        grassPlacer.grassType = grassType;
        grassPlacer.texturesToAffect = texturesToAffect;

        for (var i = 0; i < diffuses.Length; i++) {
            splats[i] = new SplatPrototype();
            splats[i].texture = diffuses[i];
            splats[i].normalMap = normals[i];
            splats[i].tileSize = new Vector2(5, 5);
        }
        grassProto = new DetailPrototype[1];
        grassProto[0] = new DetailPrototype();
        grassProto[0].prototypeTexture = grass;
        grassProto[0].bendFactor = 0.1f;
        grassProto[0].dryColor = new Color(0.804f, 0.737f, 0.102f, 1.000f);
        grassProto[0].healthyColor = new Color(0.263f, 0.976f, 0.165f, 1.000f);
        grassProto[0].maxHeight = 0.5f;
        grassProto[0].minHeight = 0.2f;
        grassProto[0].maxWidth = 1f;
        grassProto[0].minWidth = 0.5f;
        grassProto[0].noiseSpread = 0.1f;
        grassProto[0].prototype = null;
        grassProto[0].renderMode = DetailRenderMode.GrassBillboard;
        grassProto[0].usePrototypeMesh = false;

        ensureChunk(new ChunkCoord(0, 0), false);
        ensureChunk(new ChunkCoord(-1, -1), true);
        ensureChunk(new ChunkCoord(0, -1), true);
        ensureChunk(new ChunkCoord(-1, 0), true);
    }