4ff395c862
Finished the NPC Creator tool
491 lines
23 KiB
C#
491 lines
23 KiB
C#
using UnityEngine;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using UnityEngine.TerrainTools;
|
|
|
|
namespace UnityEditor.TerrainTools.Erosion
|
|
{
|
|
[Serializable]
|
|
internal class HydraulicEroder : ITerrainEroder
|
|
{
|
|
|
|
[SerializeField]
|
|
public HydraulicErosionSettings m_ErosionSettings = new HydraulicErosionSettings();
|
|
|
|
//we need to ping-pong these
|
|
[NonSerialized]
|
|
private RTHandle[] m_HeightmapRT = { null, null };
|
|
[NonSerialized]
|
|
private RTHandle[] m_WaterRT = { null, null };
|
|
[NonSerialized]
|
|
private RTHandle[] m_WaterVelRT = { null, null };
|
|
[NonSerialized]
|
|
private RTHandle[] m_FluxRT = { null, null };
|
|
[NonSerialized]
|
|
private RTHandle[] m_SedimentRT = { null, null };
|
|
|
|
|
|
[NonSerialized]
|
|
private RTHandle m_ErodedRT = null;
|
|
private RTHandle m_HardnessRT = null;
|
|
|
|
[NonSerialized]
|
|
Vector2Int m_RTSize = new Vector2Int(0, 0);
|
|
|
|
[NonSerialized]
|
|
private ComputeShader m_HydraulicCS = null;
|
|
[NonSerialized]
|
|
private ComputeShader m_ThermalCS = null;
|
|
|
|
|
|
|
|
private ComputeShader GetHydraulicCS()
|
|
{
|
|
if (m_HydraulicCS == null)
|
|
{
|
|
m_HydraulicCS = ComputeUtility.GetShader("Hydraulic");
|
|
}
|
|
return m_HydraulicCS;
|
|
}
|
|
|
|
private ComputeShader GetThermalCS()
|
|
{
|
|
if (m_ThermalCS == null)
|
|
{
|
|
m_ThermalCS = ComputeUtility.GetShader("Thermal");
|
|
}
|
|
return m_ThermalCS;
|
|
}
|
|
|
|
private void CreateRTHandles(Vector2Int dim)
|
|
{
|
|
m_RTSize = dim;
|
|
|
|
var r = RTUtils.GetDescriptorRW(dim.x, dim.y, 0, RenderTextureFormat.RFloat);
|
|
var rg = RTUtils.GetDescriptorRW(dim.x, dim.y, 0, RenderTextureFormat.RGFloat);
|
|
var argb = RTUtils.GetDescriptorRW(dim.x, dim.y, 0, RenderTextureFormat.ARGBFloat);
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
m_HeightmapRT[i] = RTUtils.GetNewHandle(r).WithName("HydroErosion_Height" + i);
|
|
m_WaterRT[i] = RTUtils.GetNewHandle(r).WithName("HydroErosion_Water" + i);
|
|
m_WaterVelRT[i] = RTUtils.GetNewHandle(rg).WithName("HydroErosion_WaterVel" + i);
|
|
m_FluxRT[i] = RTUtils.GetNewHandle(argb).WithName("HydroErosion_Flux" + i);
|
|
m_SedimentRT[i] = RTUtils.GetNewHandle(r).WithName("HydroErosion_Sediment" + i);
|
|
|
|
m_HeightmapRT[i].RT.Create();
|
|
m_WaterRT[i].RT.Create();
|
|
m_WaterVelRT[i].RT.Create();
|
|
m_FluxRT[i].RT.Create();
|
|
m_SedimentRT[i].RT.Create();
|
|
}
|
|
|
|
m_ErodedRT = RTUtils.GetNewHandle(r).WithName("HydroErosion_Eroded");
|
|
m_ErodedRT.RT.Create();
|
|
|
|
m_HardnessRT = RTUtils.GetNewHandle(r).WithName("HydroErosion_Hardness");
|
|
m_HardnessRT.RT.Create();
|
|
}
|
|
|
|
private void ReleaseRTHandles()
|
|
{
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
RTUtils.Release(m_HeightmapRT[i]);
|
|
RTUtils.Release(m_WaterRT[i]);
|
|
RTUtils.Release(m_WaterVelRT[i]);
|
|
RTUtils.Release(m_FluxRT[i]);
|
|
RTUtils.Release(m_SedimentRT[i]);
|
|
}
|
|
|
|
RTUtils.Release(m_ErodedRT);
|
|
RTUtils.Release(m_HardnessRT);
|
|
}
|
|
|
|
private void ClearRTHandles()
|
|
{
|
|
RenderTexture tmp = RenderTexture.active;
|
|
|
|
for (int i = 0; i < 2; i++)
|
|
{
|
|
Graphics.Blit(Texture2D.blackTexture, m_WaterRT[i]);
|
|
Graphics.Blit(Texture2D.blackTexture, m_WaterVelRT[i]);
|
|
Graphics.Blit(Texture2D.blackTexture, m_FluxRT[i]);
|
|
Graphics.Blit(Texture2D.blackTexture, m_SedimentRT[i]);
|
|
}
|
|
|
|
Graphics.Blit(Texture2D.blackTexture, m_ErodedRT);
|
|
Graphics.Blit(Texture2D.blackTexture, m_HardnessRT);
|
|
|
|
RenderTexture.active = tmp;
|
|
}
|
|
|
|
public Dictionary<string, RenderTexture> inputTextures { get; set; } = new Dictionary<string, RenderTexture>();
|
|
|
|
|
|
[SerializeField]
|
|
private bool m_ShowControls = true;
|
|
[SerializeField]
|
|
private bool m_ShowAdvancedUI = false;
|
|
[SerializeField]
|
|
private bool m_ShowThermalUI = false;
|
|
[SerializeField]
|
|
private bool m_ShowWaterUI = false;
|
|
[SerializeField]
|
|
private bool m_ShowSedimentUI = false;
|
|
[SerializeField]
|
|
private bool m_ShowRiverBankUI = false;
|
|
|
|
public void OnEnable() { }
|
|
|
|
public void OnInspectorGUI(Terrain terrain, IOnInspectorGUI editContext)
|
|
{
|
|
|
|
m_ShowControls = TerrainToolGUIHelper.DrawHeaderFoldoutForErosion(Erosion.Styles.m_HydroErosionControls, m_ShowControls, ResetToolVar);
|
|
|
|
|
|
if (m_ShowControls)
|
|
{
|
|
EditorGUILayout.BeginVertical("GroupBox");
|
|
m_ErosionSettings.m_SimScale.DrawInspectorGUI();
|
|
|
|
EditorGUI.indentLevel++;
|
|
m_ShowAdvancedUI = TerrainToolGUIHelper.DrawSimpleFoldout(new GUIContent("Advanced"), m_ShowAdvancedUI);
|
|
|
|
if (m_ShowAdvancedUI)
|
|
{
|
|
//m_ErosionSettings.m_IterationBlendScalar.DrawInspectorGUI();
|
|
m_ErosionSettings.m_HydroTimeDelta.DrawInspectorGUI();
|
|
m_ErosionSettings.m_HydroIterations.DrawInspectorGUI();
|
|
|
|
//m_ErosionSettings.m_GravitationalConstant = EditorGUILayout.Slider(Erosion.Styles.m_GravitationConstant, m_ErosionSettings.m_GravitationalConstant, 0.0f, -100.0f);
|
|
|
|
EditorGUI.indentLevel++;
|
|
m_ShowThermalUI = TerrainToolGUIHelper.DrawSimpleFoldout(new GUIContent("Thermal Smoothing"), m_ShowThermalUI, 1);
|
|
if (m_ShowThermalUI)
|
|
{
|
|
//m_ErosionSettings.m_DoThermal = EditorGUILayout.Toggle(Erosion.Styles.m_DoThermal, m_ErosionSettings.m_DoThermal);
|
|
m_ErosionSettings.m_ThermalTimeDelta = EditorGUILayout.Slider(Erosion.Styles.m_ThermalDTScalar, m_ErosionSettings.m_ThermalTimeDelta, 0.0001f, 10.0f);
|
|
m_ErosionSettings.m_ThermalIterations = EditorGUILayout.IntSlider(Erosion.Styles.m_NumIterations, m_ErosionSettings.m_ThermalIterations, 0, 100);
|
|
m_ErosionSettings.m_ThermalReposeAngle = EditorGUILayout.IntSlider(Erosion.Styles.m_AngleOfRepose, m_ErosionSettings.m_ThermalReposeAngle, 0, 90);
|
|
}
|
|
|
|
m_ShowWaterUI = TerrainToolGUIHelper.DrawSimpleFoldout(new GUIContent("Water Transport"), m_ShowWaterUI, 1);
|
|
if (m_ShowWaterUI)
|
|
{
|
|
//m_ErosionSettings.m_WaterLevelScale = EditorGUILayout.Slider(Erosion.Styles.m_WaterLevelScale, m_ErosionSettings.m_WaterLevelScale, 0.0f, 100.0f);
|
|
m_ErosionSettings.m_PrecipRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_EvaporationRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_FlowRate.DrawInspectorGUI();
|
|
}
|
|
|
|
m_ShowSedimentUI = TerrainToolGUIHelper.DrawSimpleFoldout(new GUIContent("Sediment Transport"), m_ShowSedimentUI, 1);
|
|
if (m_ShowSedimentUI)
|
|
{
|
|
//m_ErosionSettings.m_SedimentScale = EditorGUILayout.Slider(Erosion.Styles.m_SedimentScale, m_ErosionSettings.m_SedimentScale, 0.0f, 10.0f);
|
|
m_ErosionSettings.m_SedimentCapacity.DrawInspectorGUI();
|
|
m_ErosionSettings.m_SedimentDepositRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_SedimentDissolveRate.DrawInspectorGUI();
|
|
}
|
|
|
|
m_ShowRiverBankUI = TerrainToolGUIHelper.DrawSimpleFoldout(new GUIContent("Riverbank"), m_ShowRiverBankUI, 1);
|
|
if (m_ShowRiverBankUI)
|
|
{
|
|
m_ErosionSettings.m_RiverBankDepositRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_RiverBankDissolveRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_RiverBedDepositRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_RiverBedDissolveRate.DrawInspectorGUI();
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
}
|
|
|
|
public void ResetToolVar()
|
|
{
|
|
m_ErosionSettings.Reset();
|
|
}
|
|
|
|
public void OnMaterialInspectorGUI(Terrain terrain, IOnInspectorGUI editContext)
|
|
{
|
|
m_ShowControls = EditorGUILayout.Foldout(m_ShowControls, "Hydraulic Erosion Controls");
|
|
|
|
if (m_ShowControls)
|
|
{
|
|
|
|
EditorGUILayout.BeginVertical("GroupBox");
|
|
|
|
string[] maskSourceNames = new string[] {
|
|
"Sediment",
|
|
"Heightmap Differential",
|
|
"Water Flux",
|
|
"Water Level",
|
|
"Water Speed"
|
|
};
|
|
|
|
m_ErosionSettings.m_MaskSourceSelection = (HydraulicErosionSettings.MaskSource)EditorGUILayout.Popup("Mask Source", (int)m_ErosionSettings.m_MaskSourceSelection, maskSourceNames);
|
|
|
|
m_ErosionSettings.m_SimScale.DrawInspectorGUI();
|
|
|
|
EditorGUI.BeginChangeCheck();
|
|
m_ErosionSettings.m_MaterialSpread.DrawInspectorGUI();
|
|
if (EditorGUI.EndChangeCheck())
|
|
{
|
|
switch (m_ErosionSettings.m_MaskSourceSelection)
|
|
{
|
|
case HydraulicErosionSettings.MaskSource.HeightDiff:
|
|
case HydraulicErosionSettings.MaskSource.Sediment:
|
|
m_ErosionSettings.m_SimScale.value = Mathf.Lerp(0.0f, 10.0f, m_ErosionSettings.m_MaterialSpread.value);
|
|
m_ErosionSettings.m_ThermalTimeDelta = Mathf.Lerp(0.001f, 0.0001f, m_ErosionSettings.m_MaterialSpread.value);
|
|
break;
|
|
case HydraulicErosionSettings.MaskSource.WaterFlux:
|
|
m_ErosionSettings.m_SimScale.value = Mathf.Lerp(10.0f, 0.0f, m_ErosionSettings.m_MaterialSpread.value);
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
m_ErosionSettings.m_MaterialOpacity = EditorGUILayout.Slider(Erosion.Styles.m_MaterialOpacity, m_ErosionSettings.m_MaterialOpacity, 0.0f, 1.0f);
|
|
|
|
EditorGUI.indentLevel++;
|
|
m_ShowAdvancedUI = EditorGUILayout.Foldout(m_ShowAdvancedUI, "Advanced");
|
|
|
|
if (m_ShowAdvancedUI)
|
|
{
|
|
m_ErosionSettings.m_IterationBlendScalar.DrawInspectorGUI();
|
|
m_ErosionSettings.m_HydroTimeDelta.DrawInspectorGUI();
|
|
m_ErosionSettings.m_HydroIterations.DrawInspectorGUI();
|
|
|
|
//m_ErosionSettings.m_GravitationalConstant = EditorGUILayout.Slider(Erosion.Styles.m_GravitationConstant, m_ErosionSettings.m_GravitationalConstant, 0.0f, -100.0f);
|
|
|
|
EditorGUI.indentLevel++;
|
|
m_ShowThermalUI = EditorGUILayout.Foldout(m_ShowThermalUI, "Thermal Erosion");
|
|
if (m_ShowThermalUI)
|
|
{
|
|
m_ErosionSettings.m_DoThermal = EditorGUILayout.Toggle(Erosion.Styles.m_DoThermal, m_ErosionSettings.m_DoThermal);
|
|
m_ErosionSettings.m_ThermalTimeDelta = EditorGUILayout.Slider(Erosion.Styles.m_ThermalDTScalar, m_ErosionSettings.m_ThermalTimeDelta, 0.0000f, 0.001f);
|
|
m_ErosionSettings.m_ThermalIterations = EditorGUILayout.IntSlider(Erosion.Styles.m_NumIterations, m_ErosionSettings.m_ThermalIterations, 0, 100);
|
|
m_ErosionSettings.m_ThermalReposeAngle = EditorGUILayout.IntSlider(Erosion.Styles.m_AngleOfRepose, m_ErosionSettings.m_ThermalReposeAngle, 0, 90);
|
|
}
|
|
|
|
m_ShowWaterUI = EditorGUILayout.Foldout(m_ShowWaterUI, "Water Transport");
|
|
if (m_ShowWaterUI)
|
|
{
|
|
m_ErosionSettings.m_WaterLevelScale = EditorGUILayout.Slider(Erosion.Styles.m_WaterLevelScale, m_ErosionSettings.m_WaterLevelScale, 0.0f, 100.0f);
|
|
m_ErosionSettings.m_PrecipRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_EvaporationRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_FlowRate.DrawInspectorGUI();
|
|
}
|
|
|
|
m_ShowSedimentUI = EditorGUILayout.Foldout(m_ShowSedimentUI, "Sediment Transport");
|
|
if (m_ShowSedimentUI)
|
|
{
|
|
m_ErosionSettings.m_SedimentScale = EditorGUILayout.Slider(Erosion.Styles.m_SedimentScale, m_ErosionSettings.m_SedimentScale, 0.0f, 1.0f);
|
|
m_ErosionSettings.m_SedimentDepositRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_SedimentCapacity.DrawInspectorGUI();
|
|
m_ErosionSettings.m_SedimentDissolveRate.DrawInspectorGUI();
|
|
}
|
|
|
|
m_ShowRiverBankUI = EditorGUILayout.Foldout(m_ShowRiverBankUI, "Riverbank");
|
|
if (m_ShowRiverBankUI)
|
|
{
|
|
m_ErosionSettings.m_RiverBankDepositRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_RiverBankDissolveRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_RiverBedDepositRate.DrawInspectorGUI();
|
|
m_ErosionSettings.m_RiverBedDissolveRate.DrawInspectorGUI();
|
|
}
|
|
}
|
|
|
|
EditorGUILayout.EndVertical();
|
|
}
|
|
}
|
|
|
|
public void ErodeHeightmap(RenderTexture dest, Vector3 terrainDimensions, Rect domainRect, Vector2 texelSize, bool invertEffect = false)
|
|
{
|
|
ErodeHelper(dest, terrainDimensions, texelSize, invertEffect, false);
|
|
}
|
|
|
|
public void GetShaderParams(ref int pass, ref RenderTexture maskRT)
|
|
{
|
|
//TODO: betterify this.
|
|
switch (m_ErosionSettings.m_MaskSourceSelection)
|
|
{
|
|
case Erosion.HydraulicErosionSettings.MaskSource.Sediment:
|
|
pass = 0;
|
|
maskRT = m_ErodedRT;
|
|
break;
|
|
case Erosion.HydraulicErosionSettings.MaskSource.HeightDiff:
|
|
pass = 0;
|
|
maskRT = m_ErodedRT; //TODO - this isn't quite right since we're actually putting height diff into the eroded RT
|
|
break;
|
|
case Erosion.HydraulicErosionSettings.MaskSource.WaterFlux:
|
|
pass = 2;
|
|
maskRT = m_FluxRT[1];
|
|
break;
|
|
case Erosion.HydraulicErosionSettings.MaskSource.WaterLevel:
|
|
pass = 0;
|
|
maskRT = m_WaterRT[1];
|
|
break;
|
|
case Erosion.HydraulicErosionSettings.MaskSource.WaterSpeed:
|
|
pass = 1;
|
|
maskRT = m_WaterVelRT[1];
|
|
break;
|
|
}
|
|
}
|
|
|
|
private void ErodeHelper(RenderTexture dest, Vector3 terrainScale, Vector2 texelSize, bool invertEffect, bool lowRes)
|
|
{
|
|
ComputeShader hydraulicCS = GetHydraulicCS();
|
|
ComputeShader thermalCS = GetThermalCS();
|
|
|
|
//this one is mandatory
|
|
if (!inputTextures.ContainsKey("Height"))
|
|
{
|
|
throw (new Exception("No input heightfield specified!"));
|
|
}
|
|
|
|
int[] numWorkGroups = { 8, 8, 1 };
|
|
|
|
//figure out what size we need our render targets to be
|
|
Vector2Int domainRes = new Vector2Int(inputTextures["Height"].width, inputTextures["Height"].height);
|
|
|
|
int rx = domainRes.x - (numWorkGroups[0] * (domainRes.x / numWorkGroups[0]));
|
|
int ry = domainRes.y - (numWorkGroups[1] * (domainRes.y / numWorkGroups[1]));
|
|
|
|
domainRes.x += numWorkGroups[0] - rx;
|
|
domainRes.y += numWorkGroups[1] - ry;
|
|
|
|
if (lowRes)
|
|
{
|
|
domainRes.x /= 2;
|
|
domainRes.y /= 2;
|
|
}
|
|
|
|
CreateRTHandles(new Vector2Int(domainRes.x, domainRes.y));
|
|
|
|
RenderTexture rt = RenderTexture.active;
|
|
Graphics.Blit(inputTextures["Height"], m_HeightmapRT[0]);
|
|
Graphics.Blit(inputTextures["Height"], m_HeightmapRT[1]);
|
|
|
|
if (inputTextures.ContainsKey("Hardness"))
|
|
{
|
|
Graphics.Blit(inputTextures["Hardness"], m_HardnessRT);
|
|
}
|
|
else
|
|
{
|
|
Graphics.Blit(Texture2D.blackTexture, m_HardnessRT);
|
|
}
|
|
|
|
RenderTexture.active = rt;
|
|
|
|
ClearRTHandles();
|
|
|
|
int sedimentKernelIdx = hydraulicCS.FindKernel("HydraulicErosion");
|
|
int flowKernelIdx = hydraulicCS.FindKernel("SimulateWaterFlow");
|
|
int thermalKernelIdx = thermalCS.FindKernel("ThermalErosion");
|
|
|
|
float precipRate = 0.00001f * m_ErosionSettings.m_PrecipRate.value;
|
|
float evaporationRate = 0.00001f * m_ErosionSettings.m_EvaporationRate.value;
|
|
float flowRate = 0.0001f * m_ErosionSettings.m_FlowRate.value;
|
|
float sedimentCap = 0.1f * m_ErosionSettings.m_SedimentCapacity.value;
|
|
float sedimentDissolveRate = 0.0001f * m_ErosionSettings.m_SedimentDissolveRate.value;
|
|
float sedimentDepositRate = 0.0001f * m_ErosionSettings.m_SedimentDepositRate.value;
|
|
|
|
float simScale = 0.001f * Mathf.Max(m_ErosionSettings.m_SimScale.value, 0.000001f);
|
|
float dx = (float)texelSize.x * simScale;
|
|
float dy = (float)texelSize.y * simScale;
|
|
float dxdy = Mathf.Sqrt(dx * dx + dy * dy);
|
|
|
|
float effectScalar = m_ErosionSettings.m_IterationBlendScalar.value;
|
|
|
|
|
|
//constants for both kernels
|
|
hydraulicCS.SetFloat("EffectScalar", invertEffect ? effectScalar : -effectScalar);
|
|
hydraulicCS.SetFloat("DT", m_ErosionSettings.m_HydroTimeDelta.value);
|
|
hydraulicCS.SetVector("dxdy", new Vector4(dx, dy, 1.0f / dx, 1.0f / dy));
|
|
hydraulicCS.SetVector("WaterTransportScalars", new Vector4(m_ErosionSettings.m_WaterLevelScale, precipRate, flowRate * m_ErosionSettings.m_GravitationalConstant, evaporationRate));
|
|
hydraulicCS.SetVector("SedimentScalars", new Vector4(m_ErosionSettings.m_SedimentScale, sedimentCap, sedimentDissolveRate, sedimentDepositRate));
|
|
hydraulicCS.SetVector("RiverBedScalars", new Vector4(m_ErosionSettings.m_RiverBedDissolveRate.value, m_ErosionSettings.m_RiverBedDepositRate.value, m_ErosionSettings.m_RiverBankDissolveRate.value, m_ErosionSettings.m_RiverBankDepositRate.value));
|
|
hydraulicCS.SetVector("terrainDim", new Vector4(terrainScale.x, terrainScale.y, terrainScale.z));
|
|
hydraulicCS.SetVector("texDim", new Vector4((float)domainRes.x, (float)domainRes.y, 0.0f, 0.0f));
|
|
|
|
if (m_ErosionSettings.m_DoThermal)
|
|
{
|
|
//thermal kernel inputs
|
|
Vector2 thermal_m = new Vector2(Mathf.Tan((float)m_ErosionSettings.m_ThermalReposeAngle * Mathf.Deg2Rad), Mathf.Tan((float)m_ErosionSettings.m_ThermalReposeAngle * Mathf.Deg2Rad));
|
|
|
|
thermalCS.SetFloat("dt", m_ErosionSettings.m_ThermalTimeDelta * m_ErosionSettings.m_HydroTimeDelta.value);
|
|
thermalCS.SetFloat("EffectScalar", invertEffect ? effectScalar : -effectScalar);
|
|
thermalCS.SetVector("angleOfRepose", new Vector4(thermal_m.x, thermal_m.y, 0.0f, 0.0f));
|
|
thermalCS.SetVector("dxdy", new Vector4(dx, dy, 1.0f / dx, 1.0f / dy));
|
|
thermalCS.SetFloat("InvDiagMag", 1.0f / Mathf.Sqrt(dx * dx + dy * dy));
|
|
thermalCS.SetVector("terrainDim", new Vector4(terrainScale.x, terrainScale.y, terrainScale.z));
|
|
thermalCS.SetVector("texDim", new Vector4((float)domainRes.x, (float)domainRes.y, 0.0f, 0.0f));
|
|
|
|
thermalCS.SetTexture(thermalKernelIdx, "TerrainHeightPrev", m_HeightmapRT[0]);
|
|
thermalCS.SetTexture(thermalKernelIdx, "TerrainHeight", m_HeightmapRT[1]);
|
|
thermalCS.SetTexture(thermalKernelIdx, "SedimentPrev", m_SedimentRT[0]);
|
|
thermalCS.SetTexture(thermalKernelIdx, "Sediment", m_SedimentRT[1]);
|
|
//thermalCS.SetTexture(thermalKernelIdx, "Collision", inputTextures["Collision"]);
|
|
}
|
|
|
|
int pingPongIdx = 0;
|
|
for (int i = 0; i < (lowRes ? m_ErosionSettings.m_HydroLowResIterations : m_ErosionSettings.m_HydroIterations.value); i++)
|
|
{
|
|
int a = pingPongIdx;
|
|
int b = (a + 1) % 2;
|
|
|
|
//flow kernel textures
|
|
hydraulicCS.SetTexture(flowKernelIdx, "TerrainHeightPrev", m_HeightmapRT[a]);
|
|
hydraulicCS.SetTexture(flowKernelIdx, "WaterPrev", m_WaterRT[a]);
|
|
hydraulicCS.SetTexture(flowKernelIdx, "Water", m_WaterRT[b]);
|
|
hydraulicCS.SetTexture(flowKernelIdx, "WaterVelPrev", m_WaterVelRT[a]);
|
|
hydraulicCS.SetTexture(flowKernelIdx, "WaterVel", m_WaterVelRT[b]);
|
|
hydraulicCS.SetTexture(flowKernelIdx, "FluxPrev", m_FluxRT[a]);
|
|
hydraulicCS.SetTexture(flowKernelIdx, "Flux", m_FluxRT[b]);
|
|
|
|
|
|
hydraulicCS.Dispatch(flowKernelIdx, domainRes.x / numWorkGroups[0], domainRes.y / numWorkGroups[1], numWorkGroups[2]);
|
|
|
|
//Sediment Setup
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "TerrainHeightPrev", m_HeightmapRT[a]);
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "TerrainHeight", m_HeightmapRT[b]);
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "Water", m_WaterRT[a]);
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "WaterPrev", m_WaterRT[b]);
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "WaterVel", m_WaterVelRT[b]);
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "Flux", m_FluxRT[b]);
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "SedimentPrev", m_SedimentRT[a]);
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "Sediment", m_SedimentRT[b]);
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "Hardness", m_HardnessRT);
|
|
hydraulicCS.SetTexture(sedimentKernelIdx, "Eroded", m_ErodedRT);
|
|
|
|
|
|
hydraulicCS.Dispatch(sedimentKernelIdx, domainRes.x / numWorkGroups[0], domainRes.y / numWorkGroups[1], numWorkGroups[2]);
|
|
|
|
//Thermal Smoothing
|
|
//now do a few thermal iterations to let things settle
|
|
int thermalPingPongIdx = 0;
|
|
for (int j = 0; m_ErosionSettings.m_DoThermal && (j < m_ErosionSettings.m_ThermalIterations); j++)
|
|
{
|
|
int ta = thermalPingPongIdx;
|
|
int tb = (ta + 1) % 2;
|
|
thermalCS.SetTexture(thermalKernelIdx, "TerrainHeightPrev", m_HeightmapRT[ta]);
|
|
thermalCS.SetTexture(thermalKernelIdx, "TerrainHeight", m_HeightmapRT[tb]);
|
|
thermalCS.SetTexture(thermalKernelIdx, "Hardness", m_HardnessRT);
|
|
|
|
thermalCS.Dispatch(thermalKernelIdx, domainRes.x / numWorkGroups[0], domainRes.y / numWorkGroups[1], numWorkGroups[2]);
|
|
thermalPingPongIdx = (thermalPingPongIdx + 1) % 2;
|
|
}
|
|
|
|
pingPongIdx = (pingPongIdx + 1) % 2;
|
|
}
|
|
|
|
// set up the output render textures
|
|
Graphics.Blit(m_HeightmapRT[1], dest);
|
|
|
|
ReleaseRTHandles();
|
|
}
|
|
}
|
|
}
|