#if GRIFFIN using UnityEngine; using System.Collections; using System.Collections.Generic; using System; namespace Pinwheel.Griffin.ErosionTool { public class GHydraulicEroder : IDisposable { public GErosionSimulator Simulator { get; private set; } public float WaterSourceAmount { get; set; } public float RainRate { get; set; } public float FlowRate { get; set; } public float ErosionRate { get; set; } public float DepositionRate { get; set; } public float EvaporationRate { get; set; } public Vector3 Bounds { get; set; } private RenderTexture outflowVHData; private RenderTexture outflowDiagData; private RenderTexture velocityData; private static readonly int EROSION_MAP = Shader.PropertyToID("_ErosionMap"); private static readonly int MASK_MAP = Shader.PropertyToID("_MaskMap"); private static readonly int MASK_MAP_RESOLUTION = Shader.PropertyToID("_MaskMapResolution"); private static readonly int WATER_SOURCE_AMOUNT = Shader.PropertyToID("_WaterSourceAmount"); private static readonly int RAIN_RATE = Shader.PropertyToID("_RainRate"); private static readonly int FLOW_RATE = Shader.PropertyToID("_FlowRate"); private static readonly int EROSION_RATE = Shader.PropertyToID("_ErosionRate"); private static readonly int DEPOSITION_RATE = Shader.PropertyToID("_DepositionRate"); private static readonly int EVAPORATION_RATE = Shader.PropertyToID("_EvaporationRate"); private static readonly int BOUNDS = Shader.PropertyToID("_Bounds"); private static readonly int SIMULATION_DATA = Shader.PropertyToID("_SimulationData"); private static readonly int OUTFLOW_VH_DATA = Shader.PropertyToID("_OutflowVHData"); private static readonly int OUTFLOW_DIAG_DATA = Shader.PropertyToID("_OutflowDiagData"); private static readonly int VELOCITY_DATA = Shader.PropertyToID("_VelocityData"); private static readonly int RANDOM_SEED = Shader.PropertyToID("_RandomSeed"); private static readonly int KERNEL_INDEX = 0; private bool initialized; public GHydraulicEroder(GErosionSimulator s) { Simulator = s; } public void Init() { int width = Simulator.SimulationData.width; int height = Simulator.SimulationData.height; outflowVHData = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); outflowVHData.enableRandomWrite = true; outflowVHData.wrapMode = TextureWrapMode.Clamp; outflowVHData.Create(); outflowDiagData = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear); outflowDiagData.enableRandomWrite = true; outflowDiagData.wrapMode = TextureWrapMode.Clamp; outflowDiagData.Create(); velocityData = new RenderTexture(width, height, 0, RenderTextureFormat.RGFloat, RenderTextureReadWrite.Linear); velocityData.enableRandomWrite = true; velocityData.wrapMode = TextureWrapMode.Clamp; velocityData.Create(); initialized = true; } public void Simulate() { if (!initialized) { throw new System.Exception("POLARIS: Eroder not initialized. Call Init() before running the simulation."); } ComputeShader shader = GRuntimeSettings.Instance.internalShaders.hydraulicErosionShader; shader.SetTexture(KERNEL_INDEX, SIMULATION_DATA, Simulator.SimulationData); shader.SetTexture(KERNEL_INDEX, EROSION_MAP, Simulator.ErosionMap); shader.SetTexture(KERNEL_INDEX, OUTFLOW_VH_DATA, outflowVHData); shader.SetTexture(KERNEL_INDEX, OUTFLOW_DIAG_DATA, outflowDiagData); shader.SetTexture(KERNEL_INDEX, VELOCITY_DATA, velocityData); shader.SetTexture(KERNEL_INDEX, MASK_MAP, Simulator.SimulationMask); shader.SetVector(MASK_MAP_RESOLUTION, new Vector4(Simulator.SimulationMask.width, Simulator.SimulationMask.height, 0, 0)); shader.SetVector(BOUNDS, Simulator.Bounds); shader.SetVector(RANDOM_SEED, UnityEngine.Random.insideUnitCircle); shader.SetFloat(WATER_SOURCE_AMOUNT, WaterSourceAmount); shader.SetFloat(RAIN_RATE, RainRate); shader.SetFloat(FLOW_RATE, FlowRate); shader.SetFloat(EROSION_RATE, ErosionRate); shader.SetFloat(DEPOSITION_RATE, DepositionRate); shader.SetFloat(EVAPORATION_RATE, EvaporationRate); int dimX = (int)Simulator.Bounds.x; int dimZ = (int)Simulator.Bounds.z; int threadGroupX = (dimX + 7) / 8; int threadGroupY = 1; int threadGroupZ = (dimZ + 7) / 8; shader.Dispatch(KERNEL_INDEX, threadGroupX, threadGroupY, threadGroupZ); } public void Dispose() { if (outflowVHData != null) { outflowVHData.Release(); outflowVHData = null; } if (outflowDiagData != null) { outflowDiagData.Release(); outflowDiagData = null; } if (velocityData != null) { velocityData.Release(); velocityData = null; } initialized = false; } } } #endif