Exemplo n.º 1
0
        public override void DoCreateTile(int level, int tx, int ty, List <TileStorage.Slot> slot)
        {
            var levelLength = level + DeltaLevel - RootLevel;

            if (!(levelLength >= 0 && (tx >> levelLength) == RootTx && (ty >> levelLength) == RootTy))
            {
                return;
            }

            level = levelLength;
            tx    = tx - (RootTx << level);
            ty    = ty - (RootTy << level);

            CPUTileStorage.CPUSlot <float> cpuSlot = slot[0] as CPUTileStorage.CPUSlot <float>;

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

            cpuSlot.ClearData();

            ReadTile(level, tx, ty, cpuSlot.Data);

            base.DoCreateTile(level, tx, ty, slot);
        }
Exemplo n.º 2
0
        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 - 4;

            GPUTileStorage.GPUSlot parentGpuSlot = null;

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

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

            if (parentGpuSlot == null && level > 0)
            {
                throw new NullReferenceException("parentGpuSlot");
            }

            UpSampleMaterial.SetFloat(uniforms.tileWidth, tileWidth);

            if (level > 0)
            {
                var tex = parentGpuSlot.Texture;

                UpSampleMaterial.SetTexture(uniforms.coarseLevelSampler, tex);

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

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

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

            if (OrthoCPUProducer != null && OrthoCPUProducer.HasTile(level, tx, ty))
            {
                var orthoCPUTile = OrthoCPUProducer.FindTile(level, tx, ty, false, true);

                CPUTileStorage.CPUSlot <byte> orthoCPUSlot = null;

                if (orthoCPUTile != null)
                {
                    orthoCPUSlot = orthoCPUTile.GetSlot(0) as CPUTileStorage.CPUSlot <byte>;
                }
                else
                {
                    throw new MissingTileException("Find orthoCPU tile failed");
                }

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

                var channels = OrthoCPUProducer.Channels;
                var color    = new Color32();
                var data     = orthoCPUSlot.Data;

                for (int x = 0; x < tileWidth; x++)
                {
                    for (int y = 0; y < tileWidth; y++)
                    {
                        color.r = data[(x + y * tileWidth) * channels];

                        if (channels > 1)
                        {
                            color.g = data[(x + y * tileWidth) * channels + 1];
                        }
                        if (channels > 2)
                        {
                            color.b = data[(x + y * tileWidth) * channels + 2];
                        }
                        if (channels > 3)
                        {
                            color.a = data[(x + y * tileWidth) * channels + 3];
                        }

                        ResidualTexture.SetPixel(x, y, color);
                    }
                }

                ResidualTexture.Apply();

                UpSampleMaterial.SetTexture(uniforms.residualSampler, ResidualTexture);
                UpSampleMaterial.SetVector(uniforms.residualOSH, new Vector4(0.5f / (float)tileWidth, 0.5f / (float)tileWidth, 1.0f / (float)tileWidth, 0.0f));
            }
            else
            {
                UpSampleMaterial.SetTexture(uniforms.residualSampler, null);
                UpSampleMaterial.SetVector(uniforms.residualOSH, new Vector4(-1, -1, -1, -1));
            }

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

            var noiseL = 0;

            if (rs != 0.0f)
            {
                if (TerrainNode.Face == 1)
                {
                    int offset  = 1 << level;
                    int bottomB = Noise.Noise2D(tx + 0.5f, ty + offset) > 0.0f ? 1 : 0;
                    int rightB  = (tx == offset - 1 ? Noise.Noise2D(ty + offset + 0.5f, offset) : Noise.Noise2D(tx + 1.0f, ty + offset + 0.5f)) > 0.0f ? 2 : 0;
                    int topB    = (ty == offset - 1 ? Noise.Noise2D((3.0f * offset - 1.0f - tx) + 0.5f, offset) : Noise.Noise2D(tx + 0.5f, ty + offset + 1.0f)) > 0.0f ? 4 : 0;
                    int leftB   = (tx == 0 ? Noise.Noise2D((4.0f * offset - 1.0f - ty) + 0.5f, offset) : Noise.Noise2D(tx, ty + offset + 0.5f)) > 0.0f ? 8 : 0;
                    noiseL = bottomB + rightB + topB + leftB;
                }
                else if (TerrainNode.Face == 6)
                {
                    int offset  = 1 << level;
                    int bottomB = (ty == 0 ? Noise.Noise2D((3.0f * offset - 1.0f - tx) + 0.5f, 0) : Noise.Noise2D(tx + 0.5f, ty - offset)) > 0.0f ? 1 : 0;
                    int rightB  = (tx == offset - 1.0f ? Noise.Noise2D((2.0f * offset - 1.0f - ty) + 0.5f, 0) : Noise.Noise2D(tx + 1.0f, ty - offset + 0.5f)) > 0.0f ? 2 : 0;
                    int topB    = Noise.Noise2D(tx + 0.5f, ty - offset + 1.0f) > 0.0f ? 4 : 0;
                    int leftB   = (tx == 0 ? Noise.Noise2D(3.0f * offset + ty + 0.5f, 0) : Noise.Noise2D(tx, ty - offset + 0.5f)) > 0.0f ? 8 : 0;
                    noiseL = bottomB + rightB + topB + leftB;
                }
                else
                {
                    int offset  = (1 << level) * (TerrainNode.Face - 2);
                    int bottomB = Noise.Noise2D(tx + offset + 0.5f, ty) > 0.0f ? 1 : 0;
                    int rightB  = Noise.Noise2D((tx + offset + 1) % (4 << level), ty + 0.5f) > 0.0f ? 2 : 0;
                    int topB    = Noise.Noise2D(tx + offset + 0.5f, ty + 1.0f) > 0.0f ? 4 : 0;
                    int leftB   = Noise.Noise2D(tx + offset, ty + 0.5f) > 0.0f ? 8 : 0;
                    noiseL = bottomB + rightB + topB + leftB;
                }
            }

            var noiseRs = new int[] { 0, 0, 1, 0, 2, 0, 1, 0, 3, 3, 1, 3, 2, 2, 1, 0 };
            var noiseR  = noiseRs[noiseL];

            var noiseLs = new int[] { 0, 1, 1, 2, 1, 3, 2, 4, 1, 2, 3, 4, 2, 4, 4, 5 };

            noiseL = noiseLs[noiseL];

            UpSampleMaterial.SetTexture(uniforms.noiseSampler, NoiseTextures[noiseL]);
            UpSampleMaterial.SetVector(uniforms.noiseUVLH, new Vector4(noiseR, (noiseR + 1) % 4, 0.0f, HSV ? 1.0f : 0.0f));

            if (HSV)
            {
                Vector4 col = NoiseColor * rs / 255.0f;
                col.w *= 2.0f;

                UpSampleMaterial.SetVector(uniforms.noiseColor, col);
            }
            else
            {
                Vector4 col = NoiseColor * rs * 2.0f / 255.0f;
                col.w *= 2.0f;

                UpSampleMaterial.SetVector(uniforms.noiseColor, col);
            }

            UpSampleMaterial.SetVector(uniforms.noiseRootColor, RootNoiseColor);

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

            base.DoCreateTile(level, tx, ty, slot);
        }
