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); }
/// <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); }