public override void DoCreateTile(int level, int tx, int ty, List <TileStorage.Slot> slot)
        {
            var gpuSlot = slot[0] as GPUTileStorage.GPUSlot;

            if (gpuSlot == null)
            {
                throw new NullReferenceException("gpuSlot");
            }

            var tileWidth = gpuSlot.Owner.TileSize;
            var tileSize  = tileWidth - (1 + GetBorder() * 2);

            //var parentTile = FindTile(level - 1, tx / 2, ty / 2, false, true);
            var rootQuadSize = TerrainNode.TerrainQuadRoot.Length;

            var offset = Vector4d.Zero();

            offset.x = ((double)tx / (1 << level) - 0.5) * rootQuadSize;
            offset.y = ((double)ty / (1 << level) - 0.5) * rootQuadSize;
            offset.z = rootQuadSize / (1 << level);
            offset.w = TerrainNode.Body.Radius;

            ElevationMaterial.SetFloat("_TileSize", tileSize);
            ElevationMaterial.SetFloat("_Amplitude", 32.0f);
            ElevationMaterial.SetFloat("_Frequency", 128.0f);
            ElevationMaterial.SetVector("_Offset", offset.ToVector4());
            ElevationMaterial.SetMatrix("_LocalToWorld", TerrainNode.FaceToLocal.ToMatrix4x4());

            if (TerrainNode.Body.NPS != null)
            {
                TerrainNode.Body.NPS.SetUniforms(ElevationMaterial);
            }
            if (TerrainNode.Body.TCCPS != null)
            {
                TerrainNode.Body.TCCPS.UpdateUniforms(ElevationMaterial);
            }

            Graphics.Blit(null, gpuSlot.Texture, ElevationMaterial);

            base.DoCreateTile(level, tx, ty, slot);
        }
Beispiel #2
0
        /// <summary>
        /// This function creates the elevations data and is called by the <see cref="Tile.Tasks.CreateTileTask"/> when the task is run by the <see cref="Utilities.Schedular"/>.
        /// The functions needs the tiles parent data to have already been created. If it has not the program will abort.
        /// </summary>
        /// <param name="level"></param>
        /// <param name="tx"></param>
        /// <param name="ty"></param>
        /// <param name="slot"></param>
        public override void DoCreateTile(int level, int tx, int ty, List <TileStorage.Slot> slot)
        {
            var gpuSlot = slot[0] as GPUTileStorage.GPUSlot;

            if (gpuSlot == null)
            {
                throw new NullReferenceException("gpuSlot");
            }

            var tileWidth = gpuSlot.Owner.TileSize;
            var tileSize  = tileWidth - (1 + GetBorder() * 2);

            GPUTileStorage.GPUSlot parentGpuSlot = null;

            var upsample   = level > 0;
            var parentTile = FindTile(level - 1, tx / 2, ty / 2, false, true);

            if (upsample)
            {
                if (parentTile != null)
                {
                    parentGpuSlot = parentTile.GetSlot(0) as GPUTileStorage.GPUSlot;
                }
                else
                {
                    throw new MissingTileException("Find parent tile failed");
                }
            }

            if (parentGpuSlot == null && upsample)
            {
                throw new NullReferenceException("parentGpuSlot");
            }

            var rootQuadSize = TerrainNode.TerrainQuadRoot.Length;

            var tileWSD = Vector4.zero;

            tileWSD.x = (float)tileWidth;
            tileWSD.y = (float)rootQuadSize / (float)(1 << level) / (float)tileSize;
            tileWSD.z = (float)tileSize / (float)(TerrainNode.Body.GridResolution - 1);
            tileWSD.w = 0.0f;

            UpSampleMaterial.SetVector(uniforms.tileWSD, tileWSD);

            if (upsample)
            {
                var parentTexture = parentGpuSlot.Texture;

                UpSampleMaterial.SetTexture(uniforms.coarseLevelSampler, parentTexture);

                var dx = (float)(tx % 2) * (float)(tileSize / 2.0f);
                var dy = (float)(ty % 2) * (float)(tileSize / 2.0f);

                var coarseLevelOSL = new Vector4(dx / (float)parentTexture.width, dy / (float)parentTexture.height, 1.0f / (float)parentTexture.width, 0.0f);

                UpSampleMaterial.SetVector(uniforms.coarseLevelOSL, coarseLevelOSL);
            }
            else
            {
                UpSampleMaterial.SetVector(uniforms.coarseLevelOSL, new Vector4(-1.0f, -1.0f, -1.0f, -1.0f));
            }

            UpSampleMaterial.SetTexture(uniforms.residualSampler, null);
            UpSampleMaterial.SetVector(uniforms.residualOSH, new Vector4(0.0f, 0.0f, 1.0f, 0.0f));

            var rs = level < NoiseAmplitudes.Length ? NoiseAmplitudes[level] : 0.0f;

            rs = rs / AmplitudeDiviner;
            rs = -Math.Abs(rs);

            var offset = Vector4d.Zero();

            offset.x = ((double)tx / (1 << level) - 0.5) * rootQuadSize;
            offset.y = ((double)ty / (1 << level) - 0.5) * rootQuadSize;
            offset.z = rootQuadSize / (1 << level);
            offset.w = TerrainNode.Body.Radius;

            if (level == 0)
            {
                UpSampleMaterial.SetFloat(uniforms.frequency, UpsampleSettings.Freqeuncy * (1 << level));
            }

            var ltow = TerrainNode.FaceToLocal.ToMatrix4x4();

            UpSampleMaterial.SetFloat(uniforms.amp, rs * UpsampleSettings.Amplitude);
            UpSampleMaterial.SetVector(uniforms.offset, offset.ToVector4());
            UpSampleMaterial.SetMatrix(uniforms.localToWorld, ltow);

            Graphics.Blit(null, gpuSlot.Texture, UpSampleMaterial);

            base.DoCreateTile(level, tx, ty, slot);
        }