Exemplo n.º 3
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);

            // TODO : Make it classwide...
            var residualTileSize = GetTileSize(0);
            var residualTexture  = RTExtensions.CreateRTexture(residualTileSize, 0, RenderTextureFormat.RFloat, FilterMode.Point, TextureWrapMode.Clamp);
            var residualBuffer   = new ComputeBuffer(residualTileSize * residualTileSize, sizeof(float));

            if (ResidualProducer != null)
            {
                if (ResidualProducer.HasTile(level, tx, ty))
                {
                    if (ResidualProducer.IsGPUProducer)
                    {
                        GPUTileStorage.GPUSlot residualGpuSlot = null;

                        var residualTile = ResidualProducer.FindTile(level, tx, ty, false, true);

                        if (residualTile != null)
                        {
                            residualGpuSlot = residualTile.GetSlot(0) as GPUTileStorage.GPUSlot;
                        }
                        else
                        {
                            throw new MissingTileException("Find residual tile failed");
                        }

                        if (residualGpuSlot == null)
                        {
                            throw new MissingTileException("Find parent tile failed");
                        }

                        UpSampleMaterial.SetTexture("_ResidualSampler", residualGpuSlot.Texture);
                        UpSampleMaterial.SetVector("_ResidualOSH", new Vector4(0.25f / (float)tileWidth, 0.25f / (float)tileWidth, 2.0f / (float)tileWidth, 1.0f));
                    }
                    else
                    {
                        CPUTileStorage.CPUSlot <float> residualCPUSlot = null;

                        var residualTile = ResidualProducer.FindTile(level, tx, ty, false, true);

                        if (residualTile != null)
                        {
                            residualCPUSlot = residualTile.GetSlot(0) as CPUTileStorage.CPUSlot <float>;
                        }
                        else
                        {
                            throw new MissingTileException("Find residual tile failed");
                        }

                        if (residualCPUSlot == null)
                        {
                            throw new MissingTileException("Find parent tile failed");
                        }

                        residualBuffer.SetData(residualCPUSlot.Data);

                        RTUtility.ClearColor(residualTexture);
                        CBUtility.WriteIntoRenderTexture(residualTexture, CBUtility.Channels.R, residualBuffer, GodManager.Instance.WriteData);
                        //RTUtility.SaveAs8bit(residualTileSize, residualTileSize, CBUtility.Channels.R, string.Format("Residual_{0}_{1}-{2}-{3}", TerrainNode.name, level, tx, ty), "/Resources/Preprocess/Textures/Debug/", residualCPUSlot.Data);

                        UpSampleMaterial.SetTexture("_ResidualSampler", residualTexture);
                        UpSampleMaterial.SetVector("_ResidualOSH", new Vector4(0.25f / (float)tileWidth, 0.25f / (float)tileWidth, 2.0f / (float)tileWidth, 1.0f));
                    }
                }
                else
                {
                    UpSampleMaterial.SetTexture("_ResidualSampler", null);
                    UpSampleMaterial.SetVector("_ResidualOSH", new Vector4(0.0f, 0.0f, 1.0f, 0.0f));
                }
            }
            else
            {
                UpSampleMaterial.SetTexture("_ResidualSampler", null);
                UpSampleMaterial.SetVector("_ResidualOSH", new Vector4(0.0f, 0.0f, 1.0f, 0.0f));
            }

            if (upsample)
            {
                if (parentTile != null)
                {
                    parentGpuSlot = parentTile.GetSlot(0) as GPUTileStorage.GPUSlot;
                }
                else
                {
                    throw new MissingTileException(string.Format("Find parent tile failed! {0}:{1}-{2}", level - 1, tx / 2, ty / 2));
                }
            }

            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.ParentBody.GridResolution - 1);
            tileWSD.w = 0.0f;

            var tileScreenSize = (0.5 + (float)GetBorder()) / (tileWSD.x - 1 - (float)GetBorder() * 2);
            var tileSD         = new Vector2d(tileScreenSize, 1.0 + tileScreenSize * 2.0);

            UpSampleMaterial.SetVector("_TileWSD", tileWSD);
            UpSampleMaterial.SetVector("_TileSD", tileSD.ToVector2());

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

                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.SetTexture("_CoarseLevelSampler", parentTexture);
                UpSampleMaterial.SetVector("_CoarseLevelOSL", coarseLevelOSL);
            }
            else
            {
                UpSampleMaterial.SetTexture("_CoarseLevelSampler", null);
                UpSampleMaterial.SetVector("_CoarseLevelOSL", new Vector4(-1.0f, -1.0f, -1.0f, -1.0f));
            }

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

            var offset = new Vector4d(((double)tx / (1 << level) - 0.5) * rootQuadSize,
                                      ((double)ty / (1 << level) - 0.5) * rootQuadSize,
                                      rootQuadSize / (1 << level),
                                      TerrainNode.ParentBody.Size);

            UpSampleMaterial.SetFloat("_Amplitude", rs / (TerrainNode.ParentBody.Amplitude / 10.0f));
            UpSampleMaterial.SetFloat("_Frequency", TerrainNode.ParentBody.Frequency * (1 << level));
            UpSampleMaterial.SetVector("_Offset", offset.ToVector4());
            UpSampleMaterial.SetMatrix("_LocalToWorld", TerrainNode.FaceToLocal.ToMatrix4x4());

            if (TerrainNode.ParentBody.TCCPS != null)
            {
                TerrainNode.ParentBody.TCCPS.SetUniforms(UpSampleMaterial);
            }

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

            residualTexture.ReleaseAndDestroy();
            residualBuffer.ReleaseAndDisposeBuffer();

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