Ejemplo n.º 1
0
        public Vector4 SampleNoise(Vector2 xzPosition, AsyncTextureUnsafe <Color32> source, float strength, NoiseType type)
        {
            Vector4 normalizedNoise = RawTextureSampler.SampleBilinear(
                xzPosition.x * RenderConfig.NoiseScale,
                xzPosition.y * RenderConfig.NoiseScale,
                source
                );

            if (type == NoiseType.NegativeOneToOne)
            {
                normalizedNoise.Set(
                    normalizedNoise.x * 2f - 1f,
                    normalizedNoise.y * 2f - 1f,
                    normalizedNoise.z * 2f - 1f,
                    normalizedNoise.w * 2f - 1f
                    );
            }

            return(normalizedNoise * strength);
        }
Ejemplo n.º 2
0
        private IEnumerator RefreshHeightmap(ChunkOrientationData chunkOrientation)
        {
            var terrainData = Terrain.terrainData;

            var unsafeOrientationTexture = new AsyncTextureUnsafe <Color32>(chunkOrientation.OrientationTexture);
            var unsafeWeightsTexture     = new AsyncTextureUnsafe <Color32>(chunkOrientation.WeightsTexture);
            var unsafeDuckTexture        = new AsyncTextureUnsafe <Color32>(chunkOrientation.DuckTexture);

            var unsafeFlatlandsNoise = new AsyncTextureUnsafe <Color32>(RenderConfig.FlatlandsElevationNoiseSource);
            var unsafeHillsNoise     = new AsyncTextureUnsafe <Color32>(RenderConfig.HillsElevationNoiseSource);

            Vector3 terrainSize = terrainData.size;

            int mapWidth  = terrainData.heightmapWidth;
            int mapHeight = terrainData.heightmapHeight;

            float[,] heights = terrainData.GetHeights(0, 0, mapWidth, mapHeight);

            float maxTextureNormalX = Width / RenderConfig.ChunkWidth;
            float maxTextureNormalZ = Height / RenderConfig.ChunkHeight;

            float indexToNormalX = 1f / (mapHeight - 1f);
            float indexToNormalZ = 1f / (mapWidth - 1f);

            Vector3 chunkPosition = transform.position;

            var columnTasks = new Task[mapHeight];

            for (int height = 0; height < mapHeight; height++)
            {
                int cachedHeight = height;

                var indexBytes = new byte[2];

                PointOrientationData pointOrientation = new PointOrientationData();

                var columnTask = new Task(() => {
                    for (int width = 0; width < mapWidth; width++)
                    {
                        float terrainNormalX, terrainNormalZ, textureNormalX, textureNormalZ, worldX, worldZ;

                        Color32 orientationColor;
                        Color weightsColor, duckColor;

                        //For some reason, terrainData seems to index its points
                        //as (y, x) rather than the more traditional (x, y), so
                        //we need to sample our texture accordingly
                        terrainNormalX = cachedHeight * indexToNormalX;
                        terrainNormalZ = width * indexToNormalZ;

                        worldX = chunkPosition.x + terrainNormalX * terrainSize.x;
                        worldZ = chunkPosition.z + terrainNormalZ * terrainSize.z;

                        textureNormalX = maxTextureNormalX * terrainNormalX;
                        textureNormalZ = maxTextureNormalZ * terrainNormalZ;

                        orientationColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeOrientationTexture));
                        weightsColor     = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeWeightsTexture));
                        duckColor        = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeDuckTexture));

                        PointOrientationLogic.GetOrientationDataFromColors(
                            pointOrientation, indexBytes, orientationColor, weightsColor, duckColor
                            );

                        heights[width, cachedHeight] = HeightLogic.GetHeightForPoint(
                            new Vector2(worldX, worldZ), pointOrientation, unsafeFlatlandsNoise, unsafeHillsNoise
                            );
                    }
                });

                columnTask.Start();

                columnTasks[cachedHeight] = columnTask;
            }

            while (columnTasks.Any(task => !task.IsCompleted))
            {
                yield return(SkipFrame);
            }

            terrainData.SetHeights(0, 0, heights);
        }
Ejemplo n.º 3
0
        private IEnumerator RefreshAlphamap(ChunkOrientationData orientationData)
        {
            var terrainData = Terrain.terrainData;

            var unsafeOrientationTexture = new AsyncTextureUnsafe <Color32>(orientationData.OrientationTexture);
            var unsafeWeightsTexture     = new AsyncTextureUnsafe <Color32>(orientationData.WeightsTexture);
            var unsafeDuckTexture        = new AsyncTextureUnsafe <Color32>(orientationData.DuckTexture);

            Vector3 terrainSize = terrainData.size;

            int mapWidth  = terrainData.alphamapWidth;
            int mapHeight = terrainData.alphamapHeight;

            int alphamapLength = RenderConfig.MapTextures.Count();

            float[,,] alphaMaps = terrainData.GetAlphamaps(0, 0, mapWidth, mapHeight);

            float maxTextureNormalX = Width / RenderConfig.ChunkWidth;
            float maxTextureNormalZ = Height / RenderConfig.ChunkHeight;

            float indexToNormalX = 1f / (mapHeight - 1f);
            float indexToNormalZ = 1f / (mapWidth - 1f);

            Vector3 chunkPosition = transform.position;

            var columnTasks = new Task[mapHeight];

            for (int height = 0; height < mapHeight; height++)
            {
                int cachedHeight = height;

                var indexBytes = new byte[2];

                PointOrientationData pointOrientation = new PointOrientationData();

                float[] returnMap       = new float[RenderConfig.MapTextures.Count()];
                float[] intermediateMap = new float[RenderConfig.MapTextures.Count()];

                var columnTask = new Task(() => {
                    for (int width = 0; width < mapWidth; width++)
                    {
                        float terrainNormalX, terrainNormalZ, textureNormalX, textureNormalZ, worldX, worldZ;

                        Color32 orientationColor;
                        Color weightsColor, duckColor;

                        //For some reason, terrainData seems to index its points
                        //as (y, x) rather than the more traditional (x, y), so
                        //we need to sample our texture accordingly
                        terrainNormalX = cachedHeight * indexToNormalX;
                        terrainNormalZ = width * indexToNormalZ;

                        worldX = chunkPosition.x + terrainNormalX * terrainSize.x;
                        worldZ = chunkPosition.z + terrainNormalZ * terrainSize.z;

                        textureNormalX = maxTextureNormalX * terrainNormalX;
                        textureNormalZ = maxTextureNormalZ * terrainNormalZ;

                        orientationColor = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeOrientationTexture));
                        weightsColor     = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeWeightsTexture));
                        duckColor        = ColorCorrection.ARGB_To_RGBA(RawTextureSampler.SamplePoint(textureNormalX, textureNormalZ, unsafeDuckTexture));

                        PointOrientationLogic.GetOrientationDataFromColors(
                            pointOrientation, indexBytes, orientationColor, weightsColor, duckColor
                            );

                        AlphamapLogic.GetAlphamapFromOrientation(returnMap, intermediateMap, pointOrientation);

                        for (int alphaIndex = 0; alphaIndex < alphamapLength; alphaIndex++)
                        {
                            alphaMaps[width, cachedHeight, alphaIndex] = returnMap[alphaIndex];
                        }
                    }
                });

                columnTask.Start();

                columnTasks[cachedHeight] = columnTask;
            }

            while (columnTasks.Any(task => !task.IsCompleted))
            {
                yield return(SkipFrame);
            }

            terrainData.SetAlphamaps(0, 0, alphaMaps);
        }