/// <summary> /// Calculates how much ground should go in sediment flow aka force-based erosion /// Transfers m_terrainField to m_sedimentField basing on /// m_waterVelocity, m_sedimentCapacity, m_dissolvingConstant, /// m_depositionConstant, m_tiltAngle, m_minTiltAngle /// Also calculates m_tiltAngle /// </summary> private void DissolveAndDeposition(DoubleDataTexture terrainField, Vector4 dissolvingConstant, float minTiltAngle, int TERRAIN_LAYERS) { link.m_tiltAngleMat.SetFloat("_TexSize", size); link.m_tiltAngleMat.SetFloat("_Layers", TERRAIN_LAYERS); link.m_tiltAngleMat.SetTexture("_TerrainField", terrainField.READ); Graphics.Blit(null, tiltAngle, link.m_tiltAngleMat); link.dissolutionAndDepositionMat.SetTexture("_TerrainField", terrainField.READ); link.dissolutionAndDepositionMat.SetTexture("_SedimentField", sedimentField.READ); link.dissolutionAndDepositionMat.SetTexture("_VelocityField", velocity.READ); link.dissolutionAndDepositionMat.SetTexture("_WaterField", main.READ); link.dissolutionAndDepositionMat.SetTexture("_TiltAngle", tiltAngle); link.dissolutionAndDepositionMat.SetFloat("_MinTiltAngle", minTiltAngle); link.dissolutionAndDepositionMat.SetFloat("_SedimentCapacity", sedimentCapacity); link.dissolutionAndDepositionMat.SetVector("_DissolvingConstant", dissolvingConstant); link.dissolutionAndDepositionMat.SetFloat("_DepositionConstant", depositionConstant); link.dissolutionAndDepositionMat.SetFloat("_Layers", (float)TERRAIN_LAYERS); link.dissolutionAndDepositionMat.SetFloat("_DissolveLimit", dissolveLimit); //nash added it RenderTexture[] terrainAndSediment = new RenderTexture[3] { terrainField.WRITE, sedimentField.WRITE, sedimentDeposition.WRITE }; RTUtility.MultiTargetBlit(terrainAndSediment, link.dissolutionAndDepositionMat); terrainField.Swap(); sedimentField.Swap(); sedimentDeposition.Swap(); }
/// <summary> /// Transfers ground to regolith basing on water level, regolith level, max_regolith /// aka dissolution based erosion /// </summary> private void DisintegrateAndDeposit() { m_disintegrateAndDepositMat.SetFloat("_Layers", (float)TERRAIN_LAYERS); m_disintegrateAndDepositMat.SetTexture("_TerrainField", terrainField.READ); m_disintegrateAndDepositMat.SetTexture("_WaterField", water.main.READ); m_disintegrateAndDepositMat.SetTexture("_RegolithField", regolithField.READ); m_disintegrateAndDepositMat.SetFloat("_MaxRegolith", maxRegolith); RenderTexture[] terrainAndRegolith = new RenderTexture[2] { terrainField.WRITE, regolithField.WRITE }; RTUtility.MultiTargetBlit(terrainAndRegolith, m_disintegrateAndDepositMat); terrainField.Swap(); regolithField.Swap(); }
/// <summary> /// Calculates flow of field /// </summary> public void Flow(RenderTexture onWhat) { //main.SetFilterMode(FilterMode.Point); link.m_outFlowMat.SetFloat("_TexSize", (float)ErosionSim.TEX_SIZE); link.m_outFlowMat.SetFloat("T", link.timeStep); link.m_outFlowMat.SetFloat("L", link.PIPE_LENGTH); link.m_outFlowMat.SetFloat("A", link.CELL_AREA); link.m_outFlowMat.SetFloat("G", ErosionSim.GRAVITY); link.m_outFlowMat.SetFloat("_Layers", 4); link.m_outFlowMat.SetFloat("_Damping", damping); link.m_outFlowMat.SetTexture("_TerrainField", onWhat); link.m_outFlowMat.SetTexture("_Field", main.READ); link.m_outFlowMat.SetFloat("_OverwriteFluidity", overwriteFluidity); link.m_outFlowMat.SetFloat("_Fluidity", fluidity); Graphics.Blit(outFlow.READ, outFlow.WRITE, link.m_outFlowMat); outFlow.Swap();; link.m_fieldUpdateMat.SetFloat("_TexSize", size); link.m_fieldUpdateMat.SetFloat("T", link.timeStep); link.m_fieldUpdateMat.SetFloat("L", 1f); link.m_fieldUpdateMat.SetTexture("_OutFlowField", outFlow.READ); Graphics.Blit(main.READ, main.WRITE, link.m_fieldUpdateMat); main.Swap(); //main.SetFilterMode(FilterMode.Bilinear); }
/// <summary> /// Calculates water velocity /// </summary> public void CalcWaterVelocity(float TIME_STEP) { link.m_waterVelocityMat.SetFloat("_TexSize", size); link.m_waterVelocityMat.SetFloat("L", 1f); link.m_waterVelocityMat.SetTexture("_WaterField", main.READ); link.m_waterVelocityMat.SetTexture("_WaterFieldOld", main.WRITE); link.m_waterVelocityMat.SetTexture("_OutFlowField", outFlow.READ); Graphics.Blit(null, velocity.READ, link.m_waterVelocityMat); const float viscosity = 10.5f; const int iterations = 2; link.m_diffuseVelocityMat.SetFloat("_TexSize", size); link.m_diffuseVelocityMat.SetFloat("_Alpha", 1f / (viscosity * TIME_STEP));// CELL_AREA == 1f for (int i = 0; i < iterations; i++) { Graphics.Blit(velocity.READ, velocity.WRITE, link.m_diffuseVelocityMat); velocity.Swap(); } }
private void InitMaps() { terrainField.ClearColor(); //waterOutFlow.ClearColor(); //waterVelocity.ClearColor(); //advectSediment.ClearColor(); //waterField.ClearColor(); //sedimentField.ClearColor(); regolithField.ClearColor(); regolithOutFlow.ClearColor(); //sedimentDeposition.ClearColor(); magmaVelocity.ClearColor(); DoubleDataTexture noiseTex; noiseTex = new DoubleDataTexture("", TEX_SIZE, RenderTextureFormat.RFloat, FilterMode.Bilinear); GPUPerlinNoise perlin = new GPUPerlinNoise(m_seed); perlin.LoadResourcesFor2DNoise(); m_noiseMat.SetTexture("_PermTable1D", perlin.PermutationTable1D); m_noiseMat.SetTexture("_Gradient2D", perlin.Gradient2D); for (int j = 0; j < TERRAIN_LAYERS; j++) { m_noiseMat.SetFloat("_Offset", m_offset[j]); float amp = 0.5f; float freq = m_frequency[j]; //Must clear noise from last pass noiseTex.ClearColor(); //write noise into texture with the settings for this layer for (int i = 0; i < m_octaves[j]; i++) { m_noiseMat.SetFloat("_Frequency", freq); m_noiseMat.SetFloat("_Amp", amp); m_noiseMat.SetFloat("_Pass", (float)i); Graphics.Blit(noiseTex.READ, noiseTex.WRITE, m_noiseMat, (int)m_layerStyle[j]); noiseTex.Swap(); freq *= m_lacunarity[j]; amp *= m_gain[j]; } float useAbs = 0.0f; if (m_finalNosieIsAbs[j]) { useAbs = 1.0f; } //Mask the layers that we dont want to write into Vector4 mask = new Vector4(0.0f, 0.0f, 0.0f, 0.0f); mask[j] = 1.0f; m_initTerrainMat.SetFloat("_Amp", m_amp[j]); m_initTerrainMat.SetFloat("_UseAbs", useAbs); m_initTerrainMat.SetVector("_Mask", mask); m_initTerrainMat.SetTexture("_NoiseTex", noiseTex.READ); m_initTerrainMat.SetFloat("_Height", TERRAIN_HEIGHT); //Apply the noise for this layer to the terrain field Graphics.Blit(terrainField.READ, terrainField.WRITE, m_initTerrainMat); terrainField.Swap(); } //dont need this tex anymore noiseTex.Destroy(); }