Exemplo n.º 1
0
        public void Build()
        {
            UpdateMaterial();


            _loadingCircle = TerrainUtilities.GenerateLoadingCircle(loadRadius);
            if (_tileBuffer != null)
            {
                foreach (var tile in _tileBuffer)
                {
                    Destroy(tile.Value.gameObject);
                }
            }

            _tileBuffer      = new Dictionary <IntegerCoordinate2D, TerrainTile>();
            _unusedTileQueue = new Queue <IntegerCoordinate2D>();
            _lastCenterX     = int.MaxValue;
            _lastCenterY     = int.MaxValue;
        }
        public static IEnumerator GetChunkData(IntegerCoordinate2D coordinate2D, TerrainController controller,
                                               TerrainTile tile)
        {
            //Working = true;
            var settings = controller.terrainGeneratorSettings;
            var shader   = settings.terrainComputeShader;
            //Debug.Log("Starting GPU Compute "+Time.frameCount);
            var dataSize = settings.size + 2;
            var kernel1  = settings.terrainComputeShader.FindKernel("TerrainGeneratorPass1");
            var kernel2  = settings.terrainComputeShader.FindKernel("TerrainGeneratorPass2");

            if (_inputData == null || _inputData.Length != dataSize * dataSize)
            {
                _inputData  = new TerrainTileVertexData[dataSize * dataSize];
                _dataBuffer =
                    new ComputeBuffer(_inputData.Length, 24); //2 * Vector3 = 2 * (3 * float) = 2 * (3 * 4) = 24
                _dataBuffer.SetData(_inputData);
                shader.SetInt("_size", dataSize);
                TerrainUtilities.TransferTerrainGeneratorSettingsToComputeShader(shader, settings);
                shader.SetBuffer(kernel1, "_Data", _dataBuffer);
                shader.SetBuffer(kernel2, "_Data", _dataBuffer);
                shader.SetFloat("_BlendExponent", controller.blendExponent);
                shader.SetFloat("_BlendOffset", controller.blendOffset);
                shader.SetVectorArray("_maxTessellationStrengths",
                                      controller.materialData.GetMaxTessellationStrengthArray());
            }

            //Debug.Log("StartX: "+coordinate2D.x * (settings.size - 1));
            settings.terrainComputeShader.SetInt("_startX", coordinate2D.x * (settings.size - 1));
            settings.terrainComputeShader.SetInt("_startY", coordinate2D.y * (settings.size - 1));


            //Init splat RenderTexture
            var splatTexture = new RenderTexture(dataSize, dataSize, 0)
            {
                enableRandomWrite = true, useMipMap = true, filterMode = FilterMode.Bilinear
            };

            splatTexture.Create();

            settings.terrainComputeShader.SetTexture(kernel2, "_splatTexture", splatTexture);

            /*if (tile.data.tessellationTexture != null)
             * {
             *  Object.Destroy(tile.data.tessellationTexture);
             * }*/

            //Init tessellation Texture
            var tessellationTexture = new RenderTexture(dataSize, dataSize, 0)
            {
                enableRandomWrite = true, useMipMap = true, filterMode = FilterMode.Point
            };

            tessellationTexture.Create();

            settings.terrainComputeShader.SetTexture(kernel2, "_tessellationTexture", tessellationTexture);

            settings.terrainComputeShader.Dispatch(kernel1, dataSize * dataSize / 8, 1, 1);
            settings.terrainComputeShader.Dispatch(kernel2, dataSize * dataSize / 8, 1, 1);

            var request = AsyncGPUReadback.Request(_dataBuffer);

            yield return(new WaitUntil(() => request.done));

            _inputData = request.GetData <TerrainTileVertexData>().ToArray();
            //Combine all data into output struct
            tile.data = new TerrainTileData
            {
                locationData = _inputData//, splatTexture = splatTexture, tessellationTexture = tessellationTexture
            };
            yield return(null);
        }