void RenderTerrain(TerrainData terrain) { int w = m_size.Width; int h = m_size.Height; TileData[,,] tileGrid; byte[,] levelMap; terrain.GetData(out tileGrid, out levelMap); int min = levelMap.Min(); int max = levelMap.Max(); m_sliceBmpXY.Lock(); unsafe { var pBackBuffer = (uint*)m_sliceBmpXY.BackBuffer; int stride = m_sliceBmpXY.BackBufferStride / 4; Parallel.For(0, h, y => { for (int x = 0; x < w; ++x) { int z = terrain.GetSurfaceLevel(x, y); TileData td; while (true) { var p = new IntVector3(x, y, z); td = terrain.GetTileData(p); if (td.IsEmptyNoWater) { z--; continue; } if (this.ShowWaterEnabled && td.WaterLevel > 0) { var wl = terrain.GetWaterLevel(p + Direction.Up); if (wl > 0) { z++; continue; } } break; } int m = MyMath.Round(MyMath.LinearInterpolation(min, max, 100, 255, z)); var cv = GetTileColor(td); int r = cv.X; int g = cv.Y; int b = cv.Z; r = r * m / 255; g = g * m / 255; b = b * m / 255; var ptr = pBackBuffer + y * stride + x; *ptr = (uint)((r << 16) | (g << 8) | (b << 0)); } }); } m_sliceBmpXY.AddDirtyRect(new Int32Rect(0, 0, m_sliceBmpXY.PixelWidth, m_sliceBmpXY.PixelHeight)); m_sliceBmpXY.Unlock(); }