public static void UpdateLighting(int x, int y, int z) { //Debug.Log("update lighting"); //float start = Time.realtimeSinceStartup; Queue <Vector3Int> skyLightQueue = new Queue <Vector3Int>(); Vector3Int p = new Vector3Int(); // init for (int i = -15; i <= 15; i++) { for (int j = -15; j <= 15; j++) { p.Set(x + i, y, z + j); int chunkX = Mathf.FloorToInt(p.x / 16f); int chunkZ = Mathf.FloorToInt(p.z / 16f); int xInChunk = p.x - chunkX * 16; int zInChunk = p.z - chunkZ * 16; NBTChunk chunk = GetChunk(chunkX, chunkZ); for (int temp_y = chunk.Sections.Count * 16 - 1; temp_y >= 0; temp_y--) { chunk.SetSkyLightByte(xInChunk, temp_y, zInChunk, 0); } } } HashSet <Vector3Int> skyLightSet = new HashSet <Vector3Int>(); // light from sun (no vertical falloff) for (int i = -15; i <= 15; i++) { for (int j = -15; j <= 15; j++) { p.Set(x + i, y, z + j); int chunkX = Mathf.FloorToInt(p.x / 16f); int chunkZ = Mathf.FloorToInt(p.z / 16f); int xInChunk = p.x - chunkX * 16; int zInChunk = p.z - chunkZ * 16; NBTChunk chunk = GetChunk(chunkX, chunkZ); int temp_y = chunk.Sections.Count * 16 - 1; while (NBTGeneratorManager.LightCanTravel(chunk.GetBlockByte(xInChunk, temp_y, zInChunk))) { chunk.SetSkyLightByte(xInChunk, temp_y, zInChunk, 15); skyLightSet.Add(new Vector3Int(p.x, temp_y, p.z)); if (temp_y == 0) { break; } else { temp_y--; } } } } foreach (Vector3Int skyLightPos in skyLightSet) { if (skyLightSet.Contains(skyLightPos + Vector3Int.left) && skyLightSet.Contains(skyLightPos + Vector3Int.right) && skyLightSet.Contains(skyLightPos + Vector3Int.forward) && skyLightSet.Contains(skyLightPos + Vector3Int.back)) { continue; } skyLightQueue.Enqueue(new Vector3Int(skyLightPos.x, skyLightPos.y, skyLightPos.z)); } int count = 0; int setcount = 0; // light propagation (use flood fill) Vector3Int[] arr = new Vector3Int[6]; while (skyLightQueue.Count > 0) { count++; p = skyLightQueue.Dequeue(); byte skyLight = GetSkyLightByte(p.x, p.y, p.z); arr[0] = p + Vector3Int.left; arr[1] = p + Vector3Int.right; arr[2] = p + Vector3Int.up; arr[3] = p + Vector3Int.down; arr[4] = p + Vector3Int.forward; arr[5] = p + Vector3Int.back; for (int i = 0; i < 6; i++) { Vector3Int nextPos = arr[i]; if (NBTGeneratorManager.IsTransparent(GetBlockByte(nextPos.x, nextPos.y, nextPos.z))) { byte nextSkyLight = GetSkyLightByte(nextPos.x, nextPos.y, nextPos.z); if (nextSkyLight < skyLight - 1) { setcount++; //Debug.Log("SetSkyLightByte,nextPos=" + nextPos.x + "," + nextPos.y + "," + nextPos.z); SetSkyLightByte(nextPos.x, nextPos.y, nextPos.z, (byte)(skyLight - 1)); if (skyLight > 2) { skyLightQueue.Enqueue(nextPos); } } } } } //float end = Time.realtimeSinceStartup; //Debug.Log("time cost =" + (end - start) + ", actual propagation count=" + count + ",setcount=" + setcount); }