This commit is contained in:
CortexCore
2025-03-14 21:04:19 +08:00
parent ff8670c453
commit 757ffe79ee
1282 changed files with 104378 additions and 3 deletions

View File

@@ -0,0 +1,326 @@
#if GRIFFIN
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Griffin.ErosionTool
{
public class GErosionApplier
{
public GErosionSimulator Simulator { get; private set; }
private static Material applyGeometryMaterial;
private static Material ApplyGeometryMaterial
{
get
{
if (applyGeometryMaterial == null)
{
applyGeometryMaterial = new Material(GRuntimeSettings.Instance.internalShaders.applyErosionShader);
}
return applyGeometryMaterial;
}
}
private static Material applyTextureMaterial;
private static Material ApplyTextureMaterial
{
get
{
if (applyTextureMaterial == null)
{
applyTextureMaterial = new Material(GRuntimeSettings.Instance.internalShaders.erosionTexturerShader);
}
return applyTextureMaterial;
}
}
private static readonly int HEIGHT_MAP = Shader.PropertyToID("_HeightMap");
private static readonly int SIMULATION_DATA = Shader.PropertyToID("_SimulationData");
private static readonly int FALLOFF_TEXTURE = Shader.PropertyToID("_FalloffTexture");
private static readonly int BOUNDS = Shader.PropertyToID("_Bounds");
private static readonly int MAIN_TEX = Shader.PropertyToID("_MainTex");
private static readonly int EROSION_MAP = Shader.PropertyToID("_ErosionMap");
private static readonly int EROSION_ALBEDO = Shader.PropertyToID("_ErosionAlbedo");
private static readonly int EROSION_METALLIC = Shader.PropertyToID("_ErosionMetallic");
private static readonly int EROSION_SMOOTHNESS = Shader.PropertyToID("_ErosionSmoothness");
private static readonly int EROSION_CHANNEL_INDEX = Shader.PropertyToID("_ErosionChannelIndex");
private static readonly int EROSION_INTENSITY = Shader.PropertyToID("_ErosionIntensity");
private static readonly int EROSION_EXPONENT = Shader.PropertyToID("_ErosionExponent");
private static readonly int DEPOSITION_ALBEDO = Shader.PropertyToID("_DepositionAlbedo");
private static readonly int DEPOSITION_METALLIC = Shader.PropertyToID("_DepositionMetallic");
private static readonly int DEPOSITION_SMOOTHNESS = Shader.PropertyToID("_DepositionSmoothness");
private static readonly int DEPOSITION_CHANNEL_INDEX = Shader.PropertyToID("_DepositionChannelIndex");
private static readonly int DEPOSITION_INTENSITY = Shader.PropertyToID("_DepositionIntensity");
private static readonly int DEPOSITION_EXPONENT = Shader.PropertyToID("_DepositionExponent");
private static readonly int PASS_APPLY_SPLAT = 0;
private static readonly int PASS_APPLY_ALBEDO = 1;
private static readonly int PASS_APPLY_METALLIC = 2;
public GErosionApplier(GErosionSimulator s)
{
Simulator = s;
}
public void ApplyGeometry()
{
List<GStylizedTerrain> terrains = Simulator.GetIntersectedTerrains();
if (terrains.Count == 0)
return;
for (int i = 0; i < terrains.Count; ++i)
{
ApplyGeometry(terrains[i]);
}
for (int i = 0; i < terrains.Count; ++i)
{
UpdateGeometry(terrains[i]);
}
}
private void ApplyGeometry(GStylizedTerrain t)
{
Vector3[] worldCorner = Simulator.GetQuad();
Vector2[] uvCorners = new Vector2[worldCorner.Length];
for (int i = 0; i < uvCorners.Length; ++i)
{
uvCorners[i] = t.WorldPointToUV(worldCorner[i]);
}
Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
return;
int resolution = t.TerrainData.Geometry.HeightMapResolution;
RenderTexture rt = new RenderTexture(resolution, resolution, 0, GGeometry.HeightMapRTFormat, RenderTextureReadWrite.Linear);
GCommon.CopyToRT(t.TerrainData.Geometry.HeightMap, rt);
ApplyGeometryMaterial.SetTexture(HEIGHT_MAP, t.TerrainData.Geometry.HeightMap);
ApplyGeometryMaterial.SetTexture(SIMULATION_DATA, Simulator.SimulationData);
ApplyGeometryMaterial.SetTexture(FALLOFF_TEXTURE, Simulator.FalloffTexture);
ApplyGeometryMaterial.SetVector(BOUNDS, Simulator.Bounds);
GCommon.DrawQuad(rt, uvCorners, ApplyGeometryMaterial, 0);
Color[] oldHeightMapColors = t.TerrainData.Geometry.HeightMap.GetPixels();
RenderTexture.active = rt;
t.TerrainData.Geometry.HeightMap.ReadPixels(new Rect(0, 0, resolution, resolution), 0, 0);
t.TerrainData.Geometry.HeightMap.Apply();
RenderTexture.active = null;
Color[] newHeightMapColors = t.TerrainData.Geometry.HeightMap.GetPixels();
rt.Release();
GUtilities.DestroyObject(rt);
List<Rect> dirtyRects = new List<Rect>(GCommon.CompareTerrainTexture(t.TerrainData.Geometry.ChunkGridSize, oldHeightMapColors, newHeightMapColors));
for (int i = 0; i < dirtyRects.Count; ++i)
{
t.TerrainData.Geometry.SetRegionDirty(dirtyRects[i]);
t.TerrainData.Foliage.SetTreeRegionDirty(dirtyRects[i]);
t.TerrainData.Foliage.SetGrassRegionDirty(dirtyRects[i]);
}
}
private void UpdateGeometry(GStylizedTerrain t)
{
t.TerrainData.SetDirty(GTerrainData.DirtyFlags.Geometry);
t.UpdateTreesPosition();
t.UpdateGrassPatches();
t.TerrainData.Foliage.ClearTreeDirtyRegions();
t.TerrainData.Foliage.ClearGrassDirtyRegions();
t.TerrainData.SetDirty(GTerrainData.DirtyFlags.Foliage);
}
public void ApplySplat()
{
List<GStylizedTerrain> terrains = Simulator.GetIntersectedTerrains();
if (terrains.Count == 0)
return;
for (int i = 0; i < terrains.Count; ++i)
{
ApplySplat(terrains[i]);
}
}
private void ApplySplat(GStylizedTerrain t)
{
int controlMapCount = t.TerrainData.Shading.SplatControlMapCount;
int controlMapResolution = t.TerrainData.Shading.SplatControlResolution;
RenderTexture[] rtControls = new RenderTexture[controlMapCount];
for (int i = 0; i < controlMapCount; ++i)
{
rtControls[i] = new RenderTexture(controlMapResolution, controlMapResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
}
if (!Internal_ApplySplat(t, rtControls))
{
for (int i = 0; i < controlMapCount; ++i)
{
rtControls[i].Release();
Object.DestroyImmediate(rtControls[i]);
}
return;
}
for (int i = 0; i < controlMapCount; ++i)
{
Texture2D splatControl = t.TerrainData.Shading.GetSplatControl(i);
RenderTexture.active = rtControls[i];
splatControl.ReadPixels(new Rect(0, 0, controlMapResolution, controlMapResolution), 0, 0);
splatControl.Apply();
RenderTexture.active = null;
rtControls[i].Release();
Object.DestroyImmediate(rtControls[i]);
}
}
public bool Internal_ApplySplat(GStylizedTerrain t, RenderTexture[] rtControls)
{
Vector3[] worldCorner = Simulator.GetQuad();
Vector2[] uvCorners = new Vector2[worldCorner.Length];
for (int i = 0; i < uvCorners.Length; ++i)
{
uvCorners[i] = t.WorldPointToUV(worldCorner[i]);
}
Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
return false;
GErosionTexturingConfigs config = Simulator.TexturingConfigs;
Material mat = ApplyTextureMaterial;
mat.SetTexture(EROSION_MAP, Simulator.ErosionMap);
mat.SetTexture(FALLOFF_TEXTURE, Simulator.FalloffTexture);
mat.SetFloat(EROSION_INTENSITY, config.ErosionIntensity);
mat.SetFloat(EROSION_EXPONENT, config.ErosionExponent);
mat.SetFloat(DEPOSITION_INTENSITY, config.DepositionIntensity);
mat.SetFloat(DEPOSITION_EXPONENT, config.DepositionExponent);
int controlMapCount = t.TerrainData.Shading.SplatControlMapCount;
for (int i = 0; i < controlMapCount; ++i)
{
Texture2D control = t.TerrainData.Shading.GetSplatControl(i);
GCommon.CopyToRT(control, rtControls[i]);
mat.SetTexture(MAIN_TEX, control);
if (config.ErosionSplatIndex / 4 == i)
{
mat.SetInt(EROSION_CHANNEL_INDEX, config.ErosionSplatIndex % 4);
}
else
{
mat.SetInt(EROSION_CHANNEL_INDEX, -1);
}
if (config.DepositionSplatIndex / 4 == i)
{
mat.SetInt(DEPOSITION_CHANNEL_INDEX, config.DepositionSplatIndex % 4);
}
else
{
mat.SetInt(DEPOSITION_CHANNEL_INDEX, -1);
}
GCommon.DrawQuad(rtControls[i], uvCorners, mat, PASS_APPLY_SPLAT);
}
return true;
}
public void ApplyAMS()
{
List<GStylizedTerrain> terrains = Simulator.GetIntersectedTerrains();
if (terrains.Count == 0)
return;
for (int i = 0; i < terrains.Count; ++i)
{
ApplyAMS(terrains[i]);
}
}
private void ApplyAMS(GStylizedTerrain t)
{
int albedoResolution = t.TerrainData.Shading.AlbedoMapResolution;
RenderTexture rtAlbedo = new RenderTexture(albedoResolution, albedoResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
int metallicResolution = t.TerrainData.Shading.MetallicMapResolution;
RenderTexture rtMetallic = new RenderTexture(metallicResolution, metallicResolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear);
if (!Internal_ApplyAMS(t, rtAlbedo, rtMetallic))
{
rtAlbedo.Release();
Object.DestroyImmediate(rtAlbedo);
rtMetallic.Release();
Object.DestroyImmediate(rtMetallic);
return;
}
Texture2D albedoMap = t.TerrainData.Shading.AlbedoMap;
RenderTexture.active = rtAlbedo;
albedoMap.ReadPixels(new Rect(0, 0, albedoResolution, albedoResolution), 0, 0);
albedoMap.Apply();
RenderTexture.active = null;
rtAlbedo.Release();
Object.DestroyImmediate(rtAlbedo);
Texture2D metallicMap = t.TerrainData.Shading.MetallicMap;
RenderTexture.active = rtMetallic;
metallicMap.ReadPixels(new Rect(0, 0, metallicResolution, metallicResolution), 0, 0);
metallicMap.Apply();
RenderTexture.active = null;
rtMetallic.Release();
Object.DestroyImmediate(rtMetallic);
}
public bool Internal_ApplyAMS(GStylizedTerrain t, RenderTexture rtAlbedo, RenderTexture rtMetallic)
{
Vector3[] worldCorner = Simulator.GetQuad();
Vector2[] uvCorners = new Vector2[worldCorner.Length];
for (int i = 0; i < uvCorners.Length; ++i)
{
uvCorners[i] = t.WorldPointToUV(worldCorner[i]);
}
Rect dirtyRect = GUtilities.GetRectContainsPoints(uvCorners);
if (!dirtyRect.Overlaps(new Rect(0, 0, 1, 1)))
return false;
GCommon.CopyToRT(t.TerrainData.Shading.AlbedoMap, rtAlbedo);
GCommon.CopyToRT(t.TerrainData.Shading.MetallicMap, rtMetallic);
GErosionTexturingConfigs config = Simulator.TexturingConfigs;
Material mat = ApplyTextureMaterial;
mat.SetTexture(EROSION_MAP, Simulator.ErosionMap);
mat.SetTexture(FALLOFF_TEXTURE, Simulator.FalloffTexture);
mat.SetFloat(EROSION_INTENSITY, config.ErosionIntensity);
mat.SetFloat(EROSION_EXPONENT, config.ErosionExponent);
mat.SetColor(EROSION_ALBEDO, config.ErosionAlbedo);
mat.SetFloat(EROSION_METALLIC, config.ErosionMetallic);
mat.SetFloat(EROSION_SMOOTHNESS, config.ErosionSmoothness);
mat.SetFloat(DEPOSITION_INTENSITY, config.DepositionIntensity);
mat.SetFloat(DEPOSITION_EXPONENT, config.DepositionExponent);
mat.SetColor(DEPOSITION_ALBEDO, config.DepositionAlbedo);
mat.SetFloat(DEPOSITION_METALLIC, config.DepositionMetallic);
mat.SetFloat(DEPOSITION_SMOOTHNESS, config.DepositionSmoothness);
mat.SetTexture(MAIN_TEX, t.TerrainData.Shading.AlbedoMap);
GCommon.DrawQuad(rtAlbedo, uvCorners, mat, PASS_APPLY_ALBEDO);
mat.SetTexture(MAIN_TEX, t.TerrainData.Shading.MetallicMap);
GCommon.DrawQuad(rtMetallic, uvCorners, mat, PASS_APPLY_METALLIC);
return true;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: c3427383a734d09479139e97742db719
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,131 @@
#if GRIFFIN
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Pinwheel.Griffin.ErosionTool
{
public class GErosionInitializer
{
public GErosionSimulator Simulator { get; private set; }
private Material fetchWorldDataMaterial;
private Material FetchWorldDataMaterial
{
get
{
if (fetchWorldDataMaterial == null)
{
fetchWorldDataMaterial = new Material(GRuntimeSettings.Instance.internalShaders.fetchWorldDataShader);
}
return fetchWorldDataMaterial;
}
}
private static readonly int MAIN_TEX = Shader.PropertyToID("_MainTex");
private static readonly int BOUNDS = Shader.PropertyToID("_Bounds");
private static readonly int ENABLE_TERRAIN_MASK = Shader.PropertyToID("_EnableTerrainMask");
private static readonly int PASS_HEIGHT = 0;
private static readonly int PASS_MASK = 1;
private static readonly int PASS_EROSION_MAP = 2;
public GErosionInitializer(GErosionSimulator s)
{
Simulator = s;
}
public void Init(ref Vector3 bounds, ref RenderTexture simulationData, ref RenderTexture simulationMask, ref RenderTexture erosionMap)
{
List<GStylizedTerrain> terrains = Simulator.GetIntersectedTerrains();
bounds = GetSimulationBounds(terrains);
CreateRenderTexture(bounds, ref simulationData, ref simulationMask, ref erosionMap);
FetchWorldData(terrains, bounds, ref simulationData, ref simulationMask, ref erosionMap);
}
private Vector3 GetSimulationBounds(List<GStylizedTerrain> terrains)
{
Vector3 bounds = new Vector3();
bounds.x = Mathf.CeilToInt(Simulator.DetailLevel * Simulator.transform.lossyScale.x);
bounds.z = Mathf.CeilToInt(Simulator.DetailLevel * Simulator.transform.lossyScale.z);
for (int i = 0; i < terrains.Count; ++i)
{
bounds.y = Mathf.Max(bounds.y, terrains[i].TerrainData.Geometry.Height);
}
return bounds;
}
private void CreateRenderTexture(Vector3 bounds, ref RenderTexture simulationData, ref RenderTexture simulationMask, ref RenderTexture erosionMap)
{
if (simulationData != null)
{
simulationData.Release();
}
if (simulationMask!=null)
{
simulationMask.Release();
}
if (erosionMap!=null)
{
erosionMap.Release();
}
int width = Mathf.Clamp((int)bounds.x, 1, 4096);
int height = Mathf.Clamp((int)bounds.z, 1, 4096);
int depth = 0;
RenderTextureReadWrite rw = RenderTextureReadWrite.Linear;
simulationData = new RenderTexture(width, height, depth, RenderTextureFormat.ARGBFloat, rw);
simulationData.enableRandomWrite = true;
simulationData.wrapMode = TextureWrapMode.Clamp;
simulationData.Create();
simulationMask = new RenderTexture(width, height, depth, RenderTextureFormat.ARGBFloat, rw);
simulationMask.enableRandomWrite = true;
simulationMask.wrapMode = TextureWrapMode.Clamp;
simulationMask.Create();
erosionMap = new RenderTexture(width, height, depth, RenderTextureFormat.RGFloat, rw);
erosionMap.enableRandomWrite = true;
erosionMap.wrapMode = TextureWrapMode.Clamp;
erosionMap.Create();
}
private void FetchWorldData(List<GStylizedTerrain> terrains, Vector3 bounds, ref RenderTexture simulationData, ref RenderTexture simulationMask, ref RenderTexture erosionMap)
{
GCommon.DrawQuad(erosionMap, GCommon.FullRectUvPoints, FetchWorldDataMaterial, PASS_EROSION_MAP);
for (int i = 0; i < terrains.Count; ++i)
{
GStylizedTerrain t = terrains[i];
Vector3 terrainPos = t.transform.position;
Vector3 terrainSize = t.TerrainData.Geometry.Size;
Vector3[] terrainWorldCorners = new Vector3[4]
{
new Vector3(terrainPos.x, 0, terrainPos.z),
new Vector3(terrainPos.x, 0, terrainPos.z + terrainSize.z),
new Vector3(terrainPos.x + terrainSize.x, 0, terrainPos.z + terrainSize.z),
new Vector3(terrainPos.x + terrainSize.x, 0, terrainPos.z)
};
Vector2[] uvCorner = new Vector2[4];
for (int c = 0; c < uvCorner.Length; ++c)
{
Vector3 simSpaceCorner = Simulator.transform.InverseTransformPoint(terrainWorldCorners[c]);
uvCorner[c] = new Vector2(simSpaceCorner.x + 0.5f, simSpaceCorner.z + 0.5f);
}
FetchWorldDataMaterial.SetTexture(MAIN_TEX, t.TerrainData.Geometry.HeightMap);
FetchWorldDataMaterial.SetVector(BOUNDS, bounds);
GCommon.DrawQuad(simulationData, uvCorner, FetchWorldDataMaterial, PASS_HEIGHT);
FetchWorldDataMaterial.SetTexture(MAIN_TEX, t.TerrainData.Mask.MaskMapOrDefault);
FetchWorldDataMaterial.SetFloat(ENABLE_TERRAIN_MASK, Simulator.EnableTerrainMask ? 1 : 0);
GCommon.DrawQuad(simulationMask, uvCorner, FetchWorldDataMaterial, PASS_MASK);
}
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 86aab2e244bf1574f90567999541473c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,304 @@
#if GRIFFIN
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Griffin.ErosionTool
{
[ExecuteInEditMode]
public class GErosionSimulator : MonoBehaviour
{
[SerializeField]
private int groupId;
public int GroupId
{
get
{
return groupId;
}
set
{
groupId = value;
}
}
[SerializeField]
private bool enableTerrainMask;
public bool EnableTerrainMask
{
get
{
return enableTerrainMask;
}
set
{
enableTerrainMask = value;
}
}
[SerializeField]
private AnimationCurve falloffCurve;
public AnimationCurve FalloffCurve
{
get
{
if (falloffCurve == null)
{
falloffCurve = AnimationCurve.Linear(0, 1, 1, 1);
}
return falloffCurve;
}
set
{
falloffCurve = value;
}
}
[SerializeField]
private float detailLevel;
public float DetailLevel
{
get
{
return detailLevel;
}
set
{
detailLevel = Mathf.Clamp(value, 0.2f, 2f);
}
}
[SerializeField]
private GHydraulicErosionConfigs hydraulicConfigs;
public GHydraulicErosionConfigs HydraulicConfigs
{
get
{
return hydraulicConfigs;
}
set
{
hydraulicConfigs = value;
}
}
[SerializeField]
private GThermalErosionConfigs thermalConfigs;
public GThermalErosionConfigs ThermalConfigs
{
get
{
return thermalConfigs;
}
set
{
thermalConfigs = value;
}
}
[SerializeField]
private GErosionTexturingConfigs texturingConfigs;
public GErosionTexturingConfigs TexturingConfigs
{
get
{
return texturingConfigs;
}
set
{
texturingConfigs = value;
}
}
private RenderTexture simulationData;
public RenderTexture SimulationData
{
get
{
return simulationData;
}
}
private RenderTexture simulationMask;
public RenderTexture SimulationMask
{
get
{
return simulationMask;
}
}
private RenderTexture erosionMap;
public RenderTexture ErosionMap
{
get
{
return erosionMap;
}
}
private Texture2D falloffTexture;
public Texture2D FalloffTexture
{
get
{
return falloffTexture;
}
}
private Vector3 bounds;
public Vector3 Bounds
{
get
{
return bounds;
}
}
private void Reset()
{
groupId = -1;
enableTerrainMask = false;
falloffCurve = AnimationCurve.Linear(0, 1, 1, 0);
detailLevel = 0.5f;
hydraulicConfigs = new GHydraulicErosionConfigs();
thermalConfigs = new GThermalErosionConfigs();
texturingConfigs = new GErosionTexturingConfigs();
}
private void OnEnable()
{
UpdateFalloffTexture();
Initialize();
}
private void OnDisable()
{
CleanUp();
}
public void Initialize()
{
GErosionInitializer initializer = new GErosionInitializer(this);
initializer.Init(ref bounds, ref simulationData, ref simulationMask, ref erosionMap);
}
public void CleanUp()
{
if (simulationData != null)
{
simulationData.Release();
simulationData = null;
}
if (simulationMask != null)
{
simulationMask.Release();
simulationMask = null;
}
if (erosionMap != null)
{
erosionMap.Release();
erosionMap = null;
}
if (falloffTexture != null)
{
GUtilities.DestroyObject(falloffTexture);
}
}
public void SimulateHydraulicErosion()
{
GHydraulicEroder eroder = new GHydraulicEroder(this);
eroder.Init();
int iteration = HydraulicConfigs.IterationCount;
for (int i = 0; i < iteration; ++i)
{
float t = i * 1.0f / iteration;
eroder.WaterSourceAmount = HydraulicConfigs.WaterSourceAmount * HydraulicConfigs.WaterSourceOverTime.Evaluate(t) * HydraulicConfigs.WaterSourceMultiplier;
eroder.RainRate = HydraulicConfigs.RainRate * HydraulicConfigs.RainOverTime.Evaluate(t) * HydraulicConfigs.RainMultiplier;
eroder.FlowRate = HydraulicConfigs.FlowRate * HydraulicConfigs.FlowOverTime.Evaluate(t) * HydraulicConfigs.FlowMultiplier;
eroder.ErosionRate = HydraulicConfigs.ErosionRate * HydraulicConfigs.ErosionOverTime.Evaluate(t) * HydraulicConfigs.ErosionMultiplier;
eroder.DepositionRate = HydraulicConfigs.DepositionRate * HydraulicConfigs.DepositionOverTime.Evaluate(t) * HydraulicConfigs.DepositionMultiplier;
eroder.EvaporationRate = HydraulicConfigs.EvaporationRate * HydraulicConfigs.EvaporationOverTime.Evaluate(t) * HydraulicConfigs.EvaporationMultiplier;
eroder.Bounds = Bounds;
eroder.Simulate();
}
eroder.Dispose();
}
public void SimulateThermalErosion()
{
GThermalEroder eroder = new GThermalEroder(this);
eroder.Init();
int iteration = ThermalConfigs.IterationCount;
for (int i = 0; i < iteration; ++i)
{
float t = i * 1.0f / iteration;
eroder.MaskMap = SimulationMask;
eroder.ErosionRate = ThermalConfigs.ErosionRate * ThermalConfigs.ErosionOverTime.Evaluate(t) * ThermalConfigs.ErosionMultiplier;
eroder.RestingAngle = ThermalConfigs.RestingAngle * ThermalConfigs.RestingAngleOverTime.Evaluate(t) * ThermalConfigs.RestingAngleMultiplier;
eroder.Bounds = Bounds;
eroder.Simulate();
}
eroder.Dispose();
}
public void ApplyGeometry()
{
GErosionApplier applier = new GErosionApplier(this);
applier.ApplyGeometry();
}
public void ApplyTexture()
{
GErosionApplier applier = new GErosionApplier(this);
if (TexturingConfigs.TexturingMode == GErosionTexturingConfigs.GMode.Splat)
{
applier.ApplySplat();
}
else
{
applier.ApplyAMS();
}
}
public List<GStylizedTerrain> GetIntersectedTerrains()
{
Vector3[] worldCorner = GetQuad();
return GUtilities.ExtractTerrainsFromOverlapTest(GCommon.OverlapTest(GroupId, worldCorner));
}
public Vector3[] GetQuad()
{
Matrix4x4 matrix = Matrix4x4.TRS(transform.position, transform.rotation, transform.lossyScale);
Vector3[] quad = new Vector3[4]
{
matrix.MultiplyPoint(new Vector3(-0.5f, 0, -0.5f)),
matrix.MultiplyPoint(new Vector3(-0.5f, 0, 0.5f)),
matrix.MultiplyPoint(new Vector3(0.5f, 0, 0.5f)),
matrix.MultiplyPoint(new Vector3(0.5f, 0, -0.5f))
};
return quad;
}
public void UpdateFalloffTexture()
{
if (falloffTexture != null)
{
GUtilities.DestroyObject(falloffTexture);
}
falloffTexture = GCommon.CreateTextureFromCurve(FalloffCurve, 2048, 1);
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 6a34ef5b734b37c4b9946c0b06ed09cd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 300
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,217 @@
#if GRIFFIN
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Griffin.ErosionTool
{
[System.Serializable]
public class GErosionTexturingConfigs
{
public enum GMode
{
Splat, AlbedoMetallicSmoothness
}
[SerializeField]
private GMode texturingMode;
public GMode TexturingMode
{
get
{
return texturingMode;
}
set
{
texturingMode = value;
}
}
[SerializeField]
private float erosionIntensity;
public float ErosionIntensity
{
get
{
return erosionIntensity;
}
set
{
erosionIntensity = Mathf.Max(0, value);
}
}
[SerializeField]
private float erosionExponent;
public float ErosionExponent
{
get
{
return erosionExponent;
}
set
{
erosionExponent = Mathf.Max(0, value);
}
}
[SerializeField]
private int erosionSplatIndex;
public int ErosionSplatIndex
{
get
{
return erosionSplatIndex;
}
set
{
erosionSplatIndex = value;
}
}
[SerializeField]
private Color erosionAlbedo;
public Color ErosionAlbedo
{
get
{
return erosionAlbedo;
}
set
{
erosionAlbedo = value;
}
}
[SerializeField]
private float erosionMetallic;
public float ErosionMetallic
{
get
{
return erosionMetallic;
}
set
{
erosionMetallic = Mathf.Clamp01(value);
}
}
[SerializeField]
private float erosionSmoothness;
public float ErosionSmoothness
{
get
{
return erosionSmoothness;
}
set
{
erosionSmoothness = Mathf.Clamp01(value);
}
}
[SerializeField]
private float depositionIntensity;
public float DepositionIntensity
{
get
{
return depositionIntensity;
}
set
{
depositionIntensity = Mathf.Max(0, value);
}
}
[SerializeField]
private float depositionExponent;
public float DepositionExponent
{
get
{
return depositionExponent;
}
set
{
depositionExponent = Mathf.Max(0, value);
}
}
[SerializeField]
private int depositionSplatIndex;
public int DepositionSplatIndex
{
get
{
return depositionSplatIndex;
}
set
{
depositionSplatIndex = value;
}
}
[SerializeField]
private Color depositionAlbedo;
public Color DepositionAlbedo
{
get
{
return depositionAlbedo;
}
set
{
depositionAlbedo = value;
}
}
[SerializeField]
private float depositionMetallic;
public float DepositionMetallic
{
get
{
return depositionMetallic;
}
set
{
depositionMetallic = Mathf.Clamp01(value);
}
}
[SerializeField]
private float depositionSmoothness;
public float DepositionSmoothness
{
get
{
return depositionSmoothness;
}
set
{
depositionSmoothness = Mathf.Clamp01(value);
}
}
public GErosionTexturingConfigs()
{
texturingMode = GMode.Splat;
erosionIntensity = 1;
erosionExponent = 1;
erosionSplatIndex = 0;
erosionAlbedo = Color.red;
erosionMetallic = 0;
erosionSmoothness = 0;
depositionIntensity = 1;
depositionExponent = 1;
depositionSplatIndex = 0;
depositionAlbedo = Color.green;
depositionMetallic = 0;
depositionSmoothness = 0;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 9c6ea88855713b54782e8969d7a64b9c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,132 @@
#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

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3a2490ff026c0604c8259c026c1bfdc4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,331 @@
#if GRIFFIN
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Griffin.ErosionTool
{
[System.Serializable]
public class GHydraulicErosionConfigs
{
[SerializeField]
private float waterSourceAmount;
public float WaterSourceAmount
{
get
{
return waterSourceAmount;
}
set
{
waterSourceAmount = Mathf.Max(0, value);
}
}
[SerializeField]
private AnimationCurve waterSourceOverTime;
public AnimationCurve WaterSourceOverTime
{
get
{
if (waterSourceOverTime == null)
{
waterSourceOverTime = AnimationCurve.Linear(0, 1, 1, 1);
}
return waterSourceOverTime;
}
set
{
waterSourceOverTime = value;
}
}
[SerializeField]
private float waterSourceMultiplier;
public float WaterSourceMultiplier
{
get
{
return waterSourceMultiplier;
}
set
{
waterSourceMultiplier = Mathf.Max(0, value);
}
}
[SerializeField]
private float rainRate;
public float RainRate
{
get
{
return rainRate;
}
set
{
rainRate = Mathf.Max(0, value);
}
}
[SerializeField]
private AnimationCurve rainOverTime;
public AnimationCurve RainOverTime
{
get
{
if (rainOverTime == null)
{
rainOverTime = AnimationCurve.Linear(0, 1, 1, 1);
}
return rainOverTime;
}
set
{
rainOverTime = value;
}
}
[SerializeField]
private float rainMultiplier;
public float RainMultiplier
{
get
{
return rainMultiplier;
}
set
{
rainMultiplier = Mathf.Max(0, value);
}
}
[SerializeField]
private float flowRate;
public float FlowRate
{
get
{
return flowRate;
}
set
{
flowRate = Mathf.Max(0, value);
}
}
[SerializeField]
private AnimationCurve flowOverTime;
public AnimationCurve FlowOverTime
{
get
{
if (flowOverTime == null)
{
flowOverTime = AnimationCurve.Linear(0, 1, 1, 1);
}
return flowOverTime;
}
set
{
flowOverTime = value;
}
}
[SerializeField]
private float flowMultiplier;
public float FlowMultiplier
{
get
{
return flowMultiplier;
}
set
{
flowMultiplier = Mathf.Max(0, value);
}
}
[SerializeField]
private float erosionRate;
public float ErosionRate
{
get
{
return erosionRate;
}
set
{
erosionRate = Mathf.Max(0, value);
}
}
[SerializeField]
private AnimationCurve erosionOverTime;
public AnimationCurve ErosionOverTime
{
get
{
if (erosionOverTime == null)
{
erosionOverTime = AnimationCurve.Linear(0, 1, 1, 1);
}
return erosionOverTime;
}
set
{
erosionOverTime = value;
}
}
[SerializeField]
private float erosionMultiplier;
public float ErosionMultiplier
{
get
{
return erosionMultiplier;
}
set
{
erosionMultiplier = Mathf.Max(0, value);
}
}
[SerializeField]
private float depositionRate;
public float DepositionRate
{
get
{
return depositionRate;
}
set
{
depositionRate = Mathf.Max(0, value);
}
}
[SerializeField]
private AnimationCurve depositionOverTime;
public AnimationCurve DepositionOverTime
{
get
{
if (depositionOverTime == null)
{
depositionOverTime = AnimationCurve.Linear(0, 1, 1, 1);
}
return depositionOverTime;
}
set
{
depositionOverTime = value;
}
}
[SerializeField]
private float depositionMultiplier;
public float DepositionMultiplier
{
get
{
return depositionMultiplier;
}
set
{
depositionMultiplier = Mathf.Max(0, value);
}
}
[SerializeField]
private float evaporationRate;
public float EvaporationRate
{
get
{
return evaporationRate;
}
set
{
evaporationRate = Mathf.Max(0, value);
}
}
[SerializeField]
private AnimationCurve evaporationOverTime;
public AnimationCurve EvaporationOverTime
{
get
{
if (evaporationOverTime == null)
{
evaporationOverTime = AnimationCurve.Linear(0, 1, 1, 1);
}
return evaporationOverTime;
}
set
{
evaporationOverTime = value;
}
}
[SerializeField]
private float evaporationMultiplier;
public float EvaporationMultiplier
{
get
{
return evaporationMultiplier;
}
set
{
evaporationMultiplier = Mathf.Max(0, value);
}
}
[SerializeField]
private int iterationCount;
public int IterationCount
{
get
{
return iterationCount;
}
set
{
iterationCount = Mathf.Max(0, value);
}
}
public GHydraulicErosionConfigs()
{
waterSourceAmount = 0;
waterSourceOverTime = AnimationCurve.Linear(0, 1, 1, 1);
waterSourceMultiplier = 1;
rainRate = 0.075f;
rainOverTime = AnimationCurve.Linear(0, 1, 1, 1);
rainMultiplier = 1;
flowRate = 1;
flowOverTime = AnimationCurve.Linear(0, 1, 1, 1);
flowMultiplier = 1;
erosionRate = 0.3f;
erosionOverTime = AnimationCurve.Linear(0, 1, 1, 1);
erosionMultiplier = 1;
depositionRate = 0.075f;
depositionOverTime = AnimationCurve.Linear(0, 1, 1, 1);
depositionMultiplier = 1;
evaporationRate = 0.03f;
evaporationOverTime = AnimationCurve.Linear(0, 1, 1, 1);
evaporationMultiplier = 1;
iterationCount = 500;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f98fbb6625a892947ae571ec81d6bc90
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,105 @@
#if GRIFFIN
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
namespace Pinwheel.Griffin.ErosionTool
{
public class GThermalEroder : IDisposable
{
public GErosionSimulator Simulator { get; private set; }
public Texture MaskMap { get; set; }
public float ErosionRate { get; set; }
public float RestingAngle { get; set; }
public Vector3 Bounds { get; set; }
private RenderTexture soilVHData;
private RenderTexture soilDiagData;
private static readonly int SIMULATION_DATA = Shader.PropertyToID("_SimulationData");
private static readonly int EROSION_MAP = Shader.PropertyToID("_ErosionMap");
private static readonly int SOIL_VH_DATA = Shader.PropertyToID("_SoilVHData");
private static readonly int SOIL_DIAG_DATA = Shader.PropertyToID("_SoilDiagData");
private static readonly int MASK_MAP = Shader.PropertyToID("_MaskMap");
private static readonly int MASK_MAP_RESOLUTION = Shader.PropertyToID("_MaskMapResolution");
private static readonly int EROSION_RATE = Shader.PropertyToID("_ErosionRate");
private static readonly int RESTING_ANGLE = Shader.PropertyToID("_RestingAngle");
private static readonly int BOUNDS = Shader.PropertyToID("_Bounds");
private static readonly int KERNEL_INDEX = 0;
private bool initialized;
public GThermalEroder(GErosionSimulator s)
{
Simulator = s;
}
public void Init()
{
int width = Simulator.SimulationData.width;
int height = Simulator.SimulationData.height;
soilVHData = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
soilVHData.enableRandomWrite = true;
soilVHData.wrapMode = TextureWrapMode.Clamp;
soilVHData.Create();
soilDiagData = new RenderTexture(width, height, 0, RenderTextureFormat.ARGBFloat, RenderTextureReadWrite.Linear);
soilDiagData.enableRandomWrite = true;
soilDiagData.wrapMode = TextureWrapMode.Clamp;
soilDiagData.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.thermalErosionShader;
shader.SetTexture(KERNEL_INDEX, SIMULATION_DATA, Simulator.SimulationData);
shader.SetTexture(KERNEL_INDEX, EROSION_MAP, Simulator.ErosionMap);
shader.SetTexture(KERNEL_INDEX, SOIL_VH_DATA, soilVHData);
shader.SetTexture(KERNEL_INDEX, SOIL_DIAG_DATA, soilDiagData);
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.SetFloat(EROSION_RATE, ErosionRate);
shader.SetFloat(RESTING_ANGLE, RestingAngle);
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 (soilVHData != null)
{
soilVHData.Release();
soilVHData = null;
}
if (soilDiagData != null)
{
soilDiagData.Release();
soilDiagData = null;
}
initialized = false;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fb16d1de9b4e5b042803d7072569e9bf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,131 @@
#if GRIFFIN
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
namespace Pinwheel.Griffin.ErosionTool
{
[System.Serializable]
public class GThermalErosionConfigs
{
[SerializeField]
private float erosionRate;
public float ErosionRate
{
get
{
return erosionRate;
}
set
{
erosionRate = Mathf.Max(0, value);
}
}
[SerializeField]
private AnimationCurve erosionOverTime;
public AnimationCurve ErosionOverTime
{
get
{
if (erosionOverTime == null)
{
erosionOverTime = AnimationCurve.Linear(0, 1, 1, 1);
}
return erosionOverTime;
}
set
{
erosionOverTime = value;
}
}
[SerializeField]
private float erosionMultiplier;
public float ErosionMultiplier
{
get
{
return erosionMultiplier;
}
set
{
erosionMultiplier = Mathf.Max(0, value);
}
}
[SerializeField]
private float restingAngle;
public float RestingAngle
{
get
{
return restingAngle;
}
set
{
restingAngle = Mathf.Clamp(value, 0f, 90f);
}
}
[SerializeField]
private AnimationCurve restingAngleOverTime;
public AnimationCurve RestingAngleOverTime
{
get
{
if (restingAngleOverTime == null)
{
restingAngleOverTime = AnimationCurve.Linear(0, 1, 1, 1);
}
return restingAngleOverTime;
}
set
{
restingAngleOverTime = value;
}
}
[SerializeField]
private float restingAngleMultiplier;
public float RestingAngleMultiplier
{
get
{
return restingAngleMultiplier;
}
set
{
restingAngleMultiplier = Mathf.Max(0, value);
}
}
[SerializeField]
private int iterationCount;
public int IterationCount
{
get
{
return iterationCount;
}
set
{
iterationCount = value;
}
}
public GThermalErosionConfigs()
{
erosionRate = 0.1f;
erosionOverTime = AnimationCurve.Linear(0, 1, 1, 1);
erosionMultiplier = 1f;
restingAngle = 30f;
restingAngleOverTime = AnimationCurve.Linear(0, 1, 1, 1);
restingAngleMultiplier = 1f;
iterationCount = 10;
}
}
}
#endif

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8d4ff87008bb3914f9250cf6f31d75f2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: