├── .gitignore ├── Assets ├── Materials.meta ├── Materials │ ├── InitHeightmap.mat │ ├── InitHeightmap.mat.meta │ ├── Skybox.mat │ ├── Skybox.mat.meta │ ├── Terrain.mat │ ├── Terrain.mat.meta │ ├── Water.mat │ ├── Water.mat.meta │ ├── WaterBoundary.mat │ ├── WaterBoundary.mat.meta │ ├── default.mat │ └── default.mat.meta ├── Scenes.meta ├── Scenes │ ├── CustomTerrain.meta │ ├── CustomTerrain │ │ ├── CustomTerrain.meta │ │ ├── CustomTerrain.unity │ │ ├── CustomTerrain.unity.meta │ │ └── CustomTerrain │ │ │ ├── LightingData.asset │ │ │ ├── LightingData.asset.meta │ │ │ ├── ReflectionProbe-0.exr │ │ │ └── ReflectionProbe-0.exr.meta │ ├── UnityTerrain.meta │ └── UnityTerrain │ │ ├── NewBrush.brush │ │ ├── NewBrush.brush.meta │ │ ├── NewLayer.terrainlayer │ │ ├── NewLayer.terrainlayer.meta │ │ ├── UnityTerrain.asset │ │ ├── UnityTerrain.asset.meta │ │ ├── UnityTerrain.unity │ │ └── UnityTerrain.unity.meta ├── Scripts.meta ├── Scripts │ ├── ChunkedPlane.cs │ ├── ChunkedPlane.cs.meta │ ├── Simulation.cs │ ├── Simulation.cs.meta │ ├── UnityTerrainAdapter.cs │ ├── UnityTerrainAdapter.cs.meta │ ├── Utils.meta │ ├── Utils │ │ ├── Debugger.cs │ │ ├── Debugger.cs.meta │ │ ├── FixedSizeStack.cs │ │ ├── FixedSizeStack.cs.meta │ │ ├── FlyingCamera.cs │ │ ├── FlyingCamera.cs.meta │ │ ├── LazySingleton.cs │ │ ├── LazySingleton.cs.meta │ │ ├── MeshUtils.cs │ │ ├── MeshUtils.cs.meta │ │ ├── ShowRendererBounds.cs │ │ └── ShowRendererBounds.cs.meta │ ├── WaterBoundary.cs │ └── WaterBoundary.cs.meta ├── Shaders.meta ├── Shaders │ ├── Erosion.compute │ ├── Erosion.compute.meta │ ├── InitHeightmap.shader │ ├── InitHeightmap.shader.meta │ ├── StateCopy.shader │ ├── StateCopy.shader.meta │ ├── Surface.shader │ ├── Surface.shader.meta │ ├── Water.shader │ ├── Water.shader.meta │ ├── WaterBoundary.shader │ └── WaterBoundary.shader.meta ├── Textures.meta └── Textures │ ├── Noise.meta │ ├── Noise │ ├── perlin_1.png │ └── perlin_1.png.meta │ ├── Skyboxes.meta │ ├── Skyboxes │ ├── skybox_1.hdr │ └── skybox_1.hdr.meta │ ├── heightmap_2.png │ ├── heightmap_2.png.meta │ ├── normal.jpg │ ├── normal.jpg.meta │ ├── terrain.jpg │ └── terrain.jpg.meta ├── LICENSE ├── Logs └── Packages-Update.log ├── Packages └── manifest.json ├── ProjectSettings ├── AudioManager.asset ├── ClusterInputManager.asset ├── DynamicsManager.asset ├── EditorBuildSettings.asset ├── EditorSettings.asset ├── GraphicsSettings.asset ├── InputManager.asset ├── NavMeshAreas.asset ├── Physics2DSettings.asset ├── PresetManager.asset ├── ProjectSettings.asset ├── ProjectVersion.txt ├── QualitySettings.asset ├── TagManager.asset ├── TimeManager.asset ├── UnityConnectSettings.asset ├── VFXManager.asset └── XRSettings.asset ├── README.md └── Resources └── screen1.png /.gitignore: -------------------------------------------------------------------------------- 1 | [Ll]ibrary/ 2 | [Tt]emp/ 3 | [Oo]bj/ 4 | [Bb]uild/ 5 | [Bb]uilds/ 6 | Assets/AssetStoreTools* 7 | 8 | # Visual Studio cache directory 9 | .vs/ 10 | 11 | # Autogenerated VS/MD/Consulo solution and project files 12 | ExportedObj/ 13 | .consulo/ 14 | *.csproj 15 | *.unityproj 16 | *.sln 17 | *.suo 18 | *.tmp 19 | *.user 20 | *.userprefs 21 | *.pidb 22 | *.booproj 23 | *.svd 24 | *.pdb 25 | *.opendb 26 | 27 | # Unity3D generated meta files 28 | *.pidb.meta 29 | *.pdb.meta 30 | 31 | # Unity3D Generated File On Crash Reports 32 | sysinfo.txt 33 | 34 | # Builds 35 | *.apk 36 | *.unitypackage 37 | 38 | 39 | .idea/ -------------------------------------------------------------------------------- /Assets/Materials.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f59f20e989aae794baa35bc16ad4ec1c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/InitHeightmap.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: InitHeightmap 11 | m_Shader: {fileID: 4800000, guid: 4697a06caf91b774db1e1b797db9cb3c, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _Hardness: 43 | m_Texture: {fileID: 2800000, guid: f0773f3e799c5f247889ff2d8e9bd3ac, type: 3} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MainTex: 47 | m_Texture: {fileID: 2800000, guid: 43149b43056f9c340b49f9a408fc3284, type: 3} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _MetallicGlossMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _OcclusionMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _ParallaxMap: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | m_Floats: 63 | - _Bias: 5 64 | - _BumpScale: 1 65 | - _Cutoff: 0.5 66 | - _DetailNormalMapScale: 1 67 | - _DstBlend: 0 68 | - _GlossMapScale: 1 69 | - _Glossiness: 0.5 70 | - _GlossyReflections: 1 71 | - _Metallic: 0 72 | - _Mode: 0 73 | - _OcclusionStrength: 1 74 | - _Parallax: 0.02 75 | - _Scale: 50 76 | - _SeaLevel: 30 77 | - _SmoothnessTextureChannel: 0 78 | - _SpecularHighlights: 1 79 | - _SrcBlend: 1 80 | - _UVSec: 0 81 | - _ZWrite: 1 82 | m_Colors: 83 | - _Color: {r: 1, g: 1, b: 1, a: 1} 84 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 85 | -------------------------------------------------------------------------------- /Assets/Materials/InitHeightmap.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a1079684b02cda94a9a601a811134170 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/Skybox.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Skybox 11 | m_Shader: {fileID: 103, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: _SUNDISK_HIGH_QUALITY 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BackTex: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _BumpMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailAlbedoMap: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailMask: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _DetailNormalMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _DownTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _EmissionMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _FrontTex: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _LeftTex: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _MainTex: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | - _MetallicGlossMap: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | - _OcclusionMap: 67 | m_Texture: {fileID: 0} 68 | m_Scale: {x: 1, y: 1} 69 | m_Offset: {x: 0, y: 0} 70 | - _ParallaxMap: 71 | m_Texture: {fileID: 0} 72 | m_Scale: {x: 1, y: 1} 73 | m_Offset: {x: 0, y: 0} 74 | - _RightTex: 75 | m_Texture: {fileID: 0} 76 | m_Scale: {x: 1, y: 1} 77 | m_Offset: {x: 0, y: 0} 78 | - _Tex: 79 | m_Texture: {fileID: 8900000, guid: fa334c0fbccbdd14ea92ede1bd93db39, type: 3} 80 | m_Scale: {x: 1, y: 1} 81 | m_Offset: {x: 0, y: 0} 82 | - _UpTex: 83 | m_Texture: {fileID: 0} 84 | m_Scale: {x: 1, y: 1} 85 | m_Offset: {x: 0, y: 0} 86 | m_Floats: 87 | - _AtmosphereThickness: 1 88 | - _BumpScale: 1 89 | - _Cutoff: 0.5 90 | - _DetailNormalMapScale: 1 91 | - _DstBlend: 0 92 | - _Exposure: 0.53 93 | - _GlossMapScale: 1 94 | - _Glossiness: 0.5 95 | - _GlossyReflections: 1 96 | - _Metallic: 0 97 | - _Mode: 0 98 | - _OcclusionStrength: 1 99 | - _Parallax: 0.02 100 | - _Rotation: 0 101 | - _SmoothnessTextureChannel: 0 102 | - _SpecularHighlights: 1 103 | - _SrcBlend: 1 104 | - _SunDisk: 2 105 | - _SunSize: 0.04 106 | - _SunSizeConvergence: 5 107 | - _UVSec: 0 108 | - _ZWrite: 1 109 | m_Colors: 110 | - _Color: {r: 1, g: 1, b: 1, a: 1} 111 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 112 | - _GroundColor: {r: 0.369, g: 0.349, b: 0.341, a: 1} 113 | - _SkyTint: {r: 0.5, g: 0.5, b: 0.5, a: 1} 114 | - _Tint: {r: 1, g: 1, b: 1, a: 0.5} 115 | -------------------------------------------------------------------------------- /Assets/Materials/Skybox.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 664043a4fef6e6946b358906d45f367a 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/Terrain.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Terrain 11 | m_Shader: {fileID: 4800000, guid: a116650e46f9f3148a1f6d5c4d29be51, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 2800000, guid: f83c8dcb5e7a5924b95ab2326089ed33, type: 3} 44 | m_Scale: {x: 20, y: 20} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _NormalMap: 51 | m_Texture: {fileID: 2800000, guid: c361846caaf3e5741be99ab86a6faffc, type: 3} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _OcclusionMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _ParallaxMap: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | - _StateTex: 63 | m_Texture: {fileID: 0} 64 | m_Scale: {x: 1, y: 1} 65 | m_Offset: {x: 0, y: 0} 66 | m_Floats: 67 | - _BumpScale: 1 68 | - _Cutoff: 0.5 69 | - _DetailNormalMapScale: 1 70 | - _DstBlend: 0 71 | - _GlossMapScale: 1 72 | - _Glossiness: 0.5 73 | - _GlossyReflections: 1 74 | - _Metallic: 0 75 | - _Mode: 0 76 | - _NormalStrength: 2 77 | - _OcclusionStrength: 1 78 | - _Parallax: 0.02 79 | - _SampleSize: 0.0016 80 | - _SmoothnessTextureChannel: 0 81 | - _SpecularHighlights: 1 82 | - _SrcBlend: 1 83 | - _UVSec: 0 84 | - _ZWrite: 1 85 | m_Colors: 86 | - _Color: {r: 1, g: 1, b: 1, a: 1} 87 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 88 | -------------------------------------------------------------------------------- /Assets/Materials/Terrain.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1cf9e6530b1beb341b6ecccf254cf279 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/Water.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: Water 11 | m_Shader: {fileID: 4800000, guid: 26265a6f920893341be359ac6c3dc795, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _StateTex: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | m_Floats: 63 | - _BumpScale: 1 64 | - _Cutoff: 0.5 65 | - _DepthDecay: 0.06 66 | - _DetailNormalMapScale: 1 67 | - _DstBlend: 0 68 | - _GlossMapScale: 1 69 | - _Glossiness: 0.5 70 | - _GlossyReflections: 1 71 | - _Metallic: 0 72 | - _Mode: 0 73 | - _NormalStrength: 1 74 | - _OcclusionStrength: 1 75 | - _Parallax: 0.02 76 | - _SampleSize: 0.0078125 77 | - _Smoothness: 1 78 | - _SmoothnessTextureChannel: 0 79 | - _SpecularHighlights: 1 80 | - _SrcBlend: 1 81 | - _UVSec: 0 82 | - _ZWrite: 1 83 | m_Colors: 84 | - _Color: {r: 0.0017799971, g: 0.21828997, b: 0.3773585, a: 1} 85 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 86 | -------------------------------------------------------------------------------- /Assets/Materials/Water.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4dc86583f8ebc4d44be01aada5cc6c14 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/WaterBoundary.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: WaterBoundary 11 | m_Shader: {fileID: 4800000, guid: c5e7ca4a9f5fa9a48b096e67508a921e, type: 3} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | - _StateTex: 59 | m_Texture: {fileID: 0} 60 | m_Scale: {x: 1, y: 1} 61 | m_Offset: {x: 0, y: 0} 62 | m_Floats: 63 | - _BumpScale: 1 64 | - _Cutoff: 0.5 65 | - _DepthDecay: 1 66 | - _DetailNormalMapScale: 1 67 | - _DstBlend: 0 68 | - _GlossMapScale: 1 69 | - _Glossiness: 0.5 70 | - _GlossyReflections: 1 71 | - _Metallic: 0 72 | - _Mode: 0 73 | - _NormalStrength: 1.9 74 | - _OcclusionStrength: 1 75 | - _Parallax: 0.02 76 | - _Smoothness: 0 77 | - _SmoothnessTextureChannel: 0 78 | - _SpecularHighlights: 1 79 | - _SrcBlend: 1 80 | - _UVSec: 0 81 | - _ZWrite: 1 82 | m_Colors: 83 | - _Color: {r: 0, g: 0.08360688, b: 0.1981132, a: 0.85882354} 84 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 85 | -------------------------------------------------------------------------------- /Assets/Materials/WaterBoundary.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e72cc0628d750ef469589d7be7ed5d90 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Materials/default.mat: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!21 &2100000 4 | Material: 5 | serializedVersion: 6 6 | m_ObjectHideFlags: 0 7 | m_CorrespondingSourceObject: {fileID: 0} 8 | m_PrefabInstance: {fileID: 0} 9 | m_PrefabAsset: {fileID: 0} 10 | m_Name: default 11 | m_Shader: {fileID: 46, guid: 0000000000000000f000000000000000, type: 0} 12 | m_ShaderKeywords: 13 | m_LightmapFlags: 4 14 | m_EnableInstancingVariants: 0 15 | m_DoubleSidedGI: 0 16 | m_CustomRenderQueue: -1 17 | stringTagMap: {} 18 | disabledShaderPasses: [] 19 | m_SavedProperties: 20 | serializedVersion: 3 21 | m_TexEnvs: 22 | - _BumpMap: 23 | m_Texture: {fileID: 0} 24 | m_Scale: {x: 1, y: 1} 25 | m_Offset: {x: 0, y: 0} 26 | - _DetailAlbedoMap: 27 | m_Texture: {fileID: 0} 28 | m_Scale: {x: 1, y: 1} 29 | m_Offset: {x: 0, y: 0} 30 | - _DetailMask: 31 | m_Texture: {fileID: 0} 32 | m_Scale: {x: 1, y: 1} 33 | m_Offset: {x: 0, y: 0} 34 | - _DetailNormalMap: 35 | m_Texture: {fileID: 0} 36 | m_Scale: {x: 1, y: 1} 37 | m_Offset: {x: 0, y: 0} 38 | - _EmissionMap: 39 | m_Texture: {fileID: 0} 40 | m_Scale: {x: 1, y: 1} 41 | m_Offset: {x: 0, y: 0} 42 | - _MainTex: 43 | m_Texture: {fileID: 0} 44 | m_Scale: {x: 1, y: 1} 45 | m_Offset: {x: 0, y: 0} 46 | - _MetallicGlossMap: 47 | m_Texture: {fileID: 0} 48 | m_Scale: {x: 1, y: 1} 49 | m_Offset: {x: 0, y: 0} 50 | - _OcclusionMap: 51 | m_Texture: {fileID: 0} 52 | m_Scale: {x: 1, y: 1} 53 | m_Offset: {x: 0, y: 0} 54 | - _ParallaxMap: 55 | m_Texture: {fileID: 0} 56 | m_Scale: {x: 1, y: 1} 57 | m_Offset: {x: 0, y: 0} 58 | m_Floats: 59 | - _BumpScale: 1 60 | - _Cutoff: 0.5 61 | - _DetailNormalMapScale: 1 62 | - _DstBlend: 0 63 | - _GlossMapScale: 1 64 | - _Glossiness: 0.934 65 | - _GlossyReflections: 1 66 | - _Metallic: 0 67 | - _Mode: 0 68 | - _OcclusionStrength: 1 69 | - _Parallax: 0.02 70 | - _SmoothnessTextureChannel: 0 71 | - _SpecularHighlights: 1 72 | - _SrcBlend: 1 73 | - _UVSec: 0 74 | - _ZWrite: 1 75 | m_Colors: 76 | - _Color: {r: 0, g: 0, b: 0, a: 1} 77 | - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} 78 | -------------------------------------------------------------------------------- /Assets/Materials/default.mat.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 80d5618f4739ea243bcd801ae245215f 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 2100000 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4635f41468bd944409b4945020834454 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/CustomTerrain.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 832e56d3c3091b5499c0a6f1acd69363 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/CustomTerrain/CustomTerrain.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 2728cc64d87e2fc41989859851662092 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/CustomTerrain/CustomTerrain.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 2100000, guid: 664043a4fef6e6946b358906d45f367a, type: 2} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 1533200769} 41 | m_IndirectSpecularColor: {r: 0.55206954, g: 0.59798497, b: 0.62089014, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 1 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 1 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 512 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 256 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 1 83 | m_PVRDenoiserTypeDirect: 1 84 | m_PVRDenoiserTypeIndirect: 1 85 | m_PVRDenoiserTypeAO: 1 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 1 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 112000000, guid: ba0d52f63448df94daf38aa728be7fa5, 101 | type: 2} 102 | m_UseShadowmask: 1 103 | --- !u!196 &4 104 | NavMeshSettings: 105 | serializedVersion: 2 106 | m_ObjectHideFlags: 0 107 | m_BuildSettings: 108 | serializedVersion: 2 109 | agentTypeID: 0 110 | agentRadius: 0.5 111 | agentHeight: 2 112 | agentSlope: 45 113 | agentClimb: 0.4 114 | ledgeDropHeight: 0 115 | maxJumpAcrossDistance: 0 116 | minRegionArea: 2 117 | manualCellSize: 0 118 | cellSize: 0.16666667 119 | manualTileSize: 0 120 | tileSize: 256 121 | accuratePlacement: 0 122 | debug: 123 | m_Flags: 0 124 | m_NavMeshData: {fileID: 0} 125 | --- !u!1 &15452776 126 | GameObject: 127 | m_ObjectHideFlags: 0 128 | m_CorrespondingSourceObject: {fileID: 0} 129 | m_PrefabInstance: {fileID: 0} 130 | m_PrefabAsset: {fileID: 0} 131 | serializedVersion: 6 132 | m_Component: 133 | - component: {fileID: 15452778} 134 | - component: {fileID: 15452777} 135 | m_Layer: 0 136 | m_Name: TerrainAndWaterPlane 137 | m_TagString: Untagged 138 | m_Icon: {fileID: 0} 139 | m_NavMeshLayer: 0 140 | m_StaticEditorFlags: 0 141 | m_IsActive: 1 142 | --- !u!114 &15452777 143 | MonoBehaviour: 144 | m_ObjectHideFlags: 0 145 | m_CorrespondingSourceObject: {fileID: 0} 146 | m_PrefabInstance: {fileID: 0} 147 | m_PrefabAsset: {fileID: 0} 148 | m_GameObject: {fileID: 15452776} 149 | m_Enabled: 1 150 | m_EditorHideFlags: 0 151 | m_Script: {fileID: 11500000, guid: 94ab40bd34ad2074c9d904734c1a9c1f, type: 3} 152 | m_Name: 153 | m_EditorClassIdentifier: 154 | GenerateOnStart: 1 155 | Size: {x: 512, y: 100, z: 512} 156 | ChunksX: 16 157 | ChunksZ: 16 158 | LODSettings: 159 | - Size: 33 160 | ScreenHeight: 0.99999 161 | FadeTransitionWidth: 0.5 162 | IgnoreLodGroup: 0 163 | RenderSettings: 164 | ShadowCastingMode: 1 165 | ReceiveShadows: 1 166 | DynamicOccluded: 1 167 | - Size: 16 168 | ScreenHeight: 0.8 169 | FadeTransitionWidth: 0.5 170 | IgnoreLodGroup: 0 171 | RenderSettings: 172 | ShadowCastingMode: 1 173 | ReceiveShadows: 1 174 | DynamicOccluded: 1 175 | - Size: 8 176 | ScreenHeight: 0.361 177 | FadeTransitionWidth: 0.5 178 | IgnoreLodGroup: 0 179 | RenderSettings: 180 | ShadowCastingMode: 1 181 | ReceiveShadows: 1 182 | DynamicOccluded: 1 183 | - Size: 4 184 | ScreenHeight: 0 185 | FadeTransitionWidth: 0.5 186 | IgnoreLodGroup: 0 187 | RenderSettings: 188 | ShadowCastingMode: 1 189 | ReceiveShadows: 1 190 | DynamicOccluded: 1 191 | LodFadeMode: 2 192 | AnimateLodCrossFading: 0 193 | Materials: 194 | - {fileID: 2100000, guid: 1cf9e6530b1beb341b6ecccf254cf279, type: 2} 195 | - {fileID: 2100000, guid: 4dc86583f8ebc4d44be01aada5cc6c14, type: 2} 196 | InstantiateMaterials: 0 197 | --- !u!4 &15452778 198 | Transform: 199 | m_ObjectHideFlags: 0 200 | m_CorrespondingSourceObject: {fileID: 0} 201 | m_PrefabInstance: {fileID: 0} 202 | m_PrefabAsset: {fileID: 0} 203 | m_GameObject: {fileID: 15452776} 204 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 205 | m_LocalPosition: {x: 0, y: 0, z: 0} 206 | m_LocalScale: {x: 1, y: 1, z: 1} 207 | m_Children: [] 208 | m_Father: {fileID: 0} 209 | m_RootOrder: 3 210 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 211 | --- !u!1 &888575741 212 | GameObject: 213 | m_ObjectHideFlags: 0 214 | m_CorrespondingSourceObject: {fileID: 0} 215 | m_PrefabInstance: {fileID: 0} 216 | m_PrefabAsset: {fileID: 0} 217 | serializedVersion: 6 218 | m_Component: 219 | - component: {fileID: 888575745} 220 | - component: {fileID: 888575744} 221 | - component: {fileID: 888575743} 222 | - component: {fileID: 888575742} 223 | m_Layer: 0 224 | m_Name: Main Camera 225 | m_TagString: MainCamera 226 | m_Icon: {fileID: 0} 227 | m_NavMeshLayer: 0 228 | m_StaticEditorFlags: 0 229 | m_IsActive: 1 230 | --- !u!114 &888575742 231 | MonoBehaviour: 232 | m_ObjectHideFlags: 0 233 | m_CorrespondingSourceObject: {fileID: 0} 234 | m_PrefabInstance: {fileID: 0} 235 | m_PrefabAsset: {fileID: 0} 236 | m_GameObject: {fileID: 888575741} 237 | m_Enabled: 1 238 | m_EditorHideFlags: 0 239 | m_Script: {fileID: 11500000, guid: d6b0207ed7914c74191269f3bfb16d38, type: 3} 240 | m_Name: 241 | m_EditorClassIdentifier: 242 | MainSpeed: 100 243 | ShiftAdd: 250 244 | MaxShift: 1000 245 | MouseSensitivity: 0.25 246 | RotateOnlyIfMousedown: 1 247 | --- !u!81 &888575743 248 | AudioListener: 249 | m_ObjectHideFlags: 0 250 | m_CorrespondingSourceObject: {fileID: 0} 251 | m_PrefabInstance: {fileID: 0} 252 | m_PrefabAsset: {fileID: 0} 253 | m_GameObject: {fileID: 888575741} 254 | m_Enabled: 1 255 | --- !u!20 &888575744 256 | Camera: 257 | m_ObjectHideFlags: 0 258 | m_CorrespondingSourceObject: {fileID: 0} 259 | m_PrefabInstance: {fileID: 0} 260 | m_PrefabAsset: {fileID: 0} 261 | m_GameObject: {fileID: 888575741} 262 | m_Enabled: 1 263 | serializedVersion: 2 264 | m_ClearFlags: 1 265 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 266 | m_projectionMatrixMode: 1 267 | m_GateFitMode: 2 268 | m_FOVAxisMode: 0 269 | m_SensorSize: {x: 36, y: 24} 270 | m_LensShift: {x: 0, y: 0} 271 | m_FocalLength: 50 272 | m_NormalizedViewPortRect: 273 | serializedVersion: 2 274 | x: 0 275 | y: 0 276 | width: 1 277 | height: 1 278 | near clip plane: 0.3 279 | far clip plane: 1000 280 | field of view: 60 281 | orthographic: 0 282 | orthographic size: 5 283 | m_Depth: -1 284 | m_CullingMask: 285 | serializedVersion: 2 286 | m_Bits: 4294967295 287 | m_RenderingPath: 1 288 | m_TargetTexture: {fileID: 0} 289 | m_TargetDisplay: 0 290 | m_TargetEye: 3 291 | m_HDR: 1 292 | m_AllowMSAA: 1 293 | m_AllowDynamicResolution: 0 294 | m_ForceIntoRT: 0 295 | m_OcclusionCulling: 1 296 | m_StereoConvergence: 10 297 | m_StereoSeparation: 0.022 298 | --- !u!4 &888575745 299 | Transform: 300 | m_ObjectHideFlags: 0 301 | m_CorrespondingSourceObject: {fileID: 0} 302 | m_PrefabInstance: {fileID: 0} 303 | m_PrefabAsset: {fileID: 0} 304 | m_GameObject: {fileID: 888575741} 305 | m_LocalRotation: {x: 0.34716862, y: -0, z: -0, w: 0.9378028} 306 | m_LocalPosition: {x: 120.3, y: 152.3, z: -59.6} 307 | m_LocalScale: {x: 1, y: 1, z: 1} 308 | m_Children: [] 309 | m_Father: {fileID: 0} 310 | m_RootOrder: 0 311 | m_LocalEulerAnglesHint: {x: 40.628002, y: 0, z: 0} 312 | --- !u!1 &1416141037 313 | GameObject: 314 | m_ObjectHideFlags: 0 315 | m_CorrespondingSourceObject: {fileID: 0} 316 | m_PrefabInstance: {fileID: 0} 317 | m_PrefabAsset: {fileID: 0} 318 | serializedVersion: 6 319 | m_Component: 320 | - component: {fileID: 1416141039} 321 | - component: {fileID: 1416141038} 322 | m_Layer: 0 323 | m_Name: Simulation 324 | m_TagString: Untagged 325 | m_Icon: {fileID: 0} 326 | m_NavMeshLayer: 0 327 | m_StaticEditorFlags: 0 328 | m_IsActive: 1 329 | --- !u!114 &1416141038 330 | MonoBehaviour: 331 | m_ObjectHideFlags: 0 332 | m_CorrespondingSourceObject: {fileID: 0} 333 | m_PrefabInstance: {fileID: 0} 334 | m_PrefabAsset: {fileID: 0} 335 | m_GameObject: {fileID: 1416141037} 336 | m_Enabled: 1 337 | m_EditorHideFlags: 0 338 | m_Script: {fileID: 11500000, guid: 9dc03fd489a1eb04a9ae808ab1d54948, type: 3} 339 | m_Name: 340 | m_EditorClassIdentifier: 341 | Materials: 342 | - {fileID: 2100000, guid: 1cf9e6530b1beb341b6ecccf254cf279, type: 2} 343 | - {fileID: 2100000, guid: 4dc86583f8ebc4d44be01aada5cc6c14, type: 2} 344 | - {fileID: 2100000, guid: e72cc0628d750ef469589d7be7ed5d90, type: 2} 345 | ErosionComputeShader: {fileID: 7200000, guid: fcfc55914f9fdb646be1044044c2d042, 346 | type: 3} 347 | InitialState: {fileID: 2800000, guid: 43149b43056f9c340b49f9a408fc3284, type: 3} 348 | InitHeightMap: {fileID: 2100000, guid: a1079684b02cda94a9a601a811134170, type: 2} 349 | BrushAmount: 10 350 | InputMode: 0 351 | Width: 512 352 | Height: 512 353 | Settings: 354 | TimeScale: 1 355 | PipeLength: 1 356 | CellSize: {x: 1, y: 1} 357 | RainRate: 0 358 | Evaporation: 0 359 | PipeArea: 5 360 | Gravity: 9.81 361 | SedimentCapacity: 0.1 362 | SoilSuspensionRate: 0.8 363 | SedimentDepositionRate: 0.8 364 | SedimentSofteningRate: 5 365 | MaximalErosionDepth: 1 366 | ThermalErosionTimeScale: 20 367 | ThermalErosionRate: 1 368 | TalusAngleTangentCoeff: 0.6 369 | TalusAngleTangentBias: 0.2 370 | --- !u!4 &1416141039 371 | Transform: 372 | m_ObjectHideFlags: 0 373 | m_CorrespondingSourceObject: {fileID: 0} 374 | m_PrefabInstance: {fileID: 0} 375 | m_PrefabAsset: {fileID: 0} 376 | m_GameObject: {fileID: 1416141037} 377 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 378 | m_LocalPosition: {x: 0, y: 0, z: 0} 379 | m_LocalScale: {x: 1, y: 1, z: 1} 380 | m_Children: [] 381 | m_Father: {fileID: 0} 382 | m_RootOrder: 2 383 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 384 | --- !u!1 &1427476926 385 | GameObject: 386 | m_ObjectHideFlags: 0 387 | m_CorrespondingSourceObject: {fileID: 0} 388 | m_PrefabInstance: {fileID: 0} 389 | m_PrefabAsset: {fileID: 0} 390 | serializedVersion: 6 391 | m_Component: 392 | - component: {fileID: 1427476928} 393 | - component: {fileID: 1427476927} 394 | m_Layer: 0 395 | m_Name: WaterBoundaries 396 | m_TagString: Untagged 397 | m_Icon: {fileID: 0} 398 | m_NavMeshLayer: 0 399 | m_StaticEditorFlags: 0 400 | m_IsActive: 1 401 | --- !u!114 &1427476927 402 | MonoBehaviour: 403 | m_ObjectHideFlags: 0 404 | m_CorrespondingSourceObject: {fileID: 0} 405 | m_PrefabInstance: {fileID: 0} 406 | m_PrefabAsset: {fileID: 0} 407 | m_GameObject: {fileID: 1427476926} 408 | m_Enabled: 1 409 | m_EditorHideFlags: 0 410 | m_Script: {fileID: 11500000, guid: ebdd905ab35049e6b8ab362d30c0b560, type: 3} 411 | m_Name: 412 | m_EditorClassIdentifier: 413 | Size: {x: 512, y: 100, z: 512} 414 | Material: {fileID: 2100000, guid: e72cc0628d750ef469589d7be7ed5d90, type: 2} 415 | Resolution: {x: 512, y: 512} 416 | --- !u!4 &1427476928 417 | Transform: 418 | m_ObjectHideFlags: 0 419 | m_CorrespondingSourceObject: {fileID: 0} 420 | m_PrefabInstance: {fileID: 0} 421 | m_PrefabAsset: {fileID: 0} 422 | m_GameObject: {fileID: 1427476926} 423 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 424 | m_LocalPosition: {x: 0, y: 0, z: 0} 425 | m_LocalScale: {x: 1, y: 1, z: 1} 426 | m_Children: [] 427 | m_Father: {fileID: 0} 428 | m_RootOrder: 4 429 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 430 | --- !u!1 &1533200768 431 | GameObject: 432 | m_ObjectHideFlags: 0 433 | m_CorrespondingSourceObject: {fileID: 0} 434 | m_PrefabInstance: {fileID: 0} 435 | m_PrefabAsset: {fileID: 0} 436 | serializedVersion: 6 437 | m_Component: 438 | - component: {fileID: 1533200770} 439 | - component: {fileID: 1533200769} 440 | m_Layer: 0 441 | m_Name: Directional Light 442 | m_TagString: Untagged 443 | m_Icon: {fileID: 0} 444 | m_NavMeshLayer: 0 445 | m_StaticEditorFlags: 0 446 | m_IsActive: 1 447 | --- !u!108 &1533200769 448 | Light: 449 | m_ObjectHideFlags: 0 450 | m_CorrespondingSourceObject: {fileID: 0} 451 | m_PrefabInstance: {fileID: 0} 452 | m_PrefabAsset: {fileID: 0} 453 | m_GameObject: {fileID: 1533200768} 454 | m_Enabled: 1 455 | serializedVersion: 10 456 | m_Type: 1 457 | m_Shape: 0 458 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 459 | m_Intensity: 1 460 | m_Range: 10 461 | m_SpotAngle: 30 462 | m_InnerSpotAngle: 21.80208 463 | m_CookieSize: 10 464 | m_Shadows: 465 | m_Type: 2 466 | m_Resolution: -1 467 | m_CustomResolution: -1 468 | m_Strength: 1 469 | m_Bias: 0.15 470 | m_NormalBias: 0.4 471 | m_NearPlane: 0.2 472 | m_CullingMatrixOverride: 473 | e00: 1 474 | e01: 0 475 | e02: 0 476 | e03: 0 477 | e10: 0 478 | e11: 1 479 | e12: 0 480 | e13: 0 481 | e20: 0 482 | e21: 0 483 | e22: 1 484 | e23: 0 485 | e30: 0 486 | e31: 0 487 | e32: 0 488 | e33: 1 489 | m_UseCullingMatrixOverride: 0 490 | m_Cookie: {fileID: 0} 491 | m_DrawHalo: 0 492 | m_Flare: {fileID: 0} 493 | m_RenderMode: 0 494 | m_CullingMask: 495 | serializedVersion: 2 496 | m_Bits: 4294967295 497 | m_RenderingLayerMask: 1 498 | m_Lightmapping: 1 499 | m_LightShadowCasterMode: 0 500 | m_AreaSize: {x: 1, y: 1} 501 | m_BounceIntensity: 1 502 | m_ColorTemperature: 6570 503 | m_UseColorTemperature: 0 504 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 505 | m_UseBoundingSphereOverride: 0 506 | m_ShadowRadius: 0 507 | m_ShadowAngle: 0 508 | --- !u!4 &1533200770 509 | Transform: 510 | m_ObjectHideFlags: 0 511 | m_CorrespondingSourceObject: {fileID: 0} 512 | m_PrefabInstance: {fileID: 0} 513 | m_PrefabAsset: {fileID: 0} 514 | m_GameObject: {fileID: 1533200768} 515 | m_LocalRotation: {x: 0.39544383, y: -0.4993404, z: 0.5556995, w: 0.5343046} 516 | m_LocalPosition: {x: 0, y: 3, z: 0} 517 | m_LocalScale: {x: 1, y: 1, z: 1} 518 | m_Children: [] 519 | m_Father: {fileID: 0} 520 | m_RootOrder: 1 521 | m_LocalEulerAnglesHint: {x: 77.83401, y: -26.521002, z: 70.703} 522 | -------------------------------------------------------------------------------- /Assets/Scenes/CustomTerrain/CustomTerrain.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7ac57417042fa9b469a1820811e316af 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Scenes/CustomTerrain/CustomTerrain/LightingData.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/0e59f7c42b5ccbc8bc637b7a6435c3af648bc8b6/Assets/Scenes/CustomTerrain/CustomTerrain/LightingData.asset -------------------------------------------------------------------------------- /Assets/Scenes/CustomTerrain/CustomTerrain/LightingData.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ba0d52f63448df94daf38aa728be7fa5 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/CustomTerrain/CustomTerrain/ReflectionProbe-0.exr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/0e59f7c42b5ccbc8bc637b7a6435c3af648bc8b6/Assets/Scenes/CustomTerrain/CustomTerrain/ReflectionProbe-0.exr -------------------------------------------------------------------------------- /Assets/Scenes/CustomTerrain/CustomTerrain/ReflectionProbe-0.exr.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 29b8c95cf8dd9484bb73654ebcde6e6c 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 10 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 1 29 | seamlessCubemap: 1 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: 2 35 | aniso: 0 36 | mipBias: 0 37 | wrapU: 1 38 | wrapV: 1 39 | wrapW: 1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 2 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 3 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 100 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | forceMaximumCompressionQuality_BC6H_BC7: 0 73 | spriteSheet: 74 | serializedVersion: 2 75 | sprites: [] 76 | outline: [] 77 | physicsShape: [] 78 | bones: [] 79 | spriteID: 80 | internalID: 0 81 | vertices: [] 82 | indices: 83 | edges: [] 84 | weights: [] 85 | secondaryTextures: [] 86 | spritePackingTag: 87 | pSDRemoveMatte: 0 88 | pSDShowRemoveMatteOption: 0 89 | userData: 90 | assetBundleName: 91 | assetBundleVariant: 92 | -------------------------------------------------------------------------------- /Assets/Scenes/UnityTerrain.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 751b022485df58d46a4aa6fb0c53f05a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/UnityTerrain/NewBrush.brush: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!114 &11400000 4 | MonoBehaviour: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_GameObject: {fileID: 0} 10 | m_Enabled: 1 11 | m_EditorHideFlags: 0 12 | m_Script: {fileID: 12146, guid: 0000000000000000e000000000000000, type: 0} 13 | m_Name: NewBrush 14 | m_EditorClassIdentifier: 15 | m_Mask: {fileID: 2800000, guid: f83c8dcb5e7a5924b95ab2326089ed33, type: 3} 16 | m_Falloff: 17 | serializedVersion: 2 18 | m_Curve: 19 | - serializedVersion: 3 20 | time: 0 21 | value: 0 22 | inSlope: 0 23 | outSlope: 1 24 | tangentMode: 0 25 | weightedMode: 0 26 | inWeight: 0 27 | outWeight: 0 28 | - serializedVersion: 3 29 | time: 1 30 | value: 1 31 | inSlope: 1 32 | outSlope: 0 33 | tangentMode: 0 34 | weightedMode: 0 35 | inWeight: 0 36 | outWeight: 0 37 | m_PreInfinity: 2 38 | m_PostInfinity: 2 39 | m_RotationOrder: 4 40 | m_RadiusScale: 1.4849247 41 | m_BlackWhiteRemapMin: 0 42 | m_BlackWhiteRemapMax: 1 43 | m_InvertRemapRange: 0 44 | -------------------------------------------------------------------------------- /Assets/Scenes/UnityTerrain/NewBrush.brush.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4b3bb0b3d6d1a6c408d536d90cbed535 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/UnityTerrain/NewLayer.terrainlayer: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1953259897 &8574412962073106934 4 | TerrainLayer: 5 | m_ObjectHideFlags: 0 6 | m_CorrespondingSourceObject: {fileID: 0} 7 | m_PrefabInstance: {fileID: 0} 8 | m_PrefabAsset: {fileID: 0} 9 | m_Name: NewLayer 10 | m_DiffuseTexture: {fileID: 2800000, guid: f83c8dcb5e7a5924b95ab2326089ed33, type: 3} 11 | m_NormalMapTexture: {fileID: 0} 12 | m_MaskMapTexture: {fileID: 0} 13 | m_TileSize: {x: 20, y: 20} 14 | m_TileOffset: {x: 0, y: 0} 15 | m_Specular: {r: 0, g: 0, b: 0, a: 0} 16 | m_Metallic: 0 17 | m_Smoothness: 0 18 | m_NormalScale: 1 19 | m_DiffuseRemapMin: {x: 0, y: 0, z: 0, w: 0} 20 | m_DiffuseRemapMax: {x: 1, y: 1, z: 1, w: 1} 21 | m_MaskMapRemapMin: {x: 0, y: 0, z: 0, w: 0} 22 | m_MaskMapRemapMax: {x: 1, y: 1, z: 1, w: 1} 23 | -------------------------------------------------------------------------------- /Assets/Scenes/UnityTerrain/NewLayer.terrainlayer.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 60fb1b1637b95b74b87a4b0ffc2fffd9 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/UnityTerrain/UnityTerrain.asset: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/0e59f7c42b5ccbc8bc637b7a6435c3af648bc8b6/Assets/Scenes/UnityTerrain/UnityTerrain.asset -------------------------------------------------------------------------------- /Assets/Scenes/UnityTerrain/UnityTerrain.asset.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f7c510775dd5cdc44bec2c7395d856b8 3 | NativeFormatImporter: 4 | externalObjects: {} 5 | mainObjectFileID: 0 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scenes/UnityTerrain/UnityTerrain.unity: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!29 &1 4 | OcclusionCullingSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_OcclusionBakeSettings: 8 | smallestOccluder: 5 9 | smallestHole: 0.25 10 | backfaceThreshold: 100 11 | m_SceneGUID: 00000000000000000000000000000000 12 | m_OcclusionCullingData: {fileID: 0} 13 | --- !u!104 &2 14 | RenderSettings: 15 | m_ObjectHideFlags: 0 16 | serializedVersion: 9 17 | m_Fog: 0 18 | m_FogColor: {r: 0.5, g: 0.5, b: 0.5, a: 1} 19 | m_FogMode: 3 20 | m_FogDensity: 0.01 21 | m_LinearFogStart: 0 22 | m_LinearFogEnd: 300 23 | m_AmbientSkyColor: {r: 0.212, g: 0.227, b: 0.259, a: 1} 24 | m_AmbientEquatorColor: {r: 0.114, g: 0.125, b: 0.133, a: 1} 25 | m_AmbientGroundColor: {r: 0.047, g: 0.043, b: 0.035, a: 1} 26 | m_AmbientIntensity: 1 27 | m_AmbientMode: 0 28 | m_SubtractiveShadowColor: {r: 0.42, g: 0.478, b: 0.627, a: 1} 29 | m_SkyboxMaterial: {fileID: 2100000, guid: 664043a4fef6e6946b358906d45f367a, type: 2} 30 | m_HaloStrength: 0.5 31 | m_FlareStrength: 1 32 | m_FlareFadeSpeed: 3 33 | m_HaloTexture: {fileID: 0} 34 | m_SpotCookie: {fileID: 10001, guid: 0000000000000000e000000000000000, type: 0} 35 | m_DefaultReflectionMode: 0 36 | m_DefaultReflectionResolution: 128 37 | m_ReflectionBounces: 1 38 | m_ReflectionIntensity: 1 39 | m_CustomReflection: {fileID: 0} 40 | m_Sun: {fileID: 705507994} 41 | m_IndirectSpecularColor: {r: 0.55206954, g: 0.59798497, b: 0.62089014, a: 1} 42 | m_UseRadianceAmbientProbe: 0 43 | --- !u!157 &3 44 | LightmapSettings: 45 | m_ObjectHideFlags: 0 46 | serializedVersion: 11 47 | m_GIWorkflowMode: 0 48 | m_GISettings: 49 | serializedVersion: 2 50 | m_BounceScale: 1 51 | m_IndirectOutputScale: 1 52 | m_AlbedoBoost: 1 53 | m_EnvironmentLightingMode: 0 54 | m_EnableBakedLightmaps: 0 55 | m_EnableRealtimeLightmaps: 0 56 | m_LightmapEditorSettings: 57 | serializedVersion: 12 58 | m_Resolution: 2 59 | m_BakeResolution: 40 60 | m_AtlasSize: 1024 61 | m_AO: 0 62 | m_AOMaxDistance: 1 63 | m_CompAOExponent: 1 64 | m_CompAOExponentDirect: 0 65 | m_ExtractAmbientOcclusion: 0 66 | m_Padding: 2 67 | m_LightmapParameters: {fileID: 0} 68 | m_LightmapsBakeMode: 1 69 | m_TextureCompression: 1 70 | m_FinalGather: 0 71 | m_FinalGatherFiltering: 1 72 | m_FinalGatherRayCount: 256 73 | m_ReflectionCompression: 2 74 | m_MixedBakeMode: 2 75 | m_BakeBackend: 1 76 | m_PVRSampling: 1 77 | m_PVRDirectSampleCount: 32 78 | m_PVRSampleCount: 500 79 | m_PVRBounces: 2 80 | m_PVREnvironmentSampleCount: 500 81 | m_PVREnvironmentReferencePointCount: 2048 82 | m_PVRFilteringMode: 2 83 | m_PVRDenoiserTypeDirect: 0 84 | m_PVRDenoiserTypeIndirect: 0 85 | m_PVRDenoiserTypeAO: 0 86 | m_PVRFilterTypeDirect: 0 87 | m_PVRFilterTypeIndirect: 0 88 | m_PVRFilterTypeAO: 0 89 | m_PVREnvironmentMIS: 0 90 | m_PVRCulling: 1 91 | m_PVRFilteringGaussRadiusDirect: 1 92 | m_PVRFilteringGaussRadiusIndirect: 5 93 | m_PVRFilteringGaussRadiusAO: 2 94 | m_PVRFilteringAtrousPositionSigmaDirect: 0.5 95 | m_PVRFilteringAtrousPositionSigmaIndirect: 2 96 | m_PVRFilteringAtrousPositionSigmaAO: 1 97 | m_ExportTrainingData: 0 98 | m_TrainingDataDestination: TrainingData 99 | m_LightProbeSampleCountMultiplier: 4 100 | m_LightingDataAsset: {fileID: 0} 101 | m_UseShadowmask: 1 102 | --- !u!196 &4 103 | NavMeshSettings: 104 | serializedVersion: 2 105 | m_ObjectHideFlags: 0 106 | m_BuildSettings: 107 | serializedVersion: 2 108 | agentTypeID: 0 109 | agentRadius: 0.5 110 | agentHeight: 2 111 | agentSlope: 45 112 | agentClimb: 0.4 113 | ledgeDropHeight: 0 114 | maxJumpAcrossDistance: 0 115 | minRegionArea: 2 116 | manualCellSize: 0 117 | cellSize: 0.16666667 118 | manualTileSize: 0 119 | tileSize: 256 120 | accuratePlacement: 0 121 | debug: 122 | m_Flags: 0 123 | m_NavMeshData: {fileID: 0} 124 | --- !u!1 &542659738 125 | GameObject: 126 | m_ObjectHideFlags: 0 127 | m_CorrespondingSourceObject: {fileID: 0} 128 | m_PrefabInstance: {fileID: 0} 129 | m_PrefabAsset: {fileID: 0} 130 | serializedVersion: 6 131 | m_Component: 132 | - component: {fileID: 542659740} 133 | - component: {fileID: 542659739} 134 | m_Layer: 0 135 | m_Name: WaterPlane 136 | m_TagString: Untagged 137 | m_Icon: {fileID: 0} 138 | m_NavMeshLayer: 0 139 | m_StaticEditorFlags: 0 140 | m_IsActive: 1 141 | --- !u!114 &542659739 142 | MonoBehaviour: 143 | m_ObjectHideFlags: 0 144 | m_CorrespondingSourceObject: {fileID: 0} 145 | m_PrefabInstance: {fileID: 0} 146 | m_PrefabAsset: {fileID: 0} 147 | m_GameObject: {fileID: 542659738} 148 | m_Enabled: 1 149 | m_EditorHideFlags: 0 150 | m_Script: {fileID: 11500000, guid: 94ab40bd34ad2074c9d904734c1a9c1f, type: 3} 151 | m_Name: 152 | m_EditorClassIdentifier: 153 | GenerateOnStart: 1 154 | Size: {x: 512, y: 100, z: 512} 155 | ChunksX: 16 156 | ChunksZ: 16 157 | LODSettings: 158 | - Size: 33 159 | ScreenHeight: 0.99999 160 | FadeTransitionWidth: 0.5 161 | IgnoreLodGroup: 0 162 | RenderSettings: 163 | ShadowCastingMode: 1 164 | ReceiveShadows: 1 165 | DynamicOccluded: 1 166 | - Size: 16 167 | ScreenHeight: 0.8 168 | FadeTransitionWidth: 0.5 169 | IgnoreLodGroup: 0 170 | RenderSettings: 171 | ShadowCastingMode: 1 172 | ReceiveShadows: 1 173 | DynamicOccluded: 1 174 | - Size: 8 175 | ScreenHeight: 0.361 176 | FadeTransitionWidth: 0.5 177 | IgnoreLodGroup: 0 178 | RenderSettings: 179 | ShadowCastingMode: 1 180 | ReceiveShadows: 1 181 | DynamicOccluded: 1 182 | - Size: 4 183 | ScreenHeight: 0 184 | FadeTransitionWidth: 0.5 185 | IgnoreLodGroup: 0 186 | RenderSettings: 187 | ShadowCastingMode: 1 188 | ReceiveShadows: 1 189 | DynamicOccluded: 1 190 | LodFadeMode: 2 191 | AnimateLodCrossFading: 0 192 | Materials: 193 | - {fileID: 2100000, guid: 4dc86583f8ebc4d44be01aada5cc6c14, type: 2} 194 | InstantiateMaterials: 0 195 | --- !u!4 &542659740 196 | Transform: 197 | m_ObjectHideFlags: 0 198 | m_CorrespondingSourceObject: {fileID: 0} 199 | m_PrefabInstance: {fileID: 0} 200 | m_PrefabAsset: {fileID: 0} 201 | m_GameObject: {fileID: 542659738} 202 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 203 | m_LocalPosition: {x: 0, y: 0, z: 0} 204 | m_LocalScale: {x: 1, y: 1, z: 1} 205 | m_Children: [] 206 | m_Father: {fileID: 0} 207 | m_RootOrder: 4 208 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 209 | --- !u!1 &705507993 210 | GameObject: 211 | m_ObjectHideFlags: 0 212 | m_CorrespondingSourceObject: {fileID: 0} 213 | m_PrefabInstance: {fileID: 0} 214 | m_PrefabAsset: {fileID: 0} 215 | serializedVersion: 6 216 | m_Component: 217 | - component: {fileID: 705507995} 218 | - component: {fileID: 705507994} 219 | m_Layer: 0 220 | m_Name: Directional Light 221 | m_TagString: Untagged 222 | m_Icon: {fileID: 0} 223 | m_NavMeshLayer: 0 224 | m_StaticEditorFlags: 0 225 | m_IsActive: 1 226 | --- !u!108 &705507994 227 | Light: 228 | m_ObjectHideFlags: 0 229 | m_CorrespondingSourceObject: {fileID: 0} 230 | m_PrefabInstance: {fileID: 0} 231 | m_PrefabAsset: {fileID: 0} 232 | m_GameObject: {fileID: 705507993} 233 | m_Enabled: 1 234 | serializedVersion: 10 235 | m_Type: 1 236 | m_Shape: 0 237 | m_Color: {r: 1, g: 0.95686275, b: 0.8392157, a: 1} 238 | m_Intensity: 1 239 | m_Range: 10 240 | m_SpotAngle: 30 241 | m_InnerSpotAngle: 21.80208 242 | m_CookieSize: 10 243 | m_Shadows: 244 | m_Type: 2 245 | m_Resolution: -1 246 | m_CustomResolution: -1 247 | m_Strength: 1 248 | m_Bias: 0.15 249 | m_NormalBias: 0.4 250 | m_NearPlane: 0.2 251 | m_CullingMatrixOverride: 252 | e00: 1 253 | e01: 0 254 | e02: 0 255 | e03: 0 256 | e10: 0 257 | e11: 1 258 | e12: 0 259 | e13: 0 260 | e20: 0 261 | e21: 0 262 | e22: 1 263 | e23: 0 264 | e30: 0 265 | e31: 0 266 | e32: 0 267 | e33: 1 268 | m_UseCullingMatrixOverride: 0 269 | m_Cookie: {fileID: 0} 270 | m_DrawHalo: 0 271 | m_Flare: {fileID: 0} 272 | m_RenderMode: 0 273 | m_CullingMask: 274 | serializedVersion: 2 275 | m_Bits: 4294967295 276 | m_RenderingLayerMask: 1 277 | m_Lightmapping: 1 278 | m_LightShadowCasterMode: 0 279 | m_AreaSize: {x: 1, y: 1} 280 | m_BounceIntensity: 1 281 | m_ColorTemperature: 6570 282 | m_UseColorTemperature: 0 283 | m_BoundingSphereOverride: {x: 0, y: 0, z: 0, w: 0} 284 | m_UseBoundingSphereOverride: 0 285 | m_ShadowRadius: 0 286 | m_ShadowAngle: 0 287 | --- !u!4 &705507995 288 | Transform: 289 | m_ObjectHideFlags: 0 290 | m_CorrespondingSourceObject: {fileID: 0} 291 | m_PrefabInstance: {fileID: 0} 292 | m_PrefabAsset: {fileID: 0} 293 | m_GameObject: {fileID: 705507993} 294 | m_LocalRotation: {x: 0.39544383, y: -0.4993404, z: 0.5556995, w: 0.5343046} 295 | m_LocalPosition: {x: 0, y: 3, z: 0} 296 | m_LocalScale: {x: 1, y: 1, z: 1} 297 | m_Children: [] 298 | m_Father: {fileID: 0} 299 | m_RootOrder: 1 300 | m_LocalEulerAnglesHint: {x: 77.83401, y: -26.521002, z: 70.703} 301 | --- !u!1 &963194225 302 | GameObject: 303 | m_ObjectHideFlags: 0 304 | m_CorrespondingSourceObject: {fileID: 0} 305 | m_PrefabInstance: {fileID: 0} 306 | m_PrefabAsset: {fileID: 0} 307 | serializedVersion: 6 308 | m_Component: 309 | - component: {fileID: 963194228} 310 | - component: {fileID: 963194227} 311 | - component: {fileID: 963194226} 312 | - component: {fileID: 963194229} 313 | m_Layer: 0 314 | m_Name: Main Camera 315 | m_TagString: MainCamera 316 | m_Icon: {fileID: 0} 317 | m_NavMeshLayer: 0 318 | m_StaticEditorFlags: 0 319 | m_IsActive: 1 320 | --- !u!81 &963194226 321 | AudioListener: 322 | m_ObjectHideFlags: 0 323 | m_CorrespondingSourceObject: {fileID: 0} 324 | m_PrefabInstance: {fileID: 0} 325 | m_PrefabAsset: {fileID: 0} 326 | m_GameObject: {fileID: 963194225} 327 | m_Enabled: 1 328 | --- !u!20 &963194227 329 | Camera: 330 | m_ObjectHideFlags: 0 331 | m_CorrespondingSourceObject: {fileID: 0} 332 | m_PrefabInstance: {fileID: 0} 333 | m_PrefabAsset: {fileID: 0} 334 | m_GameObject: {fileID: 963194225} 335 | m_Enabled: 1 336 | serializedVersion: 2 337 | m_ClearFlags: 1 338 | m_BackGroundColor: {r: 0.19215687, g: 0.3019608, b: 0.4745098, a: 0} 339 | m_projectionMatrixMode: 1 340 | m_GateFitMode: 2 341 | m_FOVAxisMode: 0 342 | m_SensorSize: {x: 36, y: 24} 343 | m_LensShift: {x: 0, y: 0} 344 | m_FocalLength: 50 345 | m_NormalizedViewPortRect: 346 | serializedVersion: 2 347 | x: 0 348 | y: 0 349 | width: 1 350 | height: 1 351 | near clip plane: 0.3 352 | far clip plane: 1000 353 | field of view: 60 354 | orthographic: 0 355 | orthographic size: 5 356 | m_Depth: -1 357 | m_CullingMask: 358 | serializedVersion: 2 359 | m_Bits: 4294967295 360 | m_RenderingPath: 1 361 | m_TargetTexture: {fileID: 0} 362 | m_TargetDisplay: 0 363 | m_TargetEye: 3 364 | m_HDR: 1 365 | m_AllowMSAA: 1 366 | m_AllowDynamicResolution: 0 367 | m_ForceIntoRT: 0 368 | m_OcclusionCulling: 1 369 | m_StereoConvergence: 10 370 | m_StereoSeparation: 0.022 371 | --- !u!4 &963194228 372 | Transform: 373 | m_ObjectHideFlags: 0 374 | m_CorrespondingSourceObject: {fileID: 0} 375 | m_PrefabInstance: {fileID: 0} 376 | m_PrefabAsset: {fileID: 0} 377 | m_GameObject: {fileID: 963194225} 378 | m_LocalRotation: {x: 0.34716862, y: -0, z: -0, w: 0.9378028} 379 | m_LocalPosition: {x: 120.3, y: 152.3, z: -59.6} 380 | m_LocalScale: {x: 1, y: 1, z: 1} 381 | m_Children: [] 382 | m_Father: {fileID: 0} 383 | m_RootOrder: 0 384 | m_LocalEulerAnglesHint: {x: 40.628002, y: 0, z: 0} 385 | --- !u!114 &963194229 386 | MonoBehaviour: 387 | m_ObjectHideFlags: 0 388 | m_CorrespondingSourceObject: {fileID: 0} 389 | m_PrefabInstance: {fileID: 0} 390 | m_PrefabAsset: {fileID: 0} 391 | m_GameObject: {fileID: 963194225} 392 | m_Enabled: 1 393 | m_EditorHideFlags: 0 394 | m_Script: {fileID: 11500000, guid: d6b0207ed7914c74191269f3bfb16d38, type: 3} 395 | m_Name: 396 | m_EditorClassIdentifier: 397 | MainSpeed: 100 398 | ShiftAdd: 250 399 | MaxShift: 1000 400 | MouseSensitivity: 0.25 401 | RotateOnlyIfMousedown: 1 402 | --- !u!1 &1184266355 403 | GameObject: 404 | m_ObjectHideFlags: 0 405 | m_CorrespondingSourceObject: {fileID: 0} 406 | m_PrefabInstance: {fileID: 0} 407 | m_PrefabAsset: {fileID: 0} 408 | serializedVersion: 6 409 | m_Component: 410 | - component: {fileID: 1184266358} 411 | - component: {fileID: 1184266357} 412 | - component: {fileID: 1184266356} 413 | - component: {fileID: 1184266359} 414 | m_Layer: 0 415 | m_Name: Terrain 416 | m_TagString: Untagged 417 | m_Icon: {fileID: 0} 418 | m_NavMeshLayer: 0 419 | m_StaticEditorFlags: 4294967295 420 | m_IsActive: 1 421 | --- !u!154 &1184266356 422 | TerrainCollider: 423 | m_ObjectHideFlags: 0 424 | m_CorrespondingSourceObject: {fileID: 0} 425 | m_PrefabInstance: {fileID: 0} 426 | m_PrefabAsset: {fileID: 0} 427 | m_GameObject: {fileID: 1184266355} 428 | m_Material: {fileID: 0} 429 | m_Enabled: 1 430 | m_TerrainData: {fileID: 15600000, guid: f7c510775dd5cdc44bec2c7395d856b8, type: 2} 431 | m_EnableTreeColliders: 1 432 | --- !u!218 &1184266357 433 | Terrain: 434 | m_ObjectHideFlags: 0 435 | m_CorrespondingSourceObject: {fileID: 0} 436 | m_PrefabInstance: {fileID: 0} 437 | m_PrefabAsset: {fileID: 0} 438 | m_GameObject: {fileID: 1184266355} 439 | m_Enabled: 1 440 | serializedVersion: 6 441 | m_TerrainData: {fileID: 15600000, guid: f7c510775dd5cdc44bec2c7395d856b8, type: 2} 442 | m_TreeDistance: 5000 443 | m_TreeBillboardDistance: 50 444 | m_TreeCrossFadeLength: 5 445 | m_TreeMaximumFullLODCount: 50 446 | m_DetailObjectDistance: 80 447 | m_DetailObjectDensity: 1 448 | m_HeightmapPixelError: 5 449 | m_SplatMapDistance: 1000 450 | m_HeightmapMaximumLOD: 0 451 | m_ShadowCastingMode: 2 452 | m_DrawHeightmap: 1 453 | m_DrawInstanced: 0 454 | m_DrawTreesAndFoliage: 1 455 | m_ReflectionProbeUsage: 1 456 | m_MaterialTemplate: {fileID: 10650, guid: 0000000000000000f000000000000000, type: 0} 457 | m_BakeLightProbesForTrees: 1 458 | m_PreserveTreePrototypeLayers: 0 459 | m_DeringLightProbesForTrees: 1 460 | m_ScaleInLightmap: 0.0256 461 | m_LightmapParameters: {fileID: 15203, guid: 0000000000000000f000000000000000, type: 0} 462 | m_GroupingID: 0 463 | m_RenderingLayerMask: 1 464 | m_AllowAutoConnect: 1 465 | --- !u!4 &1184266358 466 | Transform: 467 | m_ObjectHideFlags: 0 468 | m_CorrespondingSourceObject: {fileID: 0} 469 | m_PrefabInstance: {fileID: 0} 470 | m_PrefabAsset: {fileID: 0} 471 | m_GameObject: {fileID: 1184266355} 472 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 473 | m_LocalPosition: {x: 0, y: 0, z: 0} 474 | m_LocalScale: {x: 1, y: 1, z: 1} 475 | m_Children: [] 476 | m_Father: {fileID: 0} 477 | m_RootOrder: 3 478 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 479 | --- !u!114 &1184266359 480 | MonoBehaviour: 481 | m_ObjectHideFlags: 0 482 | m_CorrespondingSourceObject: {fileID: 0} 483 | m_PrefabInstance: {fileID: 0} 484 | m_PrefabAsset: {fileID: 0} 485 | m_GameObject: {fileID: 1184266355} 486 | m_Enabled: 1 487 | m_EditorHideFlags: 0 488 | m_Script: {fileID: 11500000, guid: f5155af39c4f47e1a0fb99a5a53f9248, type: 3} 489 | m_Name: 490 | m_EditorClassIdentifier: 491 | Simulation: {fileID: 1293415289} 492 | --- !u!1 &1293415288 493 | GameObject: 494 | m_ObjectHideFlags: 0 495 | m_CorrespondingSourceObject: {fileID: 0} 496 | m_PrefabInstance: {fileID: 0} 497 | m_PrefabAsset: {fileID: 0} 498 | serializedVersion: 6 499 | m_Component: 500 | - component: {fileID: 1293415292} 501 | - component: {fileID: 1293415289} 502 | m_Layer: 0 503 | m_Name: Simulation 504 | m_TagString: Untagged 505 | m_Icon: {fileID: 0} 506 | m_NavMeshLayer: 0 507 | m_StaticEditorFlags: 0 508 | m_IsActive: 1 509 | --- !u!114 &1293415289 510 | MonoBehaviour: 511 | m_ObjectHideFlags: 0 512 | m_CorrespondingSourceObject: {fileID: 0} 513 | m_PrefabInstance: {fileID: 0} 514 | m_PrefabAsset: {fileID: 0} 515 | m_GameObject: {fileID: 1293415288} 516 | m_Enabled: 1 517 | m_EditorHideFlags: 0 518 | m_Script: {fileID: 11500000, guid: 9dc03fd489a1eb04a9ae808ab1d54948, type: 3} 519 | m_Name: 520 | m_EditorClassIdentifier: 521 | Materials: 522 | - {fileID: 2100000, guid: 1cf9e6530b1beb341b6ecccf254cf279, type: 2} 523 | - {fileID: 2100000, guid: 4dc86583f8ebc4d44be01aada5cc6c14, type: 2} 524 | ErosionComputeShader: {fileID: 7200000, guid: fcfc55914f9fdb646be1044044c2d042, 525 | type: 3} 526 | InitialState: {fileID: 2800000, guid: 43149b43056f9c340b49f9a408fc3284, type: 3} 527 | InitHeightMap: {fileID: 2100000, guid: a1079684b02cda94a9a601a811134170, type: 2} 528 | BrushAmount: 10 529 | InputMode: 0 530 | Width: 512 531 | Height: 512 532 | Settings: 533 | TimeScale: 1 534 | PipeLength: 1 535 | CellSize: {x: 1, y: 1} 536 | RainRate: 0 537 | Evaporation: 0 538 | PipeArea: 5 539 | Gravity: 9.81 540 | SedimentCapacity: 0.1 541 | SoilSuspensionRate: 0.8 542 | SedimentDepositionRate: 0.8 543 | SedimentSofteningRate: 5 544 | MaximalErosionDepth: 1 545 | ThermalErosionTimeScale: 20 546 | ThermalErosionRate: 1 547 | TalusAngleTangentCoeff: 0.6 548 | TalusAngleTangentBias: 0.2 549 | --- !u!4 &1293415292 550 | Transform: 551 | m_ObjectHideFlags: 0 552 | m_CorrespondingSourceObject: {fileID: 0} 553 | m_PrefabInstance: {fileID: 0} 554 | m_PrefabAsset: {fileID: 0} 555 | m_GameObject: {fileID: 1293415288} 556 | m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} 557 | m_LocalPosition: {x: 0, y: 0, z: 0} 558 | m_LocalScale: {x: 1, y: 1, z: 1} 559 | m_Children: [] 560 | m_Father: {fileID: 0} 561 | m_RootOrder: 2 562 | m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} 563 | -------------------------------------------------------------------------------- /Assets/Scenes/UnityTerrain/UnityTerrain.unity.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9fc0d4010bbf28b4594072e72b8655ab 3 | DefaultImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /Assets/Scripts.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 767ecf2a6a5a5544ebe43a9513853bae 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/ChunkedPlane.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Assets.Scripts.Utils; 4 | using UnityEngine; 5 | using UnityEngine.Rendering; 6 | using Utils; 7 | 8 | public class ChunkedPlane : MonoBehaviour 9 | { 10 | [Serializable] 11 | public class RenderSettings 12 | { 13 | public ShadowCastingMode ShadowCastingMode = ShadowCastingMode.On; 14 | public bool ReceiveShadows = true; 15 | public bool DynamicOccluded = true; 16 | } 17 | 18 | [Serializable] 19 | public class ChunkLODSetting 20 | { 21 | [Range(4, 200)] 22 | public int Size = 200; 23 | 24 | [Range(0, 1)] 25 | [Tooltip("The screen relative height to use for the transition [0-1].")] 26 | public float ScreenHeight; 27 | 28 | [Range(0, 1)] 29 | [Tooltip("Width of the cross-fade transition zone (proportion to the current LOD's whole length) [0-1]. Only used if it's not animated.")] 30 | public float FadeTransitionWidth = 0.5f; 31 | 32 | [Tooltip("If true, mesh for the current chunk will ignore LOD group of the chunk. May be useful for low-detailed shadow-only meshes")] 33 | public bool IgnoreLodGroup = false; 34 | 35 | public RenderSettings RenderSettings; 36 | } 37 | 38 | public bool GenerateOnStart; 39 | 40 | [Header("Terrain settings")] 41 | public Vector3 Size = new Vector3(256, 10, 256); 42 | public int ChunksX = 16; 43 | public int ChunksZ = 16; 44 | public ChunkLODSetting[] LODSettings; 45 | public LODFadeMode LodFadeMode = LODFadeMode.CrossFade; 46 | public bool AnimateLodCrossFading = true; 47 | 48 | [Header("Materials")] 49 | public Material[] Materials; 50 | public bool InstantiateMaterials; 51 | 52 | void Start() 53 | { 54 | if(GenerateOnStart) 55 | Generate(); 56 | } 57 | 58 | [ContextMenu("Generate Terrain")] 59 | public void Generate() 60 | { 61 | var chunkWorldSize = new Vector3(Size.x / ChunksX, Size.y, Size.z / ChunksZ); 62 | 63 | // Clear all children 64 | foreach (Transform child in transform) 65 | Destroy(child); 66 | 67 | for (var z = 0; z < ChunksZ; z++) 68 | { 69 | for (var x = 0; x < ChunksX; x++) 70 | { 71 | // Chunk texture coordinates 72 | var uvStart = new Vector2((float)x / ChunksX, (float)z / ChunksZ); 73 | var uvEnd = new Vector2((float)(x + 1) / ChunksX, (float)(z + 1) / ChunksZ); 74 | 75 | var group = new GameObject(string.Format("Chunk_{0}_{1}", x, z)); 76 | group.transform.position = new Vector3(x * chunkWorldSize.x, 0, z * chunkWorldSize.z); 77 | group.transform.SetParent(transform, false); 78 | 79 | var lodGroup = group.AddComponent(); 80 | lodGroup.fadeMode = LodFadeMode; 81 | lodGroup.animateCrossFading = AnimateLodCrossFading; 82 | 83 | var lods = new List(); 84 | for (var i = 0; i < LODSettings.Length; i++) 85 | { 86 | var settings = LODSettings[i]; 87 | var chunk = GenerateChunk(chunkWorldSize, uvStart, uvEnd, settings, i); 88 | chunk.transform.SetParent(group.transform, false); 89 | 90 | if (!settings.IgnoreLodGroup) 91 | { 92 | // Add chunk renderer to the LOD group 93 | var chunkRenderer = chunk.GetComponent(); 94 | lods.Add(new LOD(settings.ScreenHeight, new Renderer[] {chunkRenderer}) 95 | { 96 | fadeTransitionWidth = settings.FadeTransitionWidth 97 | }); 98 | } 99 | } 100 | 101 | lodGroup.SetLODs(lods.ToArray()); 102 | lodGroup.RecalculateBounds(); 103 | } 104 | } 105 | } 106 | 107 | private GameObject GenerateChunk(Vector3 chunkSize, Vector2 uvStart, Vector2 uvEnd, ChunkLODSetting settings, int lodLevel) 108 | { 109 | var chunkObject = new GameObject($"Terrain_Chunk_LOD{lodLevel}"); 110 | var chunkMeshFilter = chunkObject.AddComponent(); 111 | var chunkMeshRenderer = chunkObject.AddComponent(); 112 | 113 | // Renderer settings 114 | chunkMeshRenderer.shadowCastingMode = settings.RenderSettings.ShadowCastingMode; 115 | chunkMeshRenderer.allowOcclusionWhenDynamic = settings.RenderSettings.DynamicOccluded; 116 | chunkMeshRenderer.receiveShadows = settings.RenderSettings.ReceiveShadows; 117 | 118 | var mesh = MeshUtils.GeneratePlane( 119 | Vector3.zero, 120 | Vector3.right * chunkSize.x, 121 | Vector3.forward * chunkSize.z, 122 | settings.Size, 123 | settings.Size, 124 | uvStart, uvEnd); 125 | 126 | mesh.bounds = new Bounds(0.5f * chunkSize, chunkSize); 127 | mesh.name = chunkObject.name; 128 | 129 | chunkMeshFilter.mesh = mesh; 130 | chunkMeshRenderer.materials = Materials; 131 | return chunkObject; 132 | } 133 | } -------------------------------------------------------------------------------- /Assets/Scripts/ChunkedPlane.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 94ab40bd34ad2074c9d904734c1a9c1f 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Simulation.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using Assets.Scripts.Utils; 3 | using UnityEngine; 4 | 5 | public class Simulation : MonoBehaviour 6 | { 7 | [Header("References")] 8 | public Material[] Materials; 9 | public ComputeShader ErosionComputeShader; 10 | public Texture2D InitialState; 11 | public Material InitHeightMap; 12 | 13 | [Header("Drawing")] 14 | public float BrushAmount = 0f; 15 | 16 | public InputModes InputMode = InputModes.AddWater; 17 | 18 | public enum InputModes : int 19 | { 20 | AddWater = 0, 21 | RemoveWater = 1, 22 | AddTerrain = 2, 23 | RemoveTerrain = 3 24 | } 25 | 26 | [Serializable] 27 | public class SimulationSettings 28 | { 29 | [Range(0f, 10f)] 30 | public float TimeScale = 1f; 31 | 32 | public float PipeLength = 1f / 256; 33 | public Vector2 CellSize = new Vector2(1f / 256, 1f / 256); 34 | 35 | [Range(0, 0.5f)] 36 | public float RainRate = 0.012f; 37 | 38 | [Range(0, 1f)] 39 | public float Evaporation = 0.015f; 40 | 41 | [Range(0.001f, 1000)] 42 | public float PipeArea = 20; 43 | 44 | [Range(0.1f, 20f)] 45 | public float Gravity = 9.81f; 46 | 47 | [Header("Hydraulic erosion")] 48 | [Range(0.1f, 3f)] 49 | public float SedimentCapacity = 1f; 50 | 51 | [Range(0.1f, 2f)] 52 | public float SoilSuspensionRate = 0.5f; 53 | 54 | [Range(0.1f, 3f)] 55 | public float SedimentDepositionRate = 1f; 56 | 57 | [Range(0f, 10f)] 58 | public float SedimentSofteningRate = 5f; 59 | 60 | [Range(0f, 40f)] 61 | public float MaximalErosionDepth = 10f; 62 | 63 | [Header("Thermal erosion")] 64 | [Range(0, 1000f)] 65 | public float ThermalErosionTimeScale = 1f; 66 | 67 | [Range(0, 1f)] 68 | public float ThermalErosionRate = 0.15f; 69 | 70 | [Range(0f, 1f)] 71 | public float TalusAngleTangentCoeff = 0.8f; 72 | 73 | [Range(0f, 1f)] 74 | public float TalusAngleTangentBias = 0.1f; 75 | 76 | } 77 | 78 | [Header("Simulation settings")] 79 | [Range(32, 1024)] 80 | public int Width = 256; 81 | [Range(32, 1024)] 82 | public int Height = 256; 83 | public SimulationSettings Settings; 84 | 85 | // State texture ARGBFloat 86 | // R - surface height [0, +inf] 87 | // G - water over surface height [0, +inf] 88 | // B - Suspended sediment amount [0, +inf] 89 | // A - Hardness of the surface [0, 1] 90 | private RenderTexture _stateTexture; 91 | private RenderTexture _stateTextureBuffer; 92 | 93 | // Output water flux-field texture 94 | // represents how much water is OUTGOING in each direction 95 | // R - flux to the left cell [0, +inf] 96 | // G - flux to the right cell [0, +inf] 97 | // B - flux to the top cell [0, +inf] 98 | // A - flux to the bottom cell [0, +inf] 99 | private RenderTexture _waterFluxTexture; 100 | 101 | // Output terrain flux-field texture 102 | // represents how much landmass is OUTGOING in each direction 103 | // Used in thermal erosion process 104 | // R - flux to the left cell [0, +inf] 105 | // G - flux to the right cell [0, +inf] 106 | // B - flux to the top cell [0, +inf] 107 | // A - flux to the bottom cell [0, +inf] 108 | private RenderTexture _terrainFluxTexture; 109 | 110 | // Velocity texture 111 | // R - X-velocity [-inf, +inf] 112 | // G - Y-velocity [-inf, +inf] 113 | private RenderTexture _velocityTexture; 114 | 115 | // List of kernels in the compute shader to be dispatched 116 | // Sequentially in this order 117 | private readonly string[] _kernelNames = { 118 | "RainAndControl", 119 | "FluxComputation", 120 | "FluxApply", 121 | "HydraulicErosion", 122 | "SedimentAdvection", 123 | "ThermalErosion", 124 | "ApplyThermalErosion" 125 | }; 126 | 127 | // Kernel-related data 128 | private int[] _kernels; 129 | private uint _threadsPerGroupX; 130 | private uint _threadsPerGroupY; 131 | private uint _threadsPerGroupZ; 132 | 133 | // Rendering stuff 134 | private const string StateTextureKey = "_StateTex"; 135 | 136 | // Brush 137 | private Plane _floor = new Plane(Vector3.up, Vector3.zero); 138 | private float _brushRadius = 0.05f; 139 | private Vector4 _inputControls; 140 | private Material _copyMat; 141 | 142 | void Start() 143 | { 144 | Camera.main.depthTextureMode = DepthTextureMode.Depth; 145 | 146 | _copyMat = new Material(Shader.Find("Hidden/Copy")); 147 | 148 | // Set everything up 149 | Initialize(); 150 | } 151 | 152 | void Update() 153 | { 154 | // Controls 155 | _brushRadius = Mathf.Clamp(_brushRadius + Input.mouseScrollDelta.y * Time.deltaTime * 0.2f, 0.01f, 1f); 156 | 157 | var ray = Camera.main.ScreenPointToRay(Input.mousePosition); 158 | var amount = 0f; 159 | var brushX = 0f; 160 | var brushY = 0f; 161 | 162 | if (_floor.Raycast(ray, out var enter)) 163 | { 164 | var hitPoint = ray.GetPoint(enter); 165 | brushX = hitPoint.x / Width; 166 | brushY = hitPoint.z / Height; 167 | 168 | if (Input.GetMouseButton(0)) 169 | amount = BrushAmount; 170 | } 171 | else 172 | { 173 | amount = 0f; 174 | } 175 | 176 | _inputControls = new Vector4(brushX, brushY, _brushRadius, amount); 177 | Shader.SetGlobalVector("_InputControls", _inputControls); 178 | } 179 | 180 | void FixedUpdate() 181 | { 182 | // Compute dispatch 183 | if (ErosionComputeShader != null) 184 | { 185 | if (Settings != null) 186 | { 187 | // General parameters 188 | ErosionComputeShader.SetFloat("_TimeDelta", Time.fixedDeltaTime * Settings.TimeScale); 189 | ErosionComputeShader.SetFloat("_PipeArea", Settings.PipeArea); 190 | ErosionComputeShader.SetFloat("_Gravity", Settings.Gravity); 191 | ErosionComputeShader.SetFloat("_PipeLength", Settings.PipeLength); 192 | ErosionComputeShader.SetVector("_CellSize", Settings.CellSize); 193 | ErosionComputeShader.SetFloat("_Evaporation", Settings.Evaporation); 194 | ErosionComputeShader.SetFloat("_RainRate", Settings.RainRate); 195 | 196 | // Hydraulic erosion 197 | ErosionComputeShader.SetFloat("_SedimentCapacity", Settings.SedimentCapacity); 198 | ErosionComputeShader.SetFloat("_MaxErosionDepth", Settings.MaximalErosionDepth); 199 | ErosionComputeShader.SetFloat("_SuspensionRate", Settings.SoilSuspensionRate); 200 | ErosionComputeShader.SetFloat("_DepositionRate", Settings.SedimentDepositionRate); 201 | ErosionComputeShader.SetFloat("_SedimentSofteningRate", Settings.SedimentSofteningRate); 202 | 203 | // Thermal erosion 204 | ErosionComputeShader.SetFloat("_ThermalErosionRate", Settings.ThermalErosionRate); 205 | ErosionComputeShader.SetFloat("_TalusAngleTangentCoeff", Settings.TalusAngleTangentCoeff); 206 | ErosionComputeShader.SetFloat("_TalusAngleTangentBias", Settings.TalusAngleTangentBias); 207 | ErosionComputeShader.SetFloat("_ThermalErosionTimeScale", Settings.ThermalErosionTimeScale); 208 | 209 | // Inputs 210 | ErosionComputeShader.SetVector("_InputControls", _inputControls); 211 | ErosionComputeShader.SetInt("_InputMode", (int)InputMode); 212 | } 213 | 214 | // Dispatch all passes sequentially 215 | foreach (var kernel in _kernels) 216 | { 217 | ErosionComputeShader.Dispatch(kernel, 218 | _stateTexture.width / (int)_threadsPerGroupX, 219 | _stateTexture.height / (int)_threadsPerGroupY, 1); 220 | } 221 | } 222 | } 223 | 224 | [ContextMenu("Initialize")] 225 | public void Initialize() 226 | { 227 | /* ========= Setup computation =========== */ 228 | // If there are already existing textures - release them 229 | if (_stateTexture != null) 230 | _stateTexture.Release(); 231 | 232 | if (_waterFluxTexture != null) 233 | _waterFluxTexture.Release(); 234 | 235 | if (_velocityTexture != null) 236 | _velocityTexture.Release(); 237 | 238 | // Initialize texture for storing height map 239 | _stateTexture = new RenderTexture(Width, Height, 0, RenderTextureFormat.ARGBFloat) 240 | { 241 | enableRandomWrite = true, 242 | filterMode = FilterMode.Bilinear, 243 | wrapMode = TextureWrapMode.Clamp 244 | }; 245 | 246 | _stateTextureBuffer = new RenderTexture(Width, Height, 0, RenderTextureFormat.ARGBFloat) 247 | { 248 | enableRandomWrite = false, 249 | filterMode = FilterMode.Bilinear, 250 | wrapMode = TextureWrapMode.Clamp 251 | }; 252 | 253 | // Initialize texture for storing flow 254 | _waterFluxTexture = new RenderTexture(Width, Height, 0, RenderTextureFormat.ARGBFloat) 255 | { 256 | enableRandomWrite = true, 257 | filterMode = FilterMode.Point, 258 | wrapMode = TextureWrapMode.Clamp 259 | }; 260 | 261 | // Initialize texture for storing flow for thermal erosion 262 | _terrainFluxTexture = new RenderTexture(Width, Height, 0, RenderTextureFormat.ARGBFloat) 263 | { 264 | enableRandomWrite = true, 265 | filterMode = FilterMode.Point, 266 | wrapMode = TextureWrapMode.Repeat 267 | }; 268 | 269 | // Velocity texture 270 | _velocityTexture = new RenderTexture(Width, Height, 0, RenderTextureFormat.RGFloat) 271 | { 272 | enableRandomWrite = true, 273 | filterMode = FilterMode.Point, 274 | wrapMode = TextureWrapMode.Clamp 275 | }; 276 | 277 | if (!_stateTexture.IsCreated()) 278 | _stateTexture.Create(); 279 | 280 | if (!_waterFluxTexture.IsCreated()) 281 | _waterFluxTexture.Create(); 282 | 283 | if (!_terrainFluxTexture.IsCreated()) 284 | _terrainFluxTexture.Create(); 285 | 286 | if (!_velocityTexture.IsCreated()) 287 | _velocityTexture.Create(); 288 | 289 | if (InitialState != null) 290 | { 291 | if (InitHeightMap != null) 292 | Graphics.Blit(InitialState, _stateTexture, InitHeightMap); 293 | else 294 | Graphics.Blit(InitialState, _stateTexture); 295 | } 296 | 297 | // Setup computation shader 298 | if (ErosionComputeShader != null) 299 | { 300 | _kernels = new int[_kernelNames.Length]; 301 | var i = 0; 302 | foreach (var kernelName in _kernelNames) 303 | { 304 | var kernel = ErosionComputeShader.FindKernel(kernelName);; 305 | _kernels[i++] = kernel; 306 | 307 | // Set all textures 308 | ErosionComputeShader.SetTexture(kernel, "HeightMap", _stateTexture); 309 | ErosionComputeShader.SetTexture(kernel, "VelocityMap", _velocityTexture); 310 | ErosionComputeShader.SetTexture(kernel, "FluxMap", _waterFluxTexture); 311 | ErosionComputeShader.SetTexture(kernel, "TerrainFluxMap", _terrainFluxTexture); 312 | } 313 | 314 | ErosionComputeShader.SetInt("_Width", Width); 315 | ErosionComputeShader.SetInt("_Height", Height); 316 | ErosionComputeShader.GetKernelThreadGroupSizes(_kernels[0], out _threadsPerGroupX, out _threadsPerGroupY, out _threadsPerGroupZ); 317 | 318 | } 319 | 320 | // Debug information 321 | Debugger.Instance.Display("Width", Width); 322 | Debugger.Instance.Display("Height", Height); 323 | Debugger.Instance.Display("HeightMap", _stateTexture); 324 | Debugger.Instance.Display("FluxMap", _waterFluxTexture); 325 | Debugger.Instance.Display("TerrainFluxMap", _terrainFluxTexture); 326 | Debugger.Instance.Display("VelocityMap", _velocityTexture); 327 | 328 | 329 | /* ========= Setup Rendering =========== */ 330 | // Assign state texture to materials 331 | foreach (var material in Materials) 332 | { 333 | material.SetTexture(StateTextureKey, _stateTexture); 334 | } 335 | } 336 | 337 | public enum StateChannel : int 338 | { 339 | SurfaceHeight = 0, 340 | Water = 1, 341 | SuspendedSediment = 2, 342 | SurfaceHardness = 3 343 | } 344 | 345 | public void UpdateStateFromTexture(Texture source, 346 | int sourceChannel = 0, 347 | StateChannel targetStateChannel = StateChannel.SurfaceHeight, 348 | float scale = 1f, 349 | float bias = 0f) 350 | { 351 | Graphics.Blit(_stateTexture, _stateTextureBuffer); 352 | Debugger.Instance.Display("StateSource", source); 353 | _copyMat.SetTexture("_PrevTex", _stateTextureBuffer); 354 | _copyMat.SetTexture("_HTex", source); 355 | _copyMat.SetInt("_SrcChannel", sourceChannel); 356 | _copyMat.SetInt("_TgtChannel", (int)targetStateChannel); 357 | _copyMat.SetFloat("_Scale", scale); 358 | _copyMat.SetFloat("_Bias", bias); 359 | Graphics.Blit(null, _stateTexture, _copyMat); 360 | } 361 | 362 | public void UpdateSurfaceFromTerrainData(TerrainData terrainData) 363 | { 364 | UpdateStateFromTexture(terrainData.heightmapTexture, 0, 365 | StateChannel.SurfaceHeight, scale: terrainData.size.y * 2); 366 | } 367 | 368 | public void OnGUI() 369 | { 370 | var inputModes = new[] { "Add water", "Remove water", "Add Terrain", "Remove terrain" }; 371 | GUILayout.BeginArea(new Rect(10, 10, 400, 400)); 372 | InputMode = (InputModes)GUILayout.Toolbar((int)InputMode, inputModes); 373 | 374 | GUILayout.BeginHorizontal(); 375 | GUILayout.Label("Brush strength"); 376 | BrushAmount = GUILayout.HorizontalSlider(BrushAmount, 1f, 100f); 377 | GUILayout.EndHorizontal(); 378 | 379 | GUILayout.BeginHorizontal(); 380 | GUILayout.Label("Brush size"); 381 | _brushRadius = GUILayout.HorizontalSlider(_brushRadius, 0.01f, 0.2f); 382 | GUILayout.EndHorizontal(); 383 | 384 | GUILayout.Label("[W][A][S][D] - Fly, hold [Shift] - fly faster"); 385 | GUILayout.Label("hold [RMB] - rotate camera"); 386 | GUILayout.Label("[LMB] - draw"); 387 | GUILayout.EndArea(); 388 | } 389 | } -------------------------------------------------------------------------------- /Assets/Scripts/Simulation.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9dc03fd489a1eb04a9ae808ab1d54948 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/UnityTerrainAdapter.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | [RequireComponent(typeof(Terrain))] 4 | public class UnityTerrainAdapter : MonoBehaviour 5 | { 6 | public Simulation Simulation; 7 | 8 | private TerrainData _terrainData; 9 | private Terrain _terrain; 10 | 11 | private void Start() 12 | { 13 | _terrain = GetComponent(); 14 | _terrainData = _terrain.terrainData; 15 | } 16 | 17 | void Update() 18 | { 19 | if(Simulation != null && _terrainData != null) 20 | Simulation.UpdateSurfaceFromTerrainData(_terrainData); 21 | } 22 | } -------------------------------------------------------------------------------- /Assets/Scripts/UnityTerrainAdapter.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f5155af39c4f47e1a0fb99a5a53f9248 3 | timeCreated: 1583975005 -------------------------------------------------------------------------------- /Assets/Scripts/Utils.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: e41e116e6a8f7414b8457880922a09e7 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Scripts/Utils/Debugger.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f2525c7499882294287772b2d0ab5bf1 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Utils/FixedSizeStack.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | 6 | namespace Assets.Scripts.Utils 7 | { 8 | [Serializable] 9 | public class FixedSizeStack : IEnumerable, IEnumerable 10 | { 11 | private T[] _data; 12 | private int _pointer; 13 | private int _count; 14 | private long _version; 15 | 16 | public FixedSizeStack(int size) 17 | { 18 | if (size < 1) 19 | { 20 | throw new ArgumentOutOfRangeException("size"); 21 | } 22 | _data = new T[size]; 23 | _pointer = _data.GetLowerBound(0); 24 | _version = 0; 25 | } 26 | 27 | private void _IncrementPointer() 28 | { 29 | if (_pointer++ == _data.GetUpperBound(0)) 30 | { 31 | _pointer = _data.GetLowerBound(0); 32 | } 33 | } 34 | 35 | private void _DecrementPointer() 36 | { 37 | if (_pointer-- == _data.GetLowerBound(0)) 38 | { 39 | _pointer = _data.GetUpperBound(0); 40 | } 41 | } 42 | 43 | public bool Contains(T item) 44 | { 45 | return _data.Contains(item); 46 | } 47 | 48 | public int Count() 49 | { 50 | return _count; 51 | } 52 | 53 | public int Size 54 | { 55 | get { return _data.Length; } 56 | } 57 | 58 | public void Clear() 59 | { 60 | _data = new T[Size]; 61 | } 62 | 63 | public T this[int index] 64 | { 65 | get 66 | { 67 | var i = _pointer - index; 68 | if (i < 0) 69 | { 70 | i += Size; 71 | } 72 | return _data[i]; 73 | } 74 | } 75 | 76 | public T Pop() 77 | { 78 | var item = _data[_pointer]; 79 | _data[_pointer] = default(T); 80 | _DecrementPointer(); 81 | _version++; 82 | if (_count > _data.GetLowerBound(0)) 83 | { 84 | _count--; 85 | } 86 | return item; 87 | } 88 | 89 | public void Push(T item) 90 | { 91 | _IncrementPointer(); 92 | _data[_pointer] = item; 93 | _version++; 94 | if (_count <= _data.GetUpperBound(0)) 95 | { 96 | _count++; 97 | } 98 | } 99 | 100 | public T Peek() 101 | { 102 | return _data[_pointer]; 103 | } 104 | 105 | [Serializable] 106 | private struct Enumerator : IEnumerator 107 | { 108 | private readonly FixedSizeStack _stack; 109 | private int _index; 110 | private readonly long _version; 111 | private T _currentElement; 112 | 113 | internal Enumerator(FixedSizeStack stack) 114 | { 115 | _stack = stack; 116 | _version = _stack._version; 117 | _index = -2; 118 | _currentElement = default(T); 119 | } 120 | 121 | public void Dispose() 122 | { 123 | _index = -1; 124 | } 125 | 126 | public bool MoveNext() 127 | { 128 | if (_version != _stack._version) 129 | throw new InvalidOperationException("Version Conflict"); 130 | if (_index == -2) 131 | { 132 | _index = 0; 133 | var flag = _index >= 0; 134 | if (flag) 135 | _currentElement = _stack[_index]; 136 | return flag; 137 | } 138 | if (_index == -1) 139 | return false; 140 | var num = _index + 1; 141 | _index = num; 142 | var flag1 = num < _stack.Count(); 143 | _currentElement = !flag1 ? default(T) : _stack[_index]; 144 | return flag1; 145 | } 146 | 147 | public T Current 148 | { 149 | get 150 | { 151 | if (_index == -2) 152 | throw new InvalidOperationException("Enumeration Not Started"); 153 | if (_index == -1) 154 | throw new InvalidOperationException("Enumeration Ended"); 155 | return _currentElement; 156 | } 157 | } 158 | 159 | object IEnumerator.Current 160 | { 161 | get { return Current; } 162 | } 163 | 164 | void IEnumerator.Reset() 165 | { 166 | if (_version != _stack._version) 167 | throw new InvalidOperationException("Version Conflict"); 168 | _index = -2; 169 | _currentElement = default(T); 170 | } 171 | } 172 | 173 | public IEnumerator GetEnumerator() 174 | { 175 | return new Enumerator(this); 176 | } 177 | 178 | IEnumerator IEnumerable.GetEnumerator() 179 | { 180 | return GetEnumerator(); 181 | } 182 | } 183 | } -------------------------------------------------------------------------------- /Assets/Scripts/Utils/FixedSizeStack.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5dadefd9b4e68254faa9146ce5c09a76 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Utils/FlyingCamera.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Assets.Scripts.Utils 4 | { 5 | public class FlyingCamera : MonoBehaviour 6 | { 7 | public float MainSpeed = 100.0f; //regular speed 8 | public float ShiftAdd = 250.0f; //multiplied by how long shift is held. Basically running 9 | public float MaxShift = 1000.0f; //Maximum speed when holding shift 10 | public float MouseSensitivity = 0.25f; //How sensitive it with mouse 11 | public bool RotateOnlyIfMousedown = true; 12 | 13 | private Vector3 _lastMousePosition = new Vector3(255, 255, 255); //kind of in the middle of the screen, rather than at the top (play) 14 | private float _totalRun = 1.0f; 15 | 16 | void Update() 17 | { 18 | if (Input.GetMouseButtonDown(1)) 19 | { 20 | _lastMousePosition = Input.mousePosition; 21 | } 22 | 23 | if (!RotateOnlyIfMousedown || (RotateOnlyIfMousedown && Input.GetMouseButton(1))) 24 | { 25 | var mouseDelta = Input.mousePosition - _lastMousePosition; 26 | var rotationDelta = new Vector3(-mouseDelta.y * MouseSensitivity, mouseDelta.x * MouseSensitivity, 0); 27 | transform.eulerAngles = new Vector3( 28 | FlyingCamera.ClampAngle(transform.eulerAngles.x + rotationDelta.x, -89, 89), 29 | transform.eulerAngles.y + rotationDelta.y, 0); 30 | _lastMousePosition = Input.mousePosition; 31 | } 32 | 33 | var p = new Vector3(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical")); 34 | if (Input.GetKey(KeyCode.LeftShift)) 35 | { 36 | _totalRun += Time.deltaTime; 37 | p = p * _totalRun * ShiftAdd; 38 | p.x = Mathf.Clamp(p.x, -MaxShift, MaxShift); 39 | p.y = Mathf.Clamp(p.y, -MaxShift, MaxShift); 40 | p.z = Mathf.Clamp(p.z, -MaxShift, MaxShift); 41 | } 42 | else 43 | { 44 | _totalRun = Mathf.Clamp(_totalRun * 0.5f, 1f, 1000f); 45 | p = p * MainSpeed; 46 | } 47 | 48 | transform.Translate(p * Time.deltaTime); 49 | } 50 | 51 | public static float ClampAngle(float angle, float min, float max) 52 | { 53 | // accepts e.g. -80f, 80f 54 | if (angle < 0f) 55 | angle = 360 + angle; 56 | 57 | if (angle > 180f) 58 | return Mathf.Max(angle, 360 + min); 59 | 60 | return Mathf.Min(angle, max); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Assets/Scripts/Utils/FlyingCamera.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: d6b0207ed7914c74191269f3bfb16d38 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Utils/LazySingleton.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Assets.Scripts.Utils 4 | { 5 | public class LazySingleton : MonoBehaviour where T : MonoBehaviour 6 | { 7 | protected static T _instance; 8 | 9 | // Returns the instance of this singleton 10 | public static T Instance 11 | { 12 | get 13 | { 14 | if (_instance == null) 15 | { 16 | _instance = (T)FindObjectOfType(typeof(T)); 17 | 18 | if (_instance == null) 19 | { 20 | var obj = new GameObject(string.Format("[LazySingleton] {0}", typeof(T).Name)); 21 | var comp = obj.AddComponent(); 22 | _instance = comp; 23 | return comp; 24 | } 25 | } 26 | 27 | return _instance; 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Assets/Scripts/Utils/LazySingleton.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f1f85d1e3fe6bf14f806138bbb16b691 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Utils/MeshUtils.cs: -------------------------------------------------------------------------------- 1 | using UnityEngine; 2 | 3 | namespace Utils 4 | { 5 | public static class MeshUtils 6 | { 7 | public static Mesh GeneratePlane(Vector3 origin, Vector3 axis0, Vector3 axis1, int axis0Vertices, int axis1Vertices, Vector2 uvStart, Vector2 uvEnd) 8 | { 9 | var vertices = new Vector3[axis0Vertices * axis1Vertices]; 10 | var normals = new Vector3[vertices.Length]; 11 | var uvs = new Vector2[vertices.Length]; 12 | var triangles = new int[(axis0Vertices - 1) * (axis1Vertices - 1) * 2 * 3]; 13 | var normal = Vector3.Cross(axis1, axis0).normalized; 14 | 15 | // Vertices 16 | for (var i = 0; i < vertices.Length; i++) 17 | { 18 | var i0 = i / axis1Vertices; 19 | var i1 = i % axis1Vertices; 20 | var localU = i0 / (axis0Vertices - 1f); 21 | var localV = i1 / (axis1Vertices - 1f); 22 | 23 | vertices[i] = origin + localU * axis0 + localV * axis1; 24 | normals[i] = normal; 25 | uvs[i].x = Mathf.Lerp(uvStart.x, uvEnd.x, localU); 26 | uvs[i].y = Mathf.Lerp(uvStart.y, uvEnd.y, localV); 27 | } 28 | 29 | // Triangles 30 | var vertexIndex = 0; 31 | for (var i0 = 0; i0 < axis0Vertices - 1; i0++) 32 | { 33 | for (var i1 = 0; i1 < axis1Vertices - 1; i1++) 34 | { 35 | triangles[vertexIndex++] = (i0 + 0) * axis1Vertices + (i1 + 0); 36 | triangles[vertexIndex++] = (i0 + 1) * axis1Vertices + (i1 + 1); 37 | triangles[vertexIndex++] = (i0 + 1) * axis1Vertices + (i1 + 0); 38 | 39 | triangles[vertexIndex++] = (i0 + 0) * axis1Vertices + (i1 + 0); 40 | triangles[vertexIndex++] = (i0 + 0) * axis1Vertices + (i1 + 1); 41 | triangles[vertexIndex++] = (i0 + 1) * axis1Vertices + (i1 + 1); 42 | } 43 | } 44 | 45 | var mesh = new Mesh() 46 | { 47 | name = $"Plane_{axis0Vertices}x{axis1Vertices}", 48 | vertices = vertices, 49 | normals = normals, 50 | uv = uvs, 51 | triangles = triangles 52 | }; 53 | 54 | mesh.RecalculateBounds(); 55 | return mesh; 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /Assets/Scripts/Utils/MeshUtils.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 5000c274fa97009478b87f4e27e32785 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/Utils/ShowRendererBounds.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using UnityEngine; 7 | 8 | namespace Assets.Scripts.Utils 9 | { 10 | [RequireComponent(typeof(Renderer))] 11 | public class ShowRendererBounds : MonoBehaviour 12 | { 13 | public Color BoundsColor = Color.yellow; 14 | 15 | private Renderer _renderer; 16 | 17 | void OnDrawGizmos() 18 | { 19 | if (_renderer == null) 20 | _renderer = GetComponent(); 21 | 22 | Gizmos.color = BoundsColor; 23 | var bounds = _renderer.bounds; 24 | Gizmos.DrawWireCube(bounds.center, bounds.size); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Assets/Scripts/Utils/ShowRendererBounds.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 73c504204dd15934ca0318c2b26a7111 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /Assets/Scripts/WaterBoundary.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using UnityEngine; 3 | using Utils; 4 | 5 | public class WaterBoundary : MonoBehaviour 6 | { 7 | // Should match terrain size 8 | public Vector3 Size; 9 | 10 | // Material with a special WaterBoundary shader 11 | public Material Material; 12 | 13 | // Resolution should match state - texture resolution 14 | public Vector2Int Resolution = new Vector2Int(512, 512); 15 | 16 | void Start() 17 | { 18 | CreatePlane("Back(Near)", new Vector3(0, 0,0), Vector3.right * Size.x, Resolution.x); 19 | CreatePlane("Front(Far)", new Vector3(Size.x, 0, Size.z), Vector3.left * Size.x, Resolution.x); 20 | CreatePlane("Left", new Vector3(0, 0, Size.z), Vector3.back * Size.z, Resolution.x); 21 | CreatePlane("Right", new Vector3(Size.x, 0, 0), Vector3.forward * Size.z, Resolution.x); 22 | 23 | Material.SetVector("_WorldScale", Size); 24 | } 25 | 26 | void CreatePlane(string objectName, Vector3 origin, Vector3 horizontalAxis, int resolution) 27 | { 28 | var mesh = MeshUtils.GeneratePlane(Vector3.zero, horizontalAxis, 29 | new Vector3(0, Size.y, 0), 30 | resolution, 31 | 2, 32 | Vector2.zero, 33 | Vector2.one); 34 | 35 | var go = new GameObject(objectName); 36 | go.AddComponent().sharedMesh = mesh; 37 | go.AddComponent().material = Material; 38 | go.transform.SetParent(transform); 39 | go.transform.localPosition = origin; 40 | } 41 | } -------------------------------------------------------------------------------- /Assets/Scripts/WaterBoundary.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ebdd905ab35049e6b8ab362d30c0b560 3 | timeCreated: 1584476972 -------------------------------------------------------------------------------- /Assets/Shaders.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 207b54a7908236542acf729ec4d6f336 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Shaders/Erosion.compute: -------------------------------------------------------------------------------- 1 | // List of all separate kernels to be dispatched from CustomTerrain.cs 2 | #pragma kernel RainAndControl 3 | #pragma kernel FluxComputation 4 | #pragma kernel FluxApply 5 | #pragma kernel HydraulicErosion 6 | #pragma kernel SedimentAdvection 7 | #pragma kernel ThermalErosion 8 | #pragma kernel ApplyThermalErosion 9 | 10 | // Number of threads in each kernel 11 | #define NUMTHREADS numthreads(8, 8, 1) 12 | 13 | // Directional maps channel semantics 14 | // It means that for textures with 4-directional data (like flux) 15 | // value for the each direction stored in a separate channel 16 | // For example, LEFT is stored in RED channel 17 | #define LDIR(col) (col.r) 18 | #define RDIR(col) (col.g) 19 | #define TDIR(col) (col.b) 20 | #define BDIR(col) (col.a) 21 | 22 | // State channel semantics 23 | #define TERRAIN_HEIGHT(col) (col.r) 24 | #define WATER_HEIGHT(col) (col.g) 25 | #define SEDIMENT(col) (col.b) 26 | #define HARDNESS(col) (col.a) 27 | #define FULL_HEIGHT(col) ((TERRAIN_HEIGHT(col) + WATER_HEIGHT(col))) 28 | 29 | // Velocity-map channel semantics 30 | #define VELOCITY_X(col) (col.r) 31 | #define VELOCITY_Y(col) (col.g) 32 | 33 | // Sampling macro, just to simplify the code a bit 34 | #define SAMPLE_WITH_OFFSET(tex, x, y) ((tex[id.xy + uint2(x, y)])) 35 | #define CURRENT_SAMPLE(tex) (tex[id.xy]) 36 | #define LEFT_SAMPLE(tex) (SAMPLE_WITH_OFFSET(tex, -1, 0)) 37 | #define RIGHT_SAMPLE(tex) (SAMPLE_WITH_OFFSET(tex, 1, 0)) 38 | #define TOP_SAMPLE(tex) (SAMPLE_WITH_OFFSET(tex, 0, 1)) 39 | #define BOTTOM_SAMPLE(tex) (SAMPLE_WITH_OFFSET(tex, 0, -1)) 40 | 41 | #define SUM_COMPS(v) ((v.r + v.g + v.b + v.a)) 42 | 43 | 44 | /* ======== INPUTS ======== */ 45 | 46 | // Heightmap (R - height, G - water height, B - suspended sediment amount, R - Surface hardness) 47 | RWTexture2D HeightMap; 48 | 49 | // Velocity field (R - velocity x, G - velocity y) 50 | RWTexture2D VelocityMap; 51 | 52 | // Water Flux field (R - left, G - right, B - top, A - bottom) 53 | RWTexture2D FluxMap; 54 | 55 | // Terrain Flux field (R - left, G - right, B - top, A - bottom) 56 | RWTexture2D TerrainFluxMap; 57 | 58 | uint _InputMode; 59 | float4 _InputControls; 60 | 61 | // Fluid simulation properties 62 | uint _Width; 63 | uint _Height; 64 | float _TimeDelta; 65 | float _PipeArea; 66 | float _Gravity; 67 | float _PipeLength; 68 | float2 _CellSize; 69 | float _Evaporation; 70 | float _RainRate; 71 | 72 | // Hydraulic erosion properties 73 | float _SedimentCapacity; 74 | float _MaxErosionDepth; 75 | float _SuspensionRate; 76 | float _DepositionRate; 77 | float _SedimentSofteningRate; 78 | 79 | // Thermal erosion properties 80 | float _ThermalErosionTimeScale; 81 | float _ThermalErosionRate; 82 | float _TalusAngleTangentCoeff; 83 | float _TalusAngleTangentBias; 84 | 85 | float4 SampleBilinear(RWTexture2D tex, float2 uv) 86 | { 87 | float2 uva = floor(uv); 88 | float2 uvb = ceil(uv); 89 | 90 | uint2 id00 = (uint2)uva; // 0 0 91 | uint2 id10 = uint2(uvb.x, uva.y); // 1 0 92 | uint2 id01 = uint2(uva.x, uvb.y); // 0 1 93 | uint2 id11 = (uint2)uvb; // 1 1 94 | 95 | float2 d = uv - uva; 96 | 97 | return 98 | tex[id00] * (1 - d.x) * (1 - d.y) + 99 | tex[id10] * d.x * (1 - d.y) + 100 | tex[id01] * (1 - d.x) * d.y + 101 | tex[id11] * d.x * d.y; 102 | } 103 | 104 | /* Pass 1. Rain simulation and brush drawing */ 105 | [NUMTHREADS] 106 | void RainAndControl(uint3 id : SV_DispatchThreadID) 107 | { 108 | float4 currentState = CURRENT_SAMPLE(HeightMap); 109 | WATER_HEIGHT(currentState) += _TimeDelta * _RainRate; 110 | 111 | // Water-drawing brush 112 | float2 uv = float2((float)id.x / _Width, (float)id.y / _Height); 113 | float2 dist = uv - _InputControls.xy; 114 | if (length(dist) < abs(_InputControls.z)) 115 | { 116 | if(_InputMode == 0) 117 | WATER_HEIGHT(currentState) = max(0, WATER_HEIGHT(currentState) + _InputControls.w * _TimeDelta); 118 | else if (_InputMode == 1) 119 | WATER_HEIGHT(currentState) = max(0, WATER_HEIGHT(currentState) - _InputControls.w * _TimeDelta); 120 | else if (_InputMode == 2) 121 | TERRAIN_HEIGHT(currentState) = max(0, TERRAIN_HEIGHT(currentState) + _InputControls.w * _TimeDelta); 122 | else if (_InputMode == 3) 123 | TERRAIN_HEIGHT(currentState) = max(0, TERRAIN_HEIGHT(currentState) - _InputControls.w * _TimeDelta); 124 | } 125 | 126 | // Write new state to the HeightMap 127 | CURRENT_SAMPLE(HeightMap) = currentState; 128 | } 129 | 130 | 131 | /* Pass 2. Flux field computation */ 132 | [NUMTHREADS] 133 | void FluxComputation(uint3 id : SV_DispatchThreadID) 134 | { 135 | // Sample the heighmap (state map) 136 | float4 state = CURRENT_SAMPLE(HeightMap); 137 | float4 stateLeft = LEFT_SAMPLE(HeightMap); 138 | float4 stateRight = RIGHT_SAMPLE(HeightMap); 139 | float4 stateTop = TOP_SAMPLE(HeightMap); 140 | float4 stateBottom = BOTTOM_SAMPLE(HeightMap); 141 | 142 | float terrainHeight = TERRAIN_HEIGHT(state); 143 | float waterHeight = WATER_HEIGHT(state); 144 | 145 | // Flow simulation using shallow-water model. Computation of the velocity field and water height changes. 146 | // Sample flux 147 | float4 outputFlux = CURRENT_SAMPLE(FluxMap); 148 | 149 | // Overall height difference in each direction 150 | float4 heightDifference = FULL_HEIGHT(state) - float4( 151 | FULL_HEIGHT(stateLeft), 152 | FULL_HEIGHT(stateRight), 153 | FULL_HEIGHT(stateTop), 154 | FULL_HEIGHT(stateBottom)); 155 | 156 | // Output flux 157 | outputFlux = max(0, outputFlux + _TimeDelta * _Gravity * _PipeArea * heightDifference / _PipeLength); 158 | 159 | /* 160 | Rescale flux 161 | The total outflow should not exceed the total amount 162 | of the water in the given cell.If the calculated value is 163 | larger than the current amount in the given cell, then flux will 164 | be scaled down with an appropriate factor 165 | */ 166 | outputFlux *= min(1, waterHeight * _CellSize.x * _CellSize.y / (SUM_COMPS(outputFlux) * _TimeDelta)); 167 | 168 | // Boundaries (uncomment thisif you want water to bounce of boundaries) 169 | if (id.x == 0) LDIR(outputFlux) = 0; 170 | if (id.y == 0) BDIR(outputFlux) = 0; 171 | if (id.x == _Width - 1) RDIR(outputFlux) = 0; 172 | if (id.y == _Height - 1) TDIR(outputFlux) = 0; 173 | 174 | // Write new flux to the FluxMap 175 | CURRENT_SAMPLE(FluxMap) = max(0, outputFlux); 176 | } 177 | 178 | 179 | /* Pass 3. Applying fluxes to the actual cells and changing weter height */ 180 | [NUMTHREADS] 181 | void FluxApply(uint3 id : SV_DispatchThreadID) 182 | { 183 | float4 state = CURRENT_SAMPLE(HeightMap); 184 | float4 outputFlux = CURRENT_SAMPLE(FluxMap); 185 | float4 inputFlux = float4( 186 | RDIR(LEFT_SAMPLE(FluxMap)), 187 | LDIR(RIGHT_SAMPLE(FluxMap)), 188 | BDIR(TOP_SAMPLE(FluxMap)), 189 | TDIR(BOTTOM_SAMPLE(FluxMap))); 190 | float waterHeightBefore = WATER_HEIGHT(state); 191 | 192 | // Water surface and velocity field update 193 | // volume is changing by amount on incoming fluid volume minus outgoing 194 | float volumeDelta = SUM_COMPS(inputFlux) - SUM_COMPS(outputFlux); 195 | 196 | // Then, we update the water height in the current (x, y) cell: 197 | WATER_HEIGHT(state) += _TimeDelta * volumeDelta / (_CellSize.x * _CellSize.y); 198 | 199 | // Write new state to the HeightMap 200 | CURRENT_SAMPLE(HeightMap) = state; 201 | 202 | // Compute new velocity from flux to the VelocityMap 203 | CURRENT_SAMPLE(VelocityMap) = float2( 204 | 0.5 * (LDIR(inputFlux) - LDIR(outputFlux) + RDIR(outputFlux) - RDIR(inputFlux)), 205 | 0.5 * (BDIR(inputFlux) - BDIR(outputFlux) + TDIR(outputFlux) - TDIR(inputFlux))); 206 | /// _PipeLength * 0.5 * (waterHeightBefore + WATER_HEIGHT(state)); 207 | } 208 | 209 | 210 | /* Pass 4. Terrain hydraulic erosion and deposition */ 211 | [NUMTHREADS] 212 | void HydraulicErosion(uint3 id : SV_DispatchThreadID) 213 | { 214 | // Sample the heighmap (state map) 215 | float4 state = CURRENT_SAMPLE(HeightMap); 216 | float4 stateLeft = LEFT_SAMPLE(HeightMap); 217 | float4 stateRight = RIGHT_SAMPLE(HeightMap); 218 | float4 stateTop = TOP_SAMPLE(HeightMap); 219 | float4 stateBottom = BOTTOM_SAMPLE(HeightMap); 220 | float2 velocity = CURRENT_SAMPLE(VelocityMap); 221 | 222 | 223 | // Tilt angle computation 224 | float3 dhdx = float3(2 * _CellSize.x, TERRAIN_HEIGHT(stateRight) - TERRAIN_HEIGHT(stateLeft), 0); 225 | float3 dhdy = float3(0, TERRAIN_HEIGHT(stateTop) - TERRAIN_HEIGHT(stateBottom), 2 * _CellSize.y); 226 | float3 normal = cross(dhdx, dhdy); 227 | 228 | float sinTiltAngle = abs(normal.y) / length(normal); 229 | 230 | // Erosion limiting factor 231 | float lmax = saturate(1 - max(0, _MaxErosionDepth - WATER_HEIGHT(state)) / _MaxErosionDepth); 232 | float sedimentTransportCapacity = _SedimentCapacity * length(velocity) * min(sinTiltAngle, 0.05) * lmax; 233 | 234 | if (SEDIMENT(state) < sedimentTransportCapacity) 235 | { 236 | float mod = _TimeDelta * _SuspensionRate * HARDNESS(state) * (sedimentTransportCapacity - SEDIMENT(state)); 237 | TERRAIN_HEIGHT(state) -= mod; 238 | SEDIMENT(state) += mod; 239 | WATER_HEIGHT(state) += mod; 240 | } 241 | else 242 | { 243 | float mod = _TimeDelta * _DepositionRate * (SEDIMENT(state) - sedimentTransportCapacity); 244 | TERRAIN_HEIGHT(state) += mod; 245 | SEDIMENT(state) -= mod; 246 | WATER_HEIGHT(state) -= mod; 247 | } 248 | 249 | // Water evaporation. 250 | WATER_HEIGHT(state) *= 1 - _Evaporation * _TimeDelta; 251 | 252 | // Hardness update 253 | HARDNESS(state) = HARDNESS(state) - _TimeDelta * _SedimentSofteningRate * _SuspensionRate * (SEDIMENT(state) - sedimentTransportCapacity); 254 | HARDNESS(state) = clamp(HARDNESS(state), 0.1, 1); 255 | 256 | // Write heighmap 257 | CURRENT_SAMPLE(HeightMap) = state; 258 | } 259 | 260 | 261 | /* Pass 5. Terrain hydraulic erosion second step. Advecting sediment */ 262 | [NUMTHREADS] 263 | void SedimentAdvection(uint3 id : SV_DispatchThreadID) 264 | { 265 | float4 state = CURRENT_SAMPLE(HeightMap); 266 | float2 velocity = CURRENT_SAMPLE(VelocityMap); 267 | 268 | // Sediment advection 269 | SEDIMENT(state) = SEDIMENT(SampleBilinear(HeightMap, id.xy - velocity * _TimeDelta)); 270 | 271 | // Write heightmap 272 | CURRENT_SAMPLE(HeightMap) = state; 273 | } 274 | 275 | 276 | /* Pass 6. Terrain thermal erosion */ 277 | [NUMTHREADS] 278 | void ThermalErosion(uint3 id : SV_DispatchThreadID) 279 | { 280 | float4 state = CURRENT_SAMPLE(HeightMap); 281 | 282 | // Neighbors 283 | float4 neighborHeights = float4( 284 | TERRAIN_HEIGHT(LEFT_SAMPLE(HeightMap)), 285 | TERRAIN_HEIGHT(RIGHT_SAMPLE(HeightMap)), 286 | TERRAIN_HEIGHT(TOP_SAMPLE(HeightMap)), 287 | TERRAIN_HEIGHT(BOTTOM_SAMPLE(HeightMap)) 288 | ); 289 | 290 | // Overall height difference in each direction 291 | float4 heightDifference = max(0, TERRAIN_HEIGHT(state) - neighborHeights); 292 | float maxHeightDifference = max(max(heightDifference.x, heightDifference.y), max(heightDifference.z, heightDifference.w)); 293 | 294 | // First, we need to compute the amount of terrain to be moved from the current cell 295 | // It is capped at [Area * MaxHeightDifference / 2] because it will oscillate if we will allow 296 | // more mass to flow per update 297 | // ErosionRate and Hardness are just control variables to reduce the erosion where and when needed 298 | float volumeToBeMoved = _CellSize.x * _CellSize.y * maxHeightDifference * 0.5 299 | * _ThermalErosionRate * HARDNESS(state); 300 | 301 | // Compute angles for every neighbor 302 | // Actually a tan(angle) 303 | // NOTE: If Cellsize.X and _Cellsize.y are different 304 | // you need to use .x for first 2 components and .y for last 2 305 | float4 tanAngle = heightDifference / _CellSize.x; 306 | 307 | // We need to define a threshold for the angle to identify in which direction the mass is falling 308 | // It based on hardness of the material and some more control variables 309 | float treshold = HARDNESS(state) * _TalusAngleTangentCoeff + _TalusAngleTangentBias; 310 | 311 | // Next we need to set proportions that defines how much mass is transfered in each direction 312 | // Some directions will not contribute because of not enough steep angles 313 | // We are 314 | float4 k = 0; 315 | 316 | if (tanAngle.x > treshold) 317 | k.x = heightDifference.x; 318 | 319 | if (tanAngle.y > treshold) 320 | k.y = heightDifference.y; 321 | 322 | if (tanAngle.z > treshold) 323 | k.z = heightDifference.z; 324 | 325 | if (tanAngle.w > treshold) 326 | k.w = heightDifference.w; 327 | 328 | // Output flux 329 | float sumProportions = SUM_COMPS(k); 330 | float4 outputFlux = 0; 331 | 332 | if (sumProportions > 0) 333 | outputFlux = volumeToBeMoved * k / sumProportions; 334 | 335 | // Boundaries (uncomment thisif you want water to bounce of boundaries) 336 | if (id.x == 0) LDIR(outputFlux) = 0; 337 | if (id.y == 0) BDIR(outputFlux) = 0; 338 | if (id.x == _Width - 1) RDIR(outputFlux) = 0; 339 | if (id.y == _Height - 1) TDIR(outputFlux) = 0; 340 | 341 | CURRENT_SAMPLE(TerrainFluxMap) = outputFlux; 342 | } 343 | 344 | /* Pass 7. Apply thermal erosion */ 345 | [NUMTHREADS] 346 | void ApplyThermalErosion(uint3 id : SV_DispatchThreadID) 347 | { 348 | float4 state = CURRENT_SAMPLE(HeightMap); 349 | float4 outputFlux = CURRENT_SAMPLE(TerrainFluxMap); 350 | float4 inputFlux = float4( 351 | RDIR(LEFT_SAMPLE(TerrainFluxMap)), 352 | LDIR(RIGHT_SAMPLE(TerrainFluxMap)), 353 | BDIR(TOP_SAMPLE(TerrainFluxMap)), 354 | TDIR(BOTTOM_SAMPLE(TerrainFluxMap))); 355 | 356 | // Volume is changing by amount on incoming mass minus outgoing mass 357 | float volumeDelta = SUM_COMPS(inputFlux) - SUM_COMPS(outputFlux); 358 | 359 | // Then, we update the terrain height in the current (x, y) cell 360 | // min - is to prevent addind more mass than in flux 361 | TERRAIN_HEIGHT(state) += min(1, _TimeDelta * _ThermalErosionTimeScale) * volumeDelta; 362 | 363 | // Write new state to the HeightMap 364 | CURRENT_SAMPLE(HeightMap) = state; 365 | } -------------------------------------------------------------------------------- /Assets/Shaders/Erosion.compute.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fcfc55914f9fdb646be1044044c2d042 3 | ComputeShaderImporter: 4 | externalObjects: {} 5 | currentAPIMask: 4 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Shaders/InitHeightmap.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/InitHeightMap" 2 | { 3 | Properties 4 | { 5 | _MainTex ("Texture", 2D) = "white" {} 6 | [NoScaleOffset] _Hardness("Texture", 2D) = "white" {} 7 | _SeaLevel("SeaLevel", float) = 0 8 | _Scale("Scale", float) = 1 9 | _Bias("Bias", float) = 0 10 | } 11 | SubShader 12 | { 13 | // No culling or depth 14 | Cull Off ZWrite Off ZTest Always 15 | 16 | Pass 17 | { 18 | CGPROGRAM 19 | #pragma vertex vert 20 | #pragma fragment frag 21 | 22 | #include "UnityCG.cginc" 23 | 24 | struct appdata 25 | { 26 | float4 vertex : POSITION; 27 | float2 uv : TEXCOORD0; 28 | }; 29 | 30 | struct v2f 31 | { 32 | float2 uv : TEXCOORD0; 33 | float4 vertex : SV_POSITION; 34 | }; 35 | 36 | v2f vert (appdata v) 37 | { 38 | v2f o; 39 | o.vertex = UnityObjectToClipPos(v.vertex); 40 | o.uv = v.uv; 41 | return o; 42 | } 43 | 44 | sampler2D _MainTex; 45 | sampler2D _Hardness; 46 | float2 _MainTex_TexelSize; 47 | float _Scale; 48 | float _Bias; 49 | float _SeaLevel; 50 | 51 | fixed4 frag (v2f i) : SV_Target 52 | { 53 | float4 col = tex2D(_MainTex, i.uv); 54 | 55 | // Terrain height 56 | col.r = max(0, col.r * _Scale + _Bias); 57 | 58 | // Water height 59 | col.g = max(0, _SeaLevel - col.r); 60 | 61 | // Suspended sediment 62 | col.b = 0; 63 | 64 | // Hardness 65 | half h = tex2D(_Hardness, i.uv); 66 | col.a = saturate(0.2 + col.r * 0.8 * h); 67 | 68 | return col; 69 | } 70 | ENDCG 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Assets/Shaders/InitHeightmap.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 4697a06caf91b774db1e1b797db9cb3c 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/StateCopy.shader: -------------------------------------------------------------------------------- 1 | Shader "Hidden/Copy" 2 | { 3 | SubShader 4 | { 5 | Cull Off 6 | ZWrite Off 7 | ZTest Always 8 | 9 | Pass 10 | { 11 | CGPROGRAM 12 | #pragma vertex vert_img 13 | #pragma fragment frag 14 | 15 | #include "UnityCG.cginc" 16 | 17 | sampler2D _MainTex; 18 | sampler2D _HTex; 19 | sampler2D _PrevTex; 20 | float _Scale; 21 | float _Bias; 22 | int _SrcChannel; 23 | int _TgtChannel; 24 | 25 | fixed4 frag (v2f_img i) : SV_Target 26 | { 27 | float colSrc = UnpackHeightmap(tex2D(_HTex, i.uv)); 28 | float4 colPrev = tex2D(_PrevTex, i.uv); 29 | 30 | colPrev.r = colSrc * _Scale + _Bias; 31 | return colPrev; 32 | } 33 | ENDCG 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Assets/Shaders/StateCopy.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 9aa76b120c624c9db0eb0982a8d4b34e 3 | timeCreated: 1583968588 -------------------------------------------------------------------------------- /Assets/Shaders/Surface.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/Terrain" { 2 | Properties{ 3 | _MainTex("Texture", 2D) = "white" {} 4 | _NormalMap("Normals", 2D) = "bump" {} 5 | [NoScaleOffset] _StateTex("State", 2D) = "black" {} 6 | [NoScaleOffset] _NormalStrength("NormalStrength", Range(0.1, 100)) = 0.5 7 | _BumpScale("_BumpScale", Range(0.1, 100)) = 1 8 | } 9 | SubShader 10 | { 11 | Tags { "Queue"="Geometry" "RenderType"="Opaque" "IgnoreProjector"="True"} 12 | 13 | Pass 14 | { 15 | Tags {"LightMode"="ForwardBase" } 16 | 17 | CGPROGRAM 18 | #pragma vertex vert 19 | #pragma fragment frag 20 | #include "UnityCG.cginc" 21 | #include "Lighting.cginc" 22 | 23 | // compile shader into multiple variants, with and without shadows 24 | // (we don't care about any lightmaps yet, so skip these variants) 25 | #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight multi_compile_fog 26 | #include "AutoLight.cginc" 27 | 28 | struct v2f 29 | { 30 | float2 uv : TEXCOORD0; 31 | float2 uvState : TEXCOORD1; 32 | float4 pos : SV_POSITION; 33 | SHADOW_COORDS(2) 34 | UNITY_FOG_COORDS(3) 35 | }; 36 | 37 | float _NormalStrength; 38 | sampler2D _MainTex; 39 | float4 _MainTex_ST; 40 | 41 | sampler2D _NormalMap; 42 | float _BumpScale; 43 | 44 | sampler2D _StateTex; 45 | float2 _StateTex_TexelSize; 46 | 47 | #define WATER_HEIGHT(s) (s.g) 48 | #define TERRAIN_HEIGHT(s) (s.r) 49 | #define FULL_HEIGHT(s) (TERRAIN_HEIGHT(s) + WATER_HEIGHT(s)) 50 | 51 | v2f vert(appdata_base v) 52 | { 53 | float4 state = tex2Dlod(_StateTex, float4(v.texcoord.x, v.texcoord.y, 0, 0)); 54 | v.vertex.y += TERRAIN_HEIGHT(state); 55 | 56 | v2f o; 57 | o.pos = UnityObjectToClipPos(v.vertex); 58 | o.uv = v.texcoord * _MainTex_ST.xy + _MainTex_ST.zw; 59 | o.uvState = v.texcoord; 60 | 61 | TRANSFER_SHADOW(o) 62 | UNITY_TRANSFER_FOG(o, o.pos); 63 | return o; 64 | } 65 | 66 | fixed4 frag(v2f i) : SV_Target 67 | { 68 | float2 du = float2(_StateTex_TexelSize.x * 0.5, 0); 69 | float2 dv = float2(0, _StateTex_TexelSize.y * 0.5); 70 | float4 state_l = tex2D(_StateTex, i.uvState + du); 71 | float4 state_r = tex2D(_StateTex, i.uvState - du); 72 | float4 state_t = tex2D(_StateTex, i.uvState + dv); 73 | float4 state_b = tex2D(_StateTex, i.uvState - dv); 74 | 75 | half dhdu = _NormalStrength * 0.5 * (TERRAIN_HEIGHT(state_r) - TERRAIN_HEIGHT(state_l)); 76 | half dhdv = _NormalStrength * 0.5 * (TERRAIN_HEIGHT(state_b) - TERRAIN_HEIGHT(state_t)); 77 | 78 | float3 normal = float3(dhdu, 1, dhdv); 79 | float3 bump = UnpackScaleNormal(tex2D(_NormalMap, i.uv), _BumpScale); 80 | 81 | float3 worldNormal = UnityObjectToWorldNormal(normalize(normal + bump)); 82 | 83 | half nl = max(0, dot(worldNormal, _WorldSpaceLightPos0.xyz)); 84 | half diff = nl * _LightColor0.rgb; 85 | half ambient = ShadeSH9(half4(worldNormal, 1)); 86 | 87 | fixed4 col = tex2D(_MainTex, i.uv); 88 | 89 | // compute shadow attenuation (1.0 = fully lit, 0.0 = fully shadowed) 90 | fixed shadow = SHADOW_ATTENUATION(i); 91 | // darken light's illumination with shadow, keep ambient intact 92 | fixed3 lighting = diff * shadow + ambient; 93 | col.rgb *= lighting; 94 | 95 | UNITY_APPLY_FOG(i.fogCoord, col); 96 | 97 | 98 | return col; 99 | } 100 | ENDCG 101 | } 102 | 103 | Pass 104 | { 105 | Tags {"LightMode" = "ShadowCaster"} 106 | LOD 300 107 | 108 | ZWrite On 109 | ZTest Less 110 | Offset 1, 1 111 | Cull Off 112 | //ZWrite Off 113 | 114 | CGPROGRAM 115 | #pragma vertex vert 116 | #pragma fragment frag 117 | #pragma multi_compile_shadowcaster 118 | #pragma fragmentoption ARB_precision_hint_fastest 119 | #include "UnityCG.cginc" 120 | 121 | struct v2f { 122 | V2F_SHADOW_CASTER; 123 | }; 124 | 125 | sampler2D _StateTex; 126 | 127 | v2f vert(appdata_base v) 128 | { 129 | float4 state = tex2Dlod(_StateTex, float4(v.texcoord.x, v.texcoord.y, 0, 0)); 130 | v.vertex.y += state.r; 131 | 132 | v2f o; 133 | TRANSFER_SHADOW_CASTER_NORMALOFFSET(o) 134 | return o; 135 | } 136 | 137 | float4 frag(v2f i) : SV_Target 138 | { 139 | SHADOW_CASTER_FRAGMENT(i) 140 | } 141 | ENDCG 142 | } 143 | } 144 | } -------------------------------------------------------------------------------- /Assets/Shaders/Surface.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a116650e46f9f3148a1f6d5c4d29be51 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/Water.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/Water" { 2 | Properties{ 3 | _Color("Color", Color) = (0, 0, 1, 0.8) 4 | [NoScaleOffset] _StateTex("State", 2D) = "black" {} 5 | _NormalStrength("NormalStrength", Range(0.1, 100)) = 0.5 6 | _Metallic("Metallic", Range(0, 1)) = 0.5 7 | _Smoothness("Smoothness", Range(0, 1)) = 1 8 | _DepthDecay("DepthDecay", float) = 1 9 | } 10 | 11 | SubShader 12 | { 13 | Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" } 14 | 15 | Pass 16 | { 17 | Tags {"LightMode" = "ForwardBase" "IgnoreProjector" = "True" } 18 | //LOD 300 19 | Blend SrcAlpha OneMinusSrcAlpha 20 | //Zwrite Off 21 | 22 | CGPROGRAM 23 | #pragma vertex vert 24 | #pragma fragment frag 25 | #include "UnityCG.cginc" 26 | #include "Lighting.cginc" 27 | #include "UnityPBSLighting.cginc" 28 | 29 | // compile shader into multiple variants, with and without shadows 30 | // (we don't care about any lightmaps yet, so skip these variants) 31 | #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight multi_compile_fog 32 | #include "AutoLight.cginc" 33 | 34 | struct v2f 35 | { 36 | float2 uvState : TEXCOORD0; 37 | float4 pos : SV_POSITION; 38 | float3 worldPos : TEXCOORD1; 39 | float4 screenPos : TEXCOORD2; 40 | SHADOW_COORDS(3) 41 | UNITY_FOG_COORDS(4) 42 | }; 43 | 44 | sampler2D _StateTex; 45 | float2 _StateTex_TexelSize; 46 | float _NormalStrength; 47 | float _Metallic; 48 | float _Smoothness; 49 | fixed4 _Color; 50 | 51 | sampler2D _CameraDepthTexture; 52 | float4 _CameraDepthTexture_TexelSize; 53 | float _DepthDecay; 54 | 55 | #define WATER_HEIGHT(s) (s.g) 56 | #define TERRAIN_HEIGHT(s) (s.r) 57 | #define FULL_HEIGHT(s) (TERRAIN_HEIGHT(s) + WATER_HEIGHT(s)) 58 | 59 | v2f vert(appdata_base v) 60 | { 61 | float4 state = tex2Dlod(_StateTex, float4(v.texcoord.x, v.texcoord.y, 0, 0)); 62 | v.vertex.y += FULL_HEIGHT(state); 63 | 64 | v2f o; 65 | o.pos = UnityObjectToClipPos(v.vertex); 66 | o.uvState = v.texcoord; 67 | o.worldPos = mul(unity_ObjectToWorld, v.vertex); 68 | o.screenPos = ComputeScreenPos(o.pos); 69 | 70 | TRANSFER_SHADOW(o) 71 | UNITY_TRANSFER_FOG(o, o.pos); 72 | return o; 73 | } 74 | 75 | fixed4 frag(v2f i) : SV_Target 76 | { 77 | float4 state = tex2D(_StateTex, i.uvState); 78 | clip(WATER_HEIGHT(state) - 0.08); 79 | 80 | float2 du = float2(_StateTex_TexelSize.x * 0.5, 0); 81 | float2 dv = float2(0, _StateTex_TexelSize.y * 0.5); 82 | 83 | float4 state_l = tex2D(_StateTex, i.uvState + du); 84 | float4 state_r = tex2D(_StateTex, i.uvState - du); 85 | float4 state_t = tex2D(_StateTex, i.uvState + dv); 86 | float4 state_b = tex2D(_StateTex, i.uvState - dv); 87 | 88 | half dhdu = _NormalStrength * 0.5 * (FULL_HEIGHT(state_r) - FULL_HEIGHT(state_l)); 89 | half dhdv = _NormalStrength * 0.5 * (FULL_HEIGHT(state_b) - FULL_HEIGHT(state_t)); 90 | 91 | float3 normal = float3(dhdu, 1, dhdv); 92 | float3 worldNormal = UnityObjectToWorldNormal(normalize(normal)); 93 | 94 | 95 | float3 lightDir = _WorldSpaceLightPos0.xyz; 96 | float3 viewDir = normalize(_WorldSpaceCameraPos - i.worldPos); 97 | 98 | float3 lightColor = _LightColor0.rgb; 99 | float3 albedo = _Color.rgb; 100 | 101 | float3 specularTint; 102 | float oneMinusReflectivity; 103 | albedo = DiffuseAndSpecularFromMetallic( 104 | albedo, _Metallic, specularTint, oneMinusReflectivity 105 | ); 106 | 107 | UnityLight light; 108 | light.color = lightColor; 109 | light.dir = lightDir; 110 | light.ndotl = DotClamped(normal, lightDir); 111 | UnityIndirect indirectLight; 112 | indirectLight.diffuse = 0; 113 | indirectLight.specular = 0; 114 | float3 reflectionDir = reflect(-viewDir, normal); 115 | Unity_GlossyEnvironmentData envData; 116 | envData.roughness = 1 - _Smoothness; 117 | envData.reflUVW = reflectionDir; 118 | indirectLight.specular = Unity_GlossyEnvironment( 119 | UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData 120 | ); 121 | 122 | half4 c = UNITY_BRDF_PBS( 123 | albedo, specularTint, 124 | oneMinusReflectivity, _Smoothness, 125 | normal, viewDir, 126 | light, indirectLight 127 | ); 128 | 129 | float2 uv = i.screenPos.xy / i.screenPos.w; 130 | #if UNITY_UV_STARTS_AT_TOP 131 | if (_CameraDepthTexture_TexelSize.y < 0) { 132 | uv.y = 1 - uv.y; 133 | } 134 | #endif 135 | 136 | float backgroundDepth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv)); 137 | float surfaceDepth = UNITY_Z_0_FAR_FROM_CLIPSPACE(i.screenPos.z); 138 | float depthDifference = (backgroundDepth - surfaceDepth); 139 | c.a = saturate(clamp(depthDifference * _DepthDecay * 4, 0, 0.8) + 0.4 * saturate(depthDifference * _DepthDecay * 0.5)); 140 | //c.rgb = depthDifference; 141 | return c; 142 | } 143 | ENDCG 144 | } 145 | } 146 | 147 | 148 | 149 | /* 150 | SubShader{ 151 | Tags { "RenderType" = "Transparent" "Queue"="Transparent" } 152 | LOD 200 153 | 154 | ZWrite On 155 | 156 | CGPROGRAM 157 | #include "UnityCG.cginc" 158 | 159 | #pragma surface surf Standard vertex:vert alpha:blend 160 | #pragma target 3.0 161 | struct Input { 162 | float2 uv_MainTex; 163 | float3 worldRefl; 164 | float4 screenPos; 165 | INTERNAL_DATA 166 | }; 167 | 168 | float _NormalStrength; 169 | float _SampleSize; 170 | fixed4 _Color; 171 | sampler2D _MainTex; 172 | sampler2D _StateTex; 173 | float2 _StateTex_TexelSize; 174 | float4 _InputControls; 175 | half _Metallic; 176 | half _Smoothness; 177 | sampler2D _CameraDepthTexture; 178 | float4 _CameraDepthTexture_TexelSize; 179 | float _DepthDecay; 180 | 181 | #define WATER_HEIGHT(s) (s.g) 182 | #define TERRAIN_HEIGHT(s) (s.r) 183 | #define FULL_HEIGHT(s) (TERRAIN_HEIGHT(s) + WATER_HEIGHT(s)) 184 | 185 | 186 | void vert(inout appdata_full v) { 187 | float4 state = tex2Dlod(_StateTex, float4(v.texcoord.x, v.texcoord.y, 0, 0)); 188 | v.vertex.y += state.r + state.g; 189 | } 190 | 191 | void surf(Input IN, inout SurfaceOutputStandard o) { 192 | // Normals 193 | float4 state = tex2D(_StateTex, IN.uv_MainTex.x); 194 | float4 state_l = tex2D(_StateTex, float2(IN.uv_MainTex.x + _StateTex_TexelSize.x, IN.uv_MainTex.y)); 195 | float4 state_r = tex2D(_StateTex, float2(IN.uv_MainTex.x - _StateTex_TexelSize.x, IN.uv_MainTex.y)); 196 | float4 state_t = tex2D(_StateTex, float2(IN.uv_MainTex.x, IN.uv_MainTex.y + _StateTex_TexelSize.y)); 197 | float4 state_b = tex2D(_StateTex, float2(IN.uv_MainTex.x, IN.uv_MainTex.y - _StateTex_TexelSize.y)); 198 | 199 | half dhhx = 0.5 * (FULL_HEIGHT(state_r) - FULL_HEIGHT(state_l)); 200 | half dhhy = 0.5 * (FULL_HEIGHT(state_t) - FULL_HEIGHT(state_b)); 201 | 202 | 203 | //half dx = 0.5 * (FULL_HEIGHT(state_l) - FULL_HEIGHT(state)) - 0.5 * (FULL_HEIGHT(state_r) - FULL_HEIGHT(state)); 204 | //half dz = 0.5 * (FULL_HEIGHT(state_t) - FULL_HEIGHT(state)) - 0.5 * (FULL_HEIGHT(state_b) - FULL_HEIGHT(state)); 205 | half3 normal = half3(_NormalStrength * dhhx, 1, _NormalStrength * dhhy); 206 | //o.Normal = UnityObjectToWorldNormal(normalize(normal)); 207 | //o.Normal = normalize(normal); 208 | 209 | 210 | // Brush 211 | float brushPresence = saturate(sign(abs(_InputControls.z) - length(IN.uv_MainTex - _InputControls.xy))); 212 | 213 | float2 uv = IN.screenPos.xy / IN.screenPos.w; 214 | #if UNITY_UV_STARTS_AT_TOP 215 | if (_CameraDepthTexture_TexelSize.y < 0) { 216 | uv.y = 1 - uv.y; 217 | } 218 | #endif 219 | 220 | float backgroundDepth = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, uv)); 221 | float surfaceDepth = UNITY_Z_0_FAR_FROM_CLIPSPACE(IN.screenPos.z); 222 | float depthDifference = (backgroundDepth - surfaceDepth); 223 | 224 | 225 | //clip(state.g - 0.08 + brushPresence); 226 | 227 | o.Metallic = _Metallic; 228 | o.Smoothness = _Smoothness; 229 | o.Alpha = saturate(clamp(depthDifference * _DepthDecay * 4, 0, 0.8) + 0.4 * saturate(depthDifference * _DepthDecay * 0.5)); 230 | //o.Alpha = _Color.a * saturate(2 * state.g); 231 | //o.Albedo = tex2D(_MainTex, IN.uv_MainTex).rgb * _Color.rgb * (1 - d * d * 0.1); 232 | //o.Albedo = (o.Normal + 1) * 0.5; 233 | o.Albedo = _Color.rgb * (1 - clamp(depthDifference * _DepthDecay, 0, 0.6)); 234 | 235 | //o.Alpha = 1; 236 | //o.Albedo = saturate(1 - depthDifference * _DepthDecay); 237 | 238 | o.Alpha = max(o.Alpha, brushPresence); 239 | o.Albedo = (1 - brushPresence) * o.Albedo + brushPresence * float3(1, 0, 0); 240 | 241 | } 242 | ENDCG 243 | } 244 | */ 245 | Fallback "Diffuse" 246 | } -------------------------------------------------------------------------------- /Assets/Shaders/Water.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 26265a6f920893341be359ac6c3dc795 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Shaders/WaterBoundary.shader: -------------------------------------------------------------------------------- 1 | Shader "Custom/WaterBoundary" { 2 | Properties{ 3 | _Color("Color", Color) = (0, 0, 1, 0.8) 4 | [NoScaleOffset] _StateTex("State", 2D) = "black" {} 5 | } 6 | 7 | SubShader 8 | { 9 | Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" } 10 | 11 | Pass 12 | { 13 | Tags {"LightMode" = "ForwardBase" "IgnoreProjector" = "True" } 14 | //LOD 300 15 | Blend SrcAlpha OneMinusSrcAlpha 16 | //Zwrite Off 17 | 18 | CGPROGRAM 19 | #pragma vertex vert 20 | #pragma fragment frag 21 | #include "UnityCG.cginc" 22 | #include "Lighting.cginc" 23 | #include "UnityPBSLighting.cginc" 24 | 25 | // compile shader into multiple variants, with and without shadows 26 | // (we don't care about any lightmaps yet, so skip these variants) 27 | #pragma multi_compile_fwdbase nolightmap nodirlightmap nodynlightmap novertexlight multi_compile_fog 28 | #include "AutoLight.cginc" 29 | 30 | struct v2f 31 | { 32 | float2 uvState : TEXCOORD0; 33 | float4 pos : SV_POSITION; 34 | float3 worldPos : TEXCOORD1; 35 | float4 screenPos : TEXCOORD2; 36 | SHADOW_COORDS(3) 37 | UNITY_FOG_COORDS(4) 38 | }; 39 | 40 | sampler2D _StateTex; 41 | float2 _StateTex_TexelSize; 42 | float3 _WorldScale; 43 | fixed4 _Color; 44 | 45 | #define WATER_HEIGHT(s) (s.g) 46 | #define TERRAIN_HEIGHT(s) (s.r) 47 | #define FULL_HEIGHT(s) (TERRAIN_HEIGHT(s) + WATER_HEIGHT(s)) 48 | 49 | v2f vert(appdata_base v) 50 | { 51 | float4 worldPos = mul(unity_ObjectToWorld, v.vertex); 52 | 53 | // Notice that state is sample at uv = worldPos / _WorldScale 54 | float4 state = tex2Dlod(_StateTex, float4(worldPos.x / _WorldScale.x, worldPos.z / _WorldScale.z, 0, 0)); 55 | 56 | // if mesh uv.y is 0 - then y of vertex = terrain, if 1 then y of vertex = water 57 | v.vertex.y = TERRAIN_HEIGHT(state) + v.texcoord.y * WATER_HEIGHT(state); 58 | 59 | v2f o; 60 | o.pos = UnityObjectToClipPos(v.vertex); 61 | o.uvState = v.texcoord; 62 | o.worldPos = mul(unity_ObjectToWorld, v.vertex); 63 | o.screenPos = ComputeScreenPos(o.pos); 64 | 65 | TRANSFER_SHADOW(o) 66 | UNITY_TRANSFER_FOG(o, o.pos); 67 | return o; 68 | } 69 | 70 | fixed4 frag(v2f i) : SV_Target 71 | { 72 | // return simple Color 73 | // TODO: Adapt water shader 74 | return _Color; 75 | } 76 | ENDCG 77 | } 78 | } 79 | 80 | Fallback "Diffuse" 81 | } -------------------------------------------------------------------------------- /Assets/Shaders/WaterBoundary.shader.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: c5e7ca4a9f5fa9a48b096e67508a921e 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /Assets/Textures.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 89da0b40929f6ba448f314e8472ff6db 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Textures/Noise.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 58fae7a414b84434ca5a549148d7000a 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Textures/Noise/perlin_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/0e59f7c42b5ccbc8bc637b7a6435c3af648bc8b6/Assets/Textures/Noise/perlin_1.png -------------------------------------------------------------------------------- /Assets/Textures/Noise/perlin_1.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f0773f3e799c5f247889ff2d8e9bd3ac 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 9 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | internalID: 0 80 | vertices: [] 81 | indices: 82 | edges: [] 83 | weights: [] 84 | secondaryTextures: [] 85 | spritePackingTag: 86 | pSDRemoveMatte: 0 87 | pSDShowRemoveMatteOption: 0 88 | userData: 89 | assetBundleName: 90 | assetBundleVariant: 91 | -------------------------------------------------------------------------------- /Assets/Textures/Skyboxes.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1a36ed558f03737478e9b0cf0ae3a1d6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /Assets/Textures/Skyboxes/skybox_1.hdr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/0e59f7c42b5ccbc8bc637b7a6435c3af648bc8b6/Assets/Textures/Skyboxes/skybox_1.hdr -------------------------------------------------------------------------------- /Assets/Textures/Skyboxes/skybox_1.hdr.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: fa334c0fbccbdd14ea92ede1bd93db39 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 9 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 0 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 2 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 1024 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | - serializedVersion: 2 73 | buildTarget: Standalone 74 | maxTextureSize: 1024 75 | resizeAlgorithm: 0 76 | textureFormat: -1 77 | textureCompression: 1 78 | compressionQuality: 50 79 | crunchedCompression: 0 80 | allowsAlphaSplitting: 0 81 | overridden: 0 82 | androidETC2FallbackOverride: 0 83 | - serializedVersion: 2 84 | buildTarget: Android 85 | maxTextureSize: 1024 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | androidETC2FallbackOverride: 0 94 | - serializedVersion: 2 95 | buildTarget: WebGL 96 | maxTextureSize: 1024 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | spriteSheet: 106 | serializedVersion: 2 107 | sprites: [] 108 | outline: [] 109 | physicsShape: [] 110 | bones: [] 111 | spriteID: 112 | internalID: 0 113 | vertices: [] 114 | indices: 115 | edges: [] 116 | weights: [] 117 | secondaryTextures: [] 118 | spritePackingTag: 119 | pSDRemoveMatte: 0 120 | pSDShowRemoveMatteOption: 0 121 | userData: 122 | assetBundleName: 123 | assetBundleVariant: 124 | -------------------------------------------------------------------------------- /Assets/Textures/heightmap_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/0e59f7c42b5ccbc8bc637b7a6435c3af648bc8b6/Assets/Textures/heightmap_2.png -------------------------------------------------------------------------------- /Assets/Textures/heightmap_2.png.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 43149b43056f9c340b49f9a408fc3284 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 9 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: 4 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | - serializedVersion: 2 73 | buildTarget: Standalone 74 | maxTextureSize: 2048 75 | resizeAlgorithm: 0 76 | textureFormat: 4 77 | textureCompression: 1 78 | compressionQuality: 50 79 | crunchedCompression: 0 80 | allowsAlphaSplitting: 0 81 | overridden: 0 82 | androidETC2FallbackOverride: 0 83 | - serializedVersion: 2 84 | buildTarget: WebGL 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: 4 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | androidETC2FallbackOverride: 0 94 | spriteSheet: 95 | serializedVersion: 2 96 | sprites: [] 97 | outline: [] 98 | physicsShape: [] 99 | bones: [] 100 | spriteID: 101 | internalID: 0 102 | vertices: [] 103 | indices: 104 | edges: [] 105 | weights: [] 106 | secondaryTextures: [] 107 | spritePackingTag: 108 | pSDRemoveMatte: 0 109 | pSDShowRemoveMatteOption: 0 110 | userData: 111 | assetBundleName: 112 | assetBundleVariant: 113 | -------------------------------------------------------------------------------- /Assets/Textures/normal.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/0e59f7c42b5ccbc8bc637b7a6435c3af648bc8b6/Assets/Textures/normal.jpg -------------------------------------------------------------------------------- /Assets/Textures/normal.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7b4498d27a6ab7743b2336fbf4b36230 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 9 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 0 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 1 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | - serializedVersion: 2 73 | buildTarget: Standalone 74 | maxTextureSize: 2048 75 | resizeAlgorithm: 0 76 | textureFormat: -1 77 | textureCompression: 1 78 | compressionQuality: 50 79 | crunchedCompression: 0 80 | allowsAlphaSplitting: 0 81 | overridden: 0 82 | androidETC2FallbackOverride: 0 83 | - serializedVersion: 2 84 | buildTarget: Android 85 | maxTextureSize: 2048 86 | resizeAlgorithm: 0 87 | textureFormat: -1 88 | textureCompression: 1 89 | compressionQuality: 50 90 | crunchedCompression: 0 91 | allowsAlphaSplitting: 0 92 | overridden: 0 93 | androidETC2FallbackOverride: 0 94 | - serializedVersion: 2 95 | buildTarget: WebGL 96 | maxTextureSize: 2048 97 | resizeAlgorithm: 0 98 | textureFormat: -1 99 | textureCompression: 1 100 | compressionQuality: 50 101 | crunchedCompression: 0 102 | allowsAlphaSplitting: 0 103 | overridden: 0 104 | androidETC2FallbackOverride: 0 105 | spriteSheet: 106 | serializedVersion: 2 107 | sprites: [] 108 | outline: [] 109 | physicsShape: [] 110 | bones: [] 111 | spriteID: 112 | internalID: 0 113 | vertices: [] 114 | indices: 115 | edges: [] 116 | weights: [] 117 | secondaryTextures: [] 118 | spritePackingTag: 119 | pSDRemoveMatte: 0 120 | pSDShowRemoveMatteOption: 0 121 | userData: 122 | assetBundleName: 123 | assetBundleVariant: 124 | -------------------------------------------------------------------------------- /Assets/Textures/terrain.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/0e59f7c42b5ccbc8bc637b7a6435c3af648bc8b6/Assets/Textures/terrain.jpg -------------------------------------------------------------------------------- /Assets/Textures/terrain.jpg.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: f83c8dcb5e7a5924b95ab2326089ed33 3 | TextureImporter: 4 | internalIDToNameTable: [] 5 | externalObjects: {} 6 | serializedVersion: 9 7 | mipmaps: 8 | mipMapMode: 0 9 | enableMipMap: 1 10 | sRGBTexture: 1 11 | linearTexture: 0 12 | fadeOut: 0 13 | borderMipMap: 0 14 | mipMapsPreserveCoverage: 0 15 | alphaTestReferenceValue: 0.5 16 | mipMapFadeDistanceStart: 1 17 | mipMapFadeDistanceEnd: 3 18 | bumpmap: 19 | convertToNormalMap: 0 20 | externalNormalMap: 0 21 | heightScale: 0.25 22 | normalMapFilter: 0 23 | isReadable: 0 24 | streamingMipmaps: 0 25 | streamingMipmapsPriority: 0 26 | grayScaleToAlpha: 0 27 | generateCubemap: 6 28 | cubemapConvolution: 0 29 | seamlessCubemap: 0 30 | textureFormat: 1 31 | maxTextureSize: 2048 32 | textureSettings: 33 | serializedVersion: 2 34 | filterMode: -1 35 | aniso: -1 36 | mipBias: -100 37 | wrapU: -1 38 | wrapV: -1 39 | wrapW: -1 40 | nPOTScale: 1 41 | lightmap: 0 42 | compressionQuality: 50 43 | spriteMode: 0 44 | spriteExtrude: 1 45 | spriteMeshType: 1 46 | alignment: 0 47 | spritePivot: {x: 0.5, y: 0.5} 48 | spritePixelsToUnits: 100 49 | spriteBorder: {x: 0, y: 0, z: 0, w: 0} 50 | spriteGenerateFallbackPhysicsShape: 1 51 | alphaUsage: 1 52 | alphaIsTransparency: 0 53 | spriteTessellationDetail: -1 54 | textureType: 0 55 | textureShape: 1 56 | singleChannelComponent: 0 57 | maxTextureSizeSet: 0 58 | compressionQualitySet: 0 59 | textureFormatSet: 0 60 | platformSettings: 61 | - serializedVersion: 2 62 | buildTarget: DefaultTexturePlatform 63 | maxTextureSize: 2048 64 | resizeAlgorithm: 0 65 | textureFormat: -1 66 | textureCompression: 1 67 | compressionQuality: 50 68 | crunchedCompression: 0 69 | allowsAlphaSplitting: 0 70 | overridden: 0 71 | androidETC2FallbackOverride: 0 72 | spriteSheet: 73 | serializedVersion: 2 74 | sprites: [] 75 | outline: [] 76 | physicsShape: [] 77 | bones: [] 78 | spriteID: 79 | internalID: 0 80 | vertices: [] 81 | indices: 82 | edges: [] 83 | weights: [] 84 | secondaryTextures: [] 85 | spritePackingTag: 86 | pSDRemoveMatte: 0 87 | pSDShowRemoveMatteOption: 0 88 | userData: 89 | assetBundleName: 90 | assetBundleVariant: 91 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Boris Shishov 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Logs/Packages-Update.log: -------------------------------------------------------------------------------- 1 | 2 | === Sun Mar 10 18:26:20 2019 3 | 4 | Packages were changed. 5 | Update Mode: mergeDefaultDependencies 6 | 7 | The following packages were updated: 8 | com.unity.collab-proxy from version 1.2.9 to 1.2.15 9 | com.unity.package-manager-ui from version 0.0.0-builtin to 2.1.1 10 | com.unity.timeline from version 0.0.0-builtin to 1.0.0 11 | 12 | === Wed Mar 13 21:52:09 2019 13 | 14 | Packages were changed. 15 | Update Mode: updateDependencies 16 | 17 | The following packages were updated: 18 | com.unity.analytics from version 3.2.2 to 3.3.2 19 | 20 | === Thu Mar 12 01:36:46 2020 21 | 22 | Packages were changed. 23 | Update Mode: updateDependencies 24 | 25 | The following packages were added: 26 | com.unity.2d.tilemap@1.0.0 27 | com.unity.test-framework@1.1.9 28 | com.unity.2d.sprite@1.0.0 29 | com.unity.ide.vscode@1.1.4 30 | com.unity.ide.rider@1.1.4 31 | com.unity.ugui@1.0.0 32 | com.unity.modules.androidjni@1.0.0 33 | The following packages were updated: 34 | com.unity.analytics from version 3.3.2 to 3.3.5 35 | com.unity.collab-proxy from version 1.2.15 to 1.2.16 36 | com.unity.purchasing from version 2.0.1 to 2.0.6 37 | com.unity.textmeshpro from version 1.3.0 to 2.0.1 38 | com.unity.timeline from version 1.0.0 to 1.2.10 39 | The following packages were removed: 40 | com.unity.package-manager-ui@2.1.1 41 | -------------------------------------------------------------------------------- /Packages/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "com.unity.2d.sprite": "1.0.0", 4 | "com.unity.2d.tilemap": "1.0.0", 5 | "com.unity.ads": "2.0.8", 6 | "com.unity.analytics": "3.3.5", 7 | "com.unity.collab-proxy": "1.2.16", 8 | "com.unity.ide.rider": "1.1.4", 9 | "com.unity.ide.vscode": "1.1.4", 10 | "com.unity.purchasing": "2.0.6", 11 | "com.unity.test-framework": "1.1.9", 12 | "com.unity.textmeshpro": "2.0.1", 13 | "com.unity.timeline": "1.2.10", 14 | "com.unity.ugui": "1.0.0", 15 | "com.unity.modules.ai": "1.0.0", 16 | "com.unity.modules.androidjni": "1.0.0", 17 | "com.unity.modules.animation": "1.0.0", 18 | "com.unity.modules.assetbundle": "1.0.0", 19 | "com.unity.modules.audio": "1.0.0", 20 | "com.unity.modules.cloth": "1.0.0", 21 | "com.unity.modules.director": "1.0.0", 22 | "com.unity.modules.imageconversion": "1.0.0", 23 | "com.unity.modules.imgui": "1.0.0", 24 | "com.unity.modules.jsonserialize": "1.0.0", 25 | "com.unity.modules.particlesystem": "1.0.0", 26 | "com.unity.modules.physics": "1.0.0", 27 | "com.unity.modules.physics2d": "1.0.0", 28 | "com.unity.modules.screencapture": "1.0.0", 29 | "com.unity.modules.terrain": "1.0.0", 30 | "com.unity.modules.terrainphysics": "1.0.0", 31 | "com.unity.modules.tilemap": "1.0.0", 32 | "com.unity.modules.ui": "1.0.0", 33 | "com.unity.modules.uielements": "1.0.0", 34 | "com.unity.modules.umbra": "1.0.0", 35 | "com.unity.modules.unityanalytics": "1.0.0", 36 | "com.unity.modules.unitywebrequest": "1.0.0", 37 | "com.unity.modules.unitywebrequestassetbundle": "1.0.0", 38 | "com.unity.modules.unitywebrequestaudio": "1.0.0", 39 | "com.unity.modules.unitywebrequesttexture": "1.0.0", 40 | "com.unity.modules.unitywebrequestwww": "1.0.0", 41 | "com.unity.modules.vehicles": "1.0.0", 42 | "com.unity.modules.video": "1.0.0", 43 | "com.unity.modules.vr": "1.0.0", 44 | "com.unity.modules.wind": "1.0.0", 45 | "com.unity.modules.xr": "1.0.0" 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /ProjectSettings/AudioManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!11 &1 4 | AudioManager: 5 | m_ObjectHideFlags: 0 6 | m_Volume: 1 7 | Rolloff Scale: 1 8 | Doppler Factor: 1 9 | Default Speaker Mode: 2 10 | m_SampleRate: 0 11 | m_DSPBufferSize: 1024 12 | m_VirtualVoiceCount: 512 13 | m_RealVoiceCount: 32 14 | m_SpatializerPlugin: 15 | m_AmbisonicDecoderPlugin: 16 | m_DisableAudio: 0 17 | m_VirtualizeEffects: 1 18 | -------------------------------------------------------------------------------- /ProjectSettings/ClusterInputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!236 &1 4 | ClusterInputManager: 5 | m_ObjectHideFlags: 0 6 | m_Inputs: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/DynamicsManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!55 &1 4 | PhysicsManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 11 7 | m_Gravity: {x: 0, y: -9.81, z: 0} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_BounceThreshold: 2 10 | m_SleepThreshold: 0.005 11 | m_DefaultContactOffset: 0.01 12 | m_DefaultSolverIterations: 6 13 | m_DefaultSolverVelocityIterations: 1 14 | m_QueriesHitBackfaces: 0 15 | m_QueriesHitTriggers: 1 16 | m_EnableAdaptiveForce: 0 17 | m_ClothInterCollisionDistance: 0 18 | m_ClothInterCollisionStiffness: 0 19 | m_ContactsGeneration: 1 20 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 21 | m_AutoSimulation: 1 22 | m_AutoSyncTransforms: 0 23 | m_ReuseCollisionCallbacks: 1 24 | m_ClothInterCollisionSettingsToggle: 0 25 | m_ContactPairsMode: 0 26 | m_BroadphaseType: 0 27 | m_WorldBounds: 28 | m_Center: {x: 0, y: 0, z: 0} 29 | m_Extent: {x: 250, y: 250, z: 250} 30 | m_WorldSubdivisions: 8 31 | m_FrictionType: 0 32 | m_EnableEnhancedDeterminism: 0 33 | m_EnableUnifiedHeightmaps: 1 34 | m_DefaultMaxAngluarSpeed: 7 35 | -------------------------------------------------------------------------------- /ProjectSettings/EditorBuildSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1045 &1 4 | EditorBuildSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Scenes: 8 | - enabled: 1 9 | path: Assets/Scenes/CustomTerrain/CustomTerrain.unity 10 | guid: 7ac57417042fa9b469a1820811e316af 11 | m_configObjects: {} 12 | -------------------------------------------------------------------------------- /ProjectSettings/EditorSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!159 &1 4 | EditorSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 9 7 | m_ExternalVersionControlSupport: Hidden Meta Files 8 | m_SerializationMode: 2 9 | m_LineEndingsForNewScripts: 2 10 | m_DefaultBehaviorMode: 0 11 | m_PrefabRegularEnvironment: {fileID: 0} 12 | m_PrefabUIEnvironment: {fileID: 0} 13 | m_SpritePackerMode: 0 14 | m_SpritePackerPaddingPower: 1 15 | m_EtcTextureCompressorBehavior: 1 16 | m_EtcTextureFastCompressor: 1 17 | m_EtcTextureNormalCompressor: 2 18 | m_EtcTextureBestCompressor: 4 19 | m_ProjectGenerationIncludedExtensions: txt;xml;fnt;cd;asmdef;rsp;asmref 20 | m_ProjectGenerationRootNamespace: 21 | m_CollabEditorSettings: 22 | inProgressEnabled: 1 23 | m_EnableTextureStreamingInEditMode: 1 24 | m_EnableTextureStreamingInPlayMode: 1 25 | m_AsyncShaderCompilation: 1 26 | m_EnterPlayModeOptionsEnabled: 0 27 | m_EnterPlayModeOptions: 3 28 | m_ShowLightmapResolutionOverlay: 1 29 | m_UseLegacyProbeSampleCount: 1 30 | m_AssetPipelineMode: 1 31 | m_CacheServerMode: 0 32 | m_CacheServerEndpoint: 33 | m_CacheServerNamespacePrefix: default 34 | m_CacheServerEnableDownload: 1 35 | m_CacheServerEnableUpload: 1 36 | -------------------------------------------------------------------------------- /ProjectSettings/GraphicsSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!30 &1 4 | GraphicsSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 12 7 | m_Deferred: 8 | m_Mode: 1 9 | m_Shader: {fileID: 69, guid: 0000000000000000f000000000000000, type: 0} 10 | m_DeferredReflections: 11 | m_Mode: 1 12 | m_Shader: {fileID: 74, guid: 0000000000000000f000000000000000, type: 0} 13 | m_ScreenSpaceShadows: 14 | m_Mode: 1 15 | m_Shader: {fileID: 64, guid: 0000000000000000f000000000000000, type: 0} 16 | m_LegacyDeferred: 17 | m_Mode: 1 18 | m_Shader: {fileID: 63, guid: 0000000000000000f000000000000000, type: 0} 19 | m_DepthNormals: 20 | m_Mode: 1 21 | m_Shader: {fileID: 62, guid: 0000000000000000f000000000000000, type: 0} 22 | m_MotionVectors: 23 | m_Mode: 1 24 | m_Shader: {fileID: 75, guid: 0000000000000000f000000000000000, type: 0} 25 | m_LightHalo: 26 | m_Mode: 1 27 | m_Shader: {fileID: 105, guid: 0000000000000000f000000000000000, type: 0} 28 | m_LensFlare: 29 | m_Mode: 1 30 | m_Shader: {fileID: 102, guid: 0000000000000000f000000000000000, type: 0} 31 | m_AlwaysIncludedShaders: 32 | - {fileID: 7, guid: 0000000000000000f000000000000000, type: 0} 33 | - {fileID: 15104, guid: 0000000000000000f000000000000000, type: 0} 34 | - {fileID: 15105, guid: 0000000000000000f000000000000000, type: 0} 35 | - {fileID: 15106, guid: 0000000000000000f000000000000000, type: 0} 36 | - {fileID: 10753, guid: 0000000000000000f000000000000000, type: 0} 37 | - {fileID: 10770, guid: 0000000000000000f000000000000000, type: 0} 38 | m_PreloadedShaders: [] 39 | m_SpritesDefaultMaterial: {fileID: 10754, guid: 0000000000000000f000000000000000, 40 | type: 0} 41 | m_CustomRenderPipeline: {fileID: 0} 42 | m_TransparencySortMode: 0 43 | m_TransparencySortAxis: {x: 0, y: 0, z: 1} 44 | m_DefaultRenderingPath: 1 45 | m_DefaultMobileRenderingPath: 1 46 | m_TierSettings: [] 47 | m_LightmapStripping: 0 48 | m_FogStripping: 0 49 | m_InstancingStripping: 0 50 | m_LightmapKeepPlain: 1 51 | m_LightmapKeepDirCombined: 1 52 | m_LightmapKeepDynamicPlain: 1 53 | m_LightmapKeepDynamicDirCombined: 1 54 | m_LightmapKeepShadowMask: 1 55 | m_LightmapKeepSubtractive: 1 56 | m_FogKeepLinear: 1 57 | m_FogKeepExp: 1 58 | m_FogKeepExp2: 1 59 | m_AlbedoSwatchInfos: [] 60 | m_LightsUseLinearIntensity: 0 61 | m_LightsUseColorTemperature: 0 62 | -------------------------------------------------------------------------------- /ProjectSettings/InputManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!13 &1 4 | InputManager: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | m_Axes: 8 | - serializedVersion: 3 9 | m_Name: Horizontal 10 | descriptiveName: 11 | descriptiveNegativeName: 12 | negativeButton: left 13 | positiveButton: right 14 | altNegativeButton: a 15 | altPositiveButton: d 16 | gravity: 3 17 | dead: 0.001 18 | sensitivity: 3 19 | snap: 1 20 | invert: 0 21 | type: 0 22 | axis: 0 23 | joyNum: 0 24 | - serializedVersion: 3 25 | m_Name: Vertical 26 | descriptiveName: 27 | descriptiveNegativeName: 28 | negativeButton: down 29 | positiveButton: up 30 | altNegativeButton: s 31 | altPositiveButton: w 32 | gravity: 3 33 | dead: 0.001 34 | sensitivity: 3 35 | snap: 1 36 | invert: 0 37 | type: 0 38 | axis: 0 39 | joyNum: 0 40 | - serializedVersion: 3 41 | m_Name: Fire1 42 | descriptiveName: 43 | descriptiveNegativeName: 44 | negativeButton: 45 | positiveButton: left ctrl 46 | altNegativeButton: 47 | altPositiveButton: mouse 0 48 | gravity: 1000 49 | dead: 0.001 50 | sensitivity: 1000 51 | snap: 0 52 | invert: 0 53 | type: 0 54 | axis: 0 55 | joyNum: 0 56 | - serializedVersion: 3 57 | m_Name: Fire2 58 | descriptiveName: 59 | descriptiveNegativeName: 60 | negativeButton: 61 | positiveButton: left alt 62 | altNegativeButton: 63 | altPositiveButton: mouse 1 64 | gravity: 1000 65 | dead: 0.001 66 | sensitivity: 1000 67 | snap: 0 68 | invert: 0 69 | type: 0 70 | axis: 0 71 | joyNum: 0 72 | - serializedVersion: 3 73 | m_Name: Fire3 74 | descriptiveName: 75 | descriptiveNegativeName: 76 | negativeButton: 77 | positiveButton: left shift 78 | altNegativeButton: 79 | altPositiveButton: mouse 2 80 | gravity: 1000 81 | dead: 0.001 82 | sensitivity: 1000 83 | snap: 0 84 | invert: 0 85 | type: 0 86 | axis: 0 87 | joyNum: 0 88 | - serializedVersion: 3 89 | m_Name: Jump 90 | descriptiveName: 91 | descriptiveNegativeName: 92 | negativeButton: 93 | positiveButton: space 94 | altNegativeButton: 95 | altPositiveButton: 96 | gravity: 1000 97 | dead: 0.001 98 | sensitivity: 1000 99 | snap: 0 100 | invert: 0 101 | type: 0 102 | axis: 0 103 | joyNum: 0 104 | - serializedVersion: 3 105 | m_Name: Mouse X 106 | descriptiveName: 107 | descriptiveNegativeName: 108 | negativeButton: 109 | positiveButton: 110 | altNegativeButton: 111 | altPositiveButton: 112 | gravity: 0 113 | dead: 0 114 | sensitivity: 0.1 115 | snap: 0 116 | invert: 0 117 | type: 1 118 | axis: 0 119 | joyNum: 0 120 | - serializedVersion: 3 121 | m_Name: Mouse Y 122 | descriptiveName: 123 | descriptiveNegativeName: 124 | negativeButton: 125 | positiveButton: 126 | altNegativeButton: 127 | altPositiveButton: 128 | gravity: 0 129 | dead: 0 130 | sensitivity: 0.1 131 | snap: 0 132 | invert: 0 133 | type: 1 134 | axis: 1 135 | joyNum: 0 136 | - serializedVersion: 3 137 | m_Name: Mouse ScrollWheel 138 | descriptiveName: 139 | descriptiveNegativeName: 140 | negativeButton: 141 | positiveButton: 142 | altNegativeButton: 143 | altPositiveButton: 144 | gravity: 0 145 | dead: 0 146 | sensitivity: 0.1 147 | snap: 0 148 | invert: 0 149 | type: 1 150 | axis: 2 151 | joyNum: 0 152 | - serializedVersion: 3 153 | m_Name: Horizontal 154 | descriptiveName: 155 | descriptiveNegativeName: 156 | negativeButton: 157 | positiveButton: 158 | altNegativeButton: 159 | altPositiveButton: 160 | gravity: 0 161 | dead: 0.19 162 | sensitivity: 1 163 | snap: 0 164 | invert: 0 165 | type: 2 166 | axis: 0 167 | joyNum: 0 168 | - serializedVersion: 3 169 | m_Name: Vertical 170 | descriptiveName: 171 | descriptiveNegativeName: 172 | negativeButton: 173 | positiveButton: 174 | altNegativeButton: 175 | altPositiveButton: 176 | gravity: 0 177 | dead: 0.19 178 | sensitivity: 1 179 | snap: 0 180 | invert: 1 181 | type: 2 182 | axis: 1 183 | joyNum: 0 184 | - serializedVersion: 3 185 | m_Name: Fire1 186 | descriptiveName: 187 | descriptiveNegativeName: 188 | negativeButton: 189 | positiveButton: joystick button 0 190 | altNegativeButton: 191 | altPositiveButton: 192 | gravity: 1000 193 | dead: 0.001 194 | sensitivity: 1000 195 | snap: 0 196 | invert: 0 197 | type: 0 198 | axis: 0 199 | joyNum: 0 200 | - serializedVersion: 3 201 | m_Name: Fire2 202 | descriptiveName: 203 | descriptiveNegativeName: 204 | negativeButton: 205 | positiveButton: joystick button 1 206 | altNegativeButton: 207 | altPositiveButton: 208 | gravity: 1000 209 | dead: 0.001 210 | sensitivity: 1000 211 | snap: 0 212 | invert: 0 213 | type: 0 214 | axis: 0 215 | joyNum: 0 216 | - serializedVersion: 3 217 | m_Name: Fire3 218 | descriptiveName: 219 | descriptiveNegativeName: 220 | negativeButton: 221 | positiveButton: joystick button 2 222 | altNegativeButton: 223 | altPositiveButton: 224 | gravity: 1000 225 | dead: 0.001 226 | sensitivity: 1000 227 | snap: 0 228 | invert: 0 229 | type: 0 230 | axis: 0 231 | joyNum: 0 232 | - serializedVersion: 3 233 | m_Name: Jump 234 | descriptiveName: 235 | descriptiveNegativeName: 236 | negativeButton: 237 | positiveButton: joystick button 3 238 | altNegativeButton: 239 | altPositiveButton: 240 | gravity: 1000 241 | dead: 0.001 242 | sensitivity: 1000 243 | snap: 0 244 | invert: 0 245 | type: 0 246 | axis: 0 247 | joyNum: 0 248 | - serializedVersion: 3 249 | m_Name: Submit 250 | descriptiveName: 251 | descriptiveNegativeName: 252 | negativeButton: 253 | positiveButton: return 254 | altNegativeButton: 255 | altPositiveButton: joystick button 0 256 | gravity: 1000 257 | dead: 0.001 258 | sensitivity: 1000 259 | snap: 0 260 | invert: 0 261 | type: 0 262 | axis: 0 263 | joyNum: 0 264 | - serializedVersion: 3 265 | m_Name: Submit 266 | descriptiveName: 267 | descriptiveNegativeName: 268 | negativeButton: 269 | positiveButton: enter 270 | altNegativeButton: 271 | altPositiveButton: space 272 | gravity: 1000 273 | dead: 0.001 274 | sensitivity: 1000 275 | snap: 0 276 | invert: 0 277 | type: 0 278 | axis: 0 279 | joyNum: 0 280 | - serializedVersion: 3 281 | m_Name: Cancel 282 | descriptiveName: 283 | descriptiveNegativeName: 284 | negativeButton: 285 | positiveButton: escape 286 | altNegativeButton: 287 | altPositiveButton: joystick button 1 288 | gravity: 1000 289 | dead: 0.001 290 | sensitivity: 1000 291 | snap: 0 292 | invert: 0 293 | type: 0 294 | axis: 0 295 | joyNum: 0 296 | -------------------------------------------------------------------------------- /ProjectSettings/NavMeshAreas.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!126 &1 4 | NavMeshProjectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 2 7 | areas: 8 | - name: Walkable 9 | cost: 1 10 | - name: Not Walkable 11 | cost: 1 12 | - name: Jump 13 | cost: 2 14 | - name: 15 | cost: 1 16 | - name: 17 | cost: 1 18 | - name: 19 | cost: 1 20 | - name: 21 | cost: 1 22 | - name: 23 | cost: 1 24 | - name: 25 | cost: 1 26 | - name: 27 | cost: 1 28 | - name: 29 | cost: 1 30 | - name: 31 | cost: 1 32 | - name: 33 | cost: 1 34 | - name: 35 | cost: 1 36 | - name: 37 | cost: 1 38 | - name: 39 | cost: 1 40 | - name: 41 | cost: 1 42 | - name: 43 | cost: 1 44 | - name: 45 | cost: 1 46 | - name: 47 | cost: 1 48 | - name: 49 | cost: 1 50 | - name: 51 | cost: 1 52 | - name: 53 | cost: 1 54 | - name: 55 | cost: 1 56 | - name: 57 | cost: 1 58 | - name: 59 | cost: 1 60 | - name: 61 | cost: 1 62 | - name: 63 | cost: 1 64 | - name: 65 | cost: 1 66 | - name: 67 | cost: 1 68 | - name: 69 | cost: 1 70 | - name: 71 | cost: 1 72 | m_LastAgentTypeID: -887442657 73 | m_Settings: 74 | - serializedVersion: 2 75 | agentTypeID: 0 76 | agentRadius: 0.5 77 | agentHeight: 2 78 | agentSlope: 45 79 | agentClimb: 0.75 80 | ledgeDropHeight: 0 81 | maxJumpAcrossDistance: 0 82 | minRegionArea: 2 83 | manualCellSize: 0 84 | cellSize: 0.16666667 85 | manualTileSize: 0 86 | tileSize: 256 87 | accuratePlacement: 0 88 | debug: 89 | m_Flags: 0 90 | m_SettingNames: 91 | - Humanoid 92 | -------------------------------------------------------------------------------- /ProjectSettings/Physics2DSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!19 &1 4 | Physics2DSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 4 7 | m_Gravity: {x: 0, y: -9.81} 8 | m_DefaultMaterial: {fileID: 0} 9 | m_VelocityIterations: 8 10 | m_PositionIterations: 3 11 | m_VelocityThreshold: 1 12 | m_MaxLinearCorrection: 0.2 13 | m_MaxAngularCorrection: 8 14 | m_MaxTranslationSpeed: 100 15 | m_MaxRotationSpeed: 360 16 | m_BaumgarteScale: 0.2 17 | m_BaumgarteTimeOfImpactScale: 0.75 18 | m_TimeToSleep: 0.5 19 | m_LinearSleepTolerance: 0.01 20 | m_AngularSleepTolerance: 2 21 | m_DefaultContactOffset: 0.01 22 | m_JobOptions: 23 | serializedVersion: 2 24 | useMultithreading: 0 25 | useConsistencySorting: 0 26 | m_InterpolationPosesPerJob: 100 27 | m_NewContactsPerJob: 30 28 | m_CollideContactsPerJob: 100 29 | m_ClearFlagsPerJob: 200 30 | m_ClearBodyForcesPerJob: 200 31 | m_SyncDiscreteFixturesPerJob: 50 32 | m_SyncContinuousFixturesPerJob: 50 33 | m_FindNearestContactsPerJob: 100 34 | m_UpdateTriggerContactsPerJob: 100 35 | m_IslandSolverCostThreshold: 100 36 | m_IslandSolverBodyCostScale: 1 37 | m_IslandSolverContactCostScale: 10 38 | m_IslandSolverJointCostScale: 10 39 | m_IslandSolverBodiesPerJob: 50 40 | m_IslandSolverContactsPerJob: 50 41 | m_AutoSimulation: 1 42 | m_QueriesHitTriggers: 1 43 | m_QueriesStartInColliders: 1 44 | m_CallbacksOnDisable: 1 45 | m_ReuseCollisionCallbacks: 1 46 | m_AutoSyncTransforms: 0 47 | m_AlwaysShowColliders: 0 48 | m_ShowColliderSleep: 1 49 | m_ShowColliderContacts: 0 50 | m_ShowColliderAABB: 0 51 | m_ContactArrowScale: 0.2 52 | m_ColliderAwakeColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.7529412} 53 | m_ColliderAsleepColor: {r: 0.5686275, g: 0.95686275, b: 0.54509807, a: 0.36078432} 54 | m_ColliderContactColor: {r: 1, g: 0, b: 1, a: 0.6862745} 55 | m_ColliderAABBColor: {r: 1, g: 1, b: 0, a: 0.2509804} 56 | m_LayerCollisionMatrix: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff 57 | -------------------------------------------------------------------------------- /ProjectSettings/PresetManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!1386491679 &1 4 | PresetManager: 5 | m_ObjectHideFlags: 0 6 | m_DefaultList: [] 7 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!129 &1 4 | PlayerSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 16 7 | productGUID: ff1800e4a5fac0747843182b17f25195 8 | AndroidProfiler: 0 9 | AndroidFilterTouchesWhenObscured: 0 10 | AndroidEnableSustainedPerformanceMode: 0 11 | defaultScreenOrientation: 4 12 | targetDevice: 2 13 | useOnDemandResources: 0 14 | accelerometerFrequency: 60 15 | companyName: DefaultCompany 16 | productName: UnityTerrainErosionGPU 17 | defaultCursor: {fileID: 0} 18 | cursorHotspot: {x: 0, y: 0} 19 | m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1} 20 | m_ShowUnitySplashScreen: 1 21 | m_ShowUnitySplashLogo: 1 22 | m_SplashScreenOverlayOpacity: 1 23 | m_SplashScreenAnimation: 1 24 | m_SplashScreenLogoStyle: 1 25 | m_SplashScreenDrawMode: 0 26 | m_SplashScreenBackgroundAnimationZoom: 1 27 | m_SplashScreenLogoAnimationZoom: 1 28 | m_SplashScreenBackgroundLandscapeAspect: 1 29 | m_SplashScreenBackgroundPortraitAspect: 1 30 | m_SplashScreenBackgroundLandscapeUvs: 31 | serializedVersion: 2 32 | x: 0 33 | y: 0 34 | width: 1 35 | height: 1 36 | m_SplashScreenBackgroundPortraitUvs: 37 | serializedVersion: 2 38 | x: 0 39 | y: 0 40 | width: 1 41 | height: 1 42 | m_SplashScreenLogos: [] 43 | m_VirtualRealitySplashScreen: {fileID: 0} 44 | m_HolographicTrackingLossScreen: {fileID: 0} 45 | defaultScreenWidth: 1024 46 | defaultScreenHeight: 768 47 | defaultScreenWidthWeb: 960 48 | defaultScreenHeightWeb: 600 49 | m_StereoRenderingPath: 0 50 | m_ActiveColorSpace: 0 51 | m_MTRendering: 1 52 | m_StackTraceTypes: 010000000100000001000000010000000100000001000000 53 | iosShowActivityIndicatorOnLoading: -1 54 | androidShowActivityIndicatorOnLoading: -1 55 | iosAppInBackgroundBehavior: 0 56 | displayResolutionDialog: 1 57 | iosAllowHTTPDownload: 1 58 | allowedAutorotateToPortrait: 1 59 | allowedAutorotateToPortraitUpsideDown: 1 60 | allowedAutorotateToLandscapeRight: 1 61 | allowedAutorotateToLandscapeLeft: 1 62 | useOSAutorotation: 1 63 | use32BitDisplayBuffer: 1 64 | preserveFramebufferAlpha: 0 65 | disableDepthAndStencilBuffers: 0 66 | androidStartInFullscreen: 1 67 | androidRenderOutsideSafeArea: 0 68 | androidBlitType: 0 69 | defaultIsNativeResolution: 1 70 | macRetinaSupport: 1 71 | runInBackground: 1 72 | captureSingleScreen: 0 73 | muteOtherAudioSources: 0 74 | Prepare IOS For Recording: 0 75 | Force IOS Speakers When Recording: 0 76 | deferSystemGesturesMode: 0 77 | hideHomeButton: 0 78 | submitAnalytics: 1 79 | usePlayerLog: 1 80 | bakeCollisionMeshes: 0 81 | forceSingleInstance: 0 82 | resizableWindow: 0 83 | useMacAppStoreValidation: 0 84 | macAppStoreCategory: public.app-category.games 85 | gpuSkinning: 1 86 | graphicsJobs: 0 87 | xboxPIXTextureCapture: 0 88 | xboxEnableAvatar: 0 89 | xboxEnableKinect: 0 90 | xboxEnableKinectAutoTracking: 0 91 | xboxEnableFitness: 0 92 | visibleInBackground: 1 93 | allowFullscreenSwitch: 1 94 | graphicsJobMode: 0 95 | fullscreenMode: 1 96 | xboxSpeechDB: 0 97 | xboxEnableHeadOrientation: 0 98 | xboxEnableGuest: 0 99 | xboxEnablePIXSampling: 0 100 | metalFramebufferOnly: 0 101 | xboxOneResolution: 0 102 | xboxOneSResolution: 0 103 | xboxOneXResolution: 3 104 | xboxOneMonoLoggingLevel: 0 105 | xboxOneLoggingLevel: 1 106 | xboxOneDisableEsram: 0 107 | xboxOnePresentImmediateThreshold: 0 108 | switchQueueCommandMemory: 0 109 | switchQueueControlMemory: 16384 110 | switchQueueComputeMemory: 262144 111 | switchNVNShaderPoolsGranularity: 33554432 112 | switchNVNDefaultPoolsGranularity: 16777216 113 | switchNVNOtherPoolsGranularity: 16777216 114 | vulkanEnableSetSRGBWrite: 0 115 | m_SupportedAspectRatios: 116 | 4:3: 1 117 | 5:4: 1 118 | 16:10: 1 119 | 16:9: 1 120 | Others: 1 121 | bundleVersion: 0.1 122 | preloadedAssets: [] 123 | metroInputSource: 0 124 | wsaTransparentSwapchain: 0 125 | m_HolographicPauseOnTrackingLoss: 1 126 | xboxOneDisableKinectGpuReservation: 0 127 | xboxOneEnable7thCore: 0 128 | vrSettings: 129 | cardboard: 130 | depthFormat: 0 131 | enableTransitionView: 0 132 | daydream: 133 | depthFormat: 0 134 | useSustainedPerformanceMode: 0 135 | enableVideoLayer: 0 136 | useProtectedVideoMemory: 0 137 | minimumSupportedHeadTracking: 0 138 | maximumSupportedHeadTracking: 1 139 | hololens: 140 | depthFormat: 1 141 | depthBufferSharingEnabled: 0 142 | lumin: 143 | depthFormat: 0 144 | frameTiming: 2 145 | enableGLCache: 0 146 | glCacheMaxBlobSize: 524288 147 | glCacheMaxFileSize: 8388608 148 | oculus: 149 | sharedDepthBuffer: 1 150 | dashSupport: 1 151 | enable360StereoCapture: 0 152 | isWsaHolographicRemotingEnabled: 0 153 | protectGraphicsMemory: 0 154 | enableFrameTimingStats: 0 155 | useHDRDisplay: 0 156 | m_ColorGamuts: 00000000 157 | targetPixelDensity: 30 158 | resolutionScalingMode: 0 159 | androidSupportedAspectRatio: 1 160 | androidMaxAspectRatio: 2.1 161 | applicationIdentifier: {} 162 | buildNumber: {} 163 | AndroidBundleVersionCode: 1 164 | AndroidMinSdkVersion: 16 165 | AndroidTargetSdkVersion: 0 166 | AndroidPreferredInstallLocation: 1 167 | aotOptions: 168 | stripEngineCode: 1 169 | iPhoneStrippingLevel: 0 170 | iPhoneScriptCallOptimization: 0 171 | ForceInternetPermission: 0 172 | ForceSDCardPermission: 0 173 | CreateWallpaper: 0 174 | APKExpansionFiles: 0 175 | keepLoadedShadersAlive: 0 176 | StripUnusedMeshComponents: 1 177 | VertexChannelCompressionMask: 4054 178 | iPhoneSdkVersion: 988 179 | iOSTargetOSVersionString: 9.0 180 | tvOSSdkVersion: 0 181 | tvOSRequireExtendedGameController: 0 182 | tvOSTargetOSVersionString: 9.0 183 | uIPrerenderedIcon: 0 184 | uIRequiresPersistentWiFi: 0 185 | uIRequiresFullScreen: 1 186 | uIStatusBarHidden: 1 187 | uIExitOnSuspend: 0 188 | uIStatusBarStyle: 0 189 | iPhoneSplashScreen: {fileID: 0} 190 | iPhoneHighResSplashScreen: {fileID: 0} 191 | iPhoneTallHighResSplashScreen: {fileID: 0} 192 | iPhone47inSplashScreen: {fileID: 0} 193 | iPhone55inPortraitSplashScreen: {fileID: 0} 194 | iPhone55inLandscapeSplashScreen: {fileID: 0} 195 | iPhone58inPortraitSplashScreen: {fileID: 0} 196 | iPhone58inLandscapeSplashScreen: {fileID: 0} 197 | iPadPortraitSplashScreen: {fileID: 0} 198 | iPadHighResPortraitSplashScreen: {fileID: 0} 199 | iPadLandscapeSplashScreen: {fileID: 0} 200 | iPadHighResLandscapeSplashScreen: {fileID: 0} 201 | iPhone65inPortraitSplashScreen: {fileID: 0} 202 | iPhone65inLandscapeSplashScreen: {fileID: 0} 203 | iPhone61inPortraitSplashScreen: {fileID: 0} 204 | iPhone61inLandscapeSplashScreen: {fileID: 0} 205 | appleTVSplashScreen: {fileID: 0} 206 | appleTVSplashScreen2x: {fileID: 0} 207 | tvOSSmallIconLayers: [] 208 | tvOSSmallIconLayers2x: [] 209 | tvOSLargeIconLayers: [] 210 | tvOSLargeIconLayers2x: [] 211 | tvOSTopShelfImageLayers: [] 212 | tvOSTopShelfImageLayers2x: [] 213 | tvOSTopShelfImageWideLayers: [] 214 | tvOSTopShelfImageWideLayers2x: [] 215 | iOSLaunchScreenType: 0 216 | iOSLaunchScreenPortrait: {fileID: 0} 217 | iOSLaunchScreenLandscape: {fileID: 0} 218 | iOSLaunchScreenBackgroundColor: 219 | serializedVersion: 2 220 | rgba: 0 221 | iOSLaunchScreenFillPct: 100 222 | iOSLaunchScreenSize: 100 223 | iOSLaunchScreenCustomXibPath: 224 | iOSLaunchScreeniPadType: 0 225 | iOSLaunchScreeniPadImage: {fileID: 0} 226 | iOSLaunchScreeniPadBackgroundColor: 227 | serializedVersion: 2 228 | rgba: 0 229 | iOSLaunchScreeniPadFillPct: 100 230 | iOSLaunchScreeniPadSize: 100 231 | iOSLaunchScreeniPadCustomXibPath: 232 | iOSUseLaunchScreenStoryboard: 0 233 | iOSLaunchScreenCustomStoryboardPath: 234 | iOSDeviceRequirements: [] 235 | iOSURLSchemes: [] 236 | iOSBackgroundModes: 0 237 | iOSMetalForceHardShadows: 0 238 | metalEditorSupport: 1 239 | metalAPIValidation: 1 240 | iOSRenderExtraFrameOnPause: 0 241 | appleDeveloperTeamID: 242 | iOSManualSigningProvisioningProfileID: 243 | tvOSManualSigningProvisioningProfileID: 244 | iOSManualSigningProvisioningProfileType: 0 245 | tvOSManualSigningProvisioningProfileType: 0 246 | appleEnableAutomaticSigning: 0 247 | iOSRequireARKit: 0 248 | iOSAutomaticallyDetectAndAddCapabilities: 1 249 | appleEnableProMotion: 0 250 | clonedFromGUID: c0afd0d1d80e3634a9dac47e8a0426ea 251 | templatePackageId: com.unity.template.3d@1.0.11 252 | templateDefaultScene: Assets/Scenes/SampleScene.unity 253 | AndroidTargetArchitectures: 1 254 | AndroidSplashScreenScale: 0 255 | androidSplashScreen: {fileID: 0} 256 | AndroidKeystoreName: '{inproject}: ' 257 | AndroidKeyaliasName: 258 | AndroidBuildApkPerCpuArchitecture: 0 259 | AndroidTVCompatibility: 0 260 | AndroidIsGame: 1 261 | AndroidEnableTango: 0 262 | androidEnableBanner: 1 263 | androidUseLowAccuracyLocation: 0 264 | androidUseCustomKeystore: 0 265 | m_AndroidBanners: 266 | - width: 320 267 | height: 180 268 | banner: {fileID: 0} 269 | androidGamepadSupportLevel: 0 270 | resolutionDialogBanner: {fileID: 0} 271 | m_BuildTargetIcons: [] 272 | m_BuildTargetPlatformIcons: [] 273 | m_BuildTargetBatching: 274 | - m_BuildTarget: Standalone 275 | m_StaticBatching: 1 276 | m_DynamicBatching: 0 277 | - m_BuildTarget: tvOS 278 | m_StaticBatching: 1 279 | m_DynamicBatching: 0 280 | - m_BuildTarget: Android 281 | m_StaticBatching: 1 282 | m_DynamicBatching: 0 283 | - m_BuildTarget: iPhone 284 | m_StaticBatching: 1 285 | m_DynamicBatching: 0 286 | - m_BuildTarget: WebGL 287 | m_StaticBatching: 0 288 | m_DynamicBatching: 0 289 | m_BuildTargetGraphicsAPIs: 290 | - m_BuildTarget: AndroidPlayer 291 | m_APIs: 150000000b000000 292 | m_Automatic: 0 293 | - m_BuildTarget: iOSSupport 294 | m_APIs: 10000000 295 | m_Automatic: 1 296 | - m_BuildTarget: AppleTVSupport 297 | m_APIs: 10000000 298 | m_Automatic: 0 299 | - m_BuildTarget: WebGLSupport 300 | m_APIs: 0b000000 301 | m_Automatic: 1 302 | m_BuildTargetVRSettings: 303 | - m_BuildTarget: Standalone 304 | m_Enabled: 0 305 | m_Devices: 306 | - Oculus 307 | - OpenVR 308 | m_BuildTargetEnableVuforiaSettings: [] 309 | openGLRequireES31: 0 310 | openGLRequireES31AEP: 0 311 | openGLRequireES32: 0 312 | m_TemplateCustomTags: {} 313 | mobileMTRendering: 314 | Android: 1 315 | iPhone: 1 316 | tvOS: 1 317 | m_BuildTargetGroupLightmapEncodingQuality: [] 318 | m_BuildTargetGroupLightmapSettings: [] 319 | playModeTestRunnerEnabled: 0 320 | runPlayModeTestAsEditModeTest: 0 321 | actionOnDotNetUnhandledException: 1 322 | enableInternalProfiler: 0 323 | logObjCUncaughtExceptions: 1 324 | enableCrashReportAPI: 0 325 | cameraUsageDescription: 326 | locationUsageDescription: 327 | microphoneUsageDescription: 328 | switchNetLibKey: 329 | switchSocketMemoryPoolSize: 6144 330 | switchSocketAllocatorPoolSize: 128 331 | switchSocketConcurrencyLimit: 14 332 | switchScreenResolutionBehavior: 2 333 | switchUseCPUProfiler: 0 334 | switchApplicationID: 0x01004b9000490000 335 | switchNSODependencies: 336 | switchTitleNames_0: 337 | switchTitleNames_1: 338 | switchTitleNames_2: 339 | switchTitleNames_3: 340 | switchTitleNames_4: 341 | switchTitleNames_5: 342 | switchTitleNames_6: 343 | switchTitleNames_7: 344 | switchTitleNames_8: 345 | switchTitleNames_9: 346 | switchTitleNames_10: 347 | switchTitleNames_11: 348 | switchTitleNames_12: 349 | switchTitleNames_13: 350 | switchTitleNames_14: 351 | switchPublisherNames_0: 352 | switchPublisherNames_1: 353 | switchPublisherNames_2: 354 | switchPublisherNames_3: 355 | switchPublisherNames_4: 356 | switchPublisherNames_5: 357 | switchPublisherNames_6: 358 | switchPublisherNames_7: 359 | switchPublisherNames_8: 360 | switchPublisherNames_9: 361 | switchPublisherNames_10: 362 | switchPublisherNames_11: 363 | switchPublisherNames_12: 364 | switchPublisherNames_13: 365 | switchPublisherNames_14: 366 | switchIcons_0: {fileID: 0} 367 | switchIcons_1: {fileID: 0} 368 | switchIcons_2: {fileID: 0} 369 | switchIcons_3: {fileID: 0} 370 | switchIcons_4: {fileID: 0} 371 | switchIcons_5: {fileID: 0} 372 | switchIcons_6: {fileID: 0} 373 | switchIcons_7: {fileID: 0} 374 | switchIcons_8: {fileID: 0} 375 | switchIcons_9: {fileID: 0} 376 | switchIcons_10: {fileID: 0} 377 | switchIcons_11: {fileID: 0} 378 | switchIcons_12: {fileID: 0} 379 | switchIcons_13: {fileID: 0} 380 | switchIcons_14: {fileID: 0} 381 | switchSmallIcons_0: {fileID: 0} 382 | switchSmallIcons_1: {fileID: 0} 383 | switchSmallIcons_2: {fileID: 0} 384 | switchSmallIcons_3: {fileID: 0} 385 | switchSmallIcons_4: {fileID: 0} 386 | switchSmallIcons_5: {fileID: 0} 387 | switchSmallIcons_6: {fileID: 0} 388 | switchSmallIcons_7: {fileID: 0} 389 | switchSmallIcons_8: {fileID: 0} 390 | switchSmallIcons_9: {fileID: 0} 391 | switchSmallIcons_10: {fileID: 0} 392 | switchSmallIcons_11: {fileID: 0} 393 | switchSmallIcons_12: {fileID: 0} 394 | switchSmallIcons_13: {fileID: 0} 395 | switchSmallIcons_14: {fileID: 0} 396 | switchManualHTML: 397 | switchAccessibleURLs: 398 | switchLegalInformation: 399 | switchMainThreadStackSize: 1048576 400 | switchPresenceGroupId: 401 | switchLogoHandling: 0 402 | switchReleaseVersion: 0 403 | switchDisplayVersion: 1.0.0 404 | switchStartupUserAccount: 0 405 | switchTouchScreenUsage: 0 406 | switchSupportedLanguagesMask: 0 407 | switchLogoType: 0 408 | switchApplicationErrorCodeCategory: 409 | switchUserAccountSaveDataSize: 0 410 | switchUserAccountSaveDataJournalSize: 0 411 | switchApplicationAttribute: 0 412 | switchCardSpecSize: -1 413 | switchCardSpecClock: -1 414 | switchRatingsMask: 0 415 | switchRatingsInt_0: 0 416 | switchRatingsInt_1: 0 417 | switchRatingsInt_2: 0 418 | switchRatingsInt_3: 0 419 | switchRatingsInt_4: 0 420 | switchRatingsInt_5: 0 421 | switchRatingsInt_6: 0 422 | switchRatingsInt_7: 0 423 | switchRatingsInt_8: 0 424 | switchRatingsInt_9: 0 425 | switchRatingsInt_10: 0 426 | switchRatingsInt_11: 0 427 | switchLocalCommunicationIds_0: 428 | switchLocalCommunicationIds_1: 429 | switchLocalCommunicationIds_2: 430 | switchLocalCommunicationIds_3: 431 | switchLocalCommunicationIds_4: 432 | switchLocalCommunicationIds_5: 433 | switchLocalCommunicationIds_6: 434 | switchLocalCommunicationIds_7: 435 | switchParentalControl: 0 436 | switchAllowsScreenshot: 1 437 | switchAllowsVideoCapturing: 1 438 | switchAllowsRuntimeAddOnContentInstall: 0 439 | switchDataLossConfirmation: 0 440 | switchUserAccountLockEnabled: 0 441 | switchSystemResourceMemory: 16777216 442 | switchSupportedNpadStyles: 3 443 | switchNativeFsCacheSize: 32 444 | switchIsHoldTypeHorizontal: 0 445 | switchSupportedNpadCount: 8 446 | switchSocketConfigEnabled: 0 447 | switchTcpInitialSendBufferSize: 32 448 | switchTcpInitialReceiveBufferSize: 64 449 | switchTcpAutoSendBufferSizeMax: 256 450 | switchTcpAutoReceiveBufferSizeMax: 256 451 | switchUdpSendBufferSize: 9 452 | switchUdpReceiveBufferSize: 42 453 | switchSocketBufferEfficiency: 4 454 | switchSocketInitializeEnabled: 1 455 | switchNetworkInterfaceManagerInitializeEnabled: 1 456 | switchPlayerConnectionEnabled: 1 457 | ps4NPAgeRating: 12 458 | ps4NPTitleSecret: 459 | ps4NPTrophyPackPath: 460 | ps4ParentalLevel: 11 461 | ps4ContentID: ED1633-NPXX51362_00-0000000000000000 462 | ps4Category: 0 463 | ps4MasterVersion: 01.00 464 | ps4AppVersion: 01.00 465 | ps4AppType: 0 466 | ps4ParamSfxPath: 467 | ps4VideoOutPixelFormat: 0 468 | ps4VideoOutInitialWidth: 1920 469 | ps4VideoOutBaseModeInitialWidth: 1920 470 | ps4VideoOutReprojectionRate: 60 471 | ps4PronunciationXMLPath: 472 | ps4PronunciationSIGPath: 473 | ps4BackgroundImagePath: 474 | ps4StartupImagePath: 475 | ps4StartupImagesFolder: 476 | ps4IconImagesFolder: 477 | ps4SaveDataImagePath: 478 | ps4SdkOverride: 479 | ps4BGMPath: 480 | ps4ShareFilePath: 481 | ps4ShareOverlayImagePath: 482 | ps4PrivacyGuardImagePath: 483 | ps4NPtitleDatPath: 484 | ps4RemotePlayKeyAssignment: -1 485 | ps4RemotePlayKeyMappingDir: 486 | ps4PlayTogetherPlayerCount: 0 487 | ps4EnterButtonAssignment: 1 488 | ps4ApplicationParam1: 0 489 | ps4ApplicationParam2: 0 490 | ps4ApplicationParam3: 0 491 | ps4ApplicationParam4: 0 492 | ps4DownloadDataSize: 0 493 | ps4GarlicHeapSize: 2048 494 | ps4ProGarlicHeapSize: 2560 495 | playerPrefsMaxSize: 32768 496 | ps4Passcode: frAQBc8Wsa1xVPfvJcrgRYwTiizs2trQ 497 | ps4pnSessions: 1 498 | ps4pnPresence: 1 499 | ps4pnFriends: 1 500 | ps4pnGameCustomData: 1 501 | playerPrefsSupport: 0 502 | enableApplicationExit: 0 503 | resetTempFolder: 1 504 | restrictedAudioUsageRights: 0 505 | ps4UseResolutionFallback: 0 506 | ps4ReprojectionSupport: 0 507 | ps4UseAudio3dBackend: 0 508 | ps4SocialScreenEnabled: 0 509 | ps4ScriptOptimizationLevel: 0 510 | ps4Audio3dVirtualSpeakerCount: 14 511 | ps4attribCpuUsage: 0 512 | ps4PatchPkgPath: 513 | ps4PatchLatestPkgPath: 514 | ps4PatchChangeinfoPath: 515 | ps4PatchDayOne: 0 516 | ps4attribUserManagement: 0 517 | ps4attribMoveSupport: 0 518 | ps4attrib3DSupport: 0 519 | ps4attribShareSupport: 0 520 | ps4attribExclusiveVR: 0 521 | ps4disableAutoHideSplash: 0 522 | ps4videoRecordingFeaturesUsed: 0 523 | ps4contentSearchFeaturesUsed: 0 524 | ps4attribEyeToEyeDistanceSettingVR: 0 525 | ps4IncludedModules: [] 526 | monoEnv: 527 | splashScreenBackgroundSourceLandscape: {fileID: 0} 528 | splashScreenBackgroundSourcePortrait: {fileID: 0} 529 | spritePackerPolicy: 530 | webGLMemorySize: 16 531 | webGLExceptionSupport: 1 532 | webGLNameFilesAsHashes: 0 533 | webGLDataCaching: 1 534 | webGLDebugSymbols: 0 535 | webGLEmscriptenArgs: 536 | webGLModulesDirectory: 537 | webGLTemplate: APPLICATION:Default 538 | webGLAnalyzeBuildSize: 0 539 | webGLUseEmbeddedResources: 0 540 | webGLCompressionFormat: 1 541 | webGLLinkerTarget: 1 542 | webGLThreadsSupport: 0 543 | webGLWasmStreaming: 0 544 | scriptingDefineSymbols: {} 545 | platformArchitecture: {} 546 | scriptingBackend: {} 547 | il2cppCompilerConfiguration: {} 548 | managedStrippingLevel: {} 549 | incrementalIl2cppBuild: {} 550 | allowUnsafeCode: 0 551 | additionalIl2CppArgs: 552 | scriptingRuntimeVersion: 1 553 | gcIncremental: 0 554 | gcWBarrierValidation: 0 555 | apiCompatibilityLevelPerPlatform: {} 556 | m_RenderingPath: 1 557 | m_MobileRenderingPath: 1 558 | metroPackageName: Template_3D 559 | metroPackageVersion: 560 | metroCertificatePath: 561 | metroCertificatePassword: 562 | metroCertificateSubject: 563 | metroCertificateIssuer: 564 | metroCertificateNotAfter: 0000000000000000 565 | metroApplicationDescription: Template_3D 566 | wsaImages: {} 567 | metroTileShortName: 568 | metroTileShowName: 0 569 | metroMediumTileShowName: 0 570 | metroLargeTileShowName: 0 571 | metroWideTileShowName: 0 572 | metroSupportStreamingInstall: 0 573 | metroLastRequiredScene: 0 574 | metroDefaultTileSize: 1 575 | metroTileForegroundText: 2 576 | metroTileBackgroundColor: {r: 0.13333334, g: 0.17254902, b: 0.21568628, a: 0} 577 | metroSplashScreenBackgroundColor: {r: 0.12941177, g: 0.17254902, b: 0.21568628, 578 | a: 1} 579 | metroSplashScreenUseBackgroundColor: 0 580 | platformCapabilities: {} 581 | metroTargetDeviceFamilies: {} 582 | metroFTAName: 583 | metroFTAFileTypes: [] 584 | metroProtocolName: 585 | XboxOneProductId: 586 | XboxOneUpdateKey: 587 | XboxOneSandboxId: 588 | XboxOneContentId: 589 | XboxOneTitleId: 590 | XboxOneSCId: 591 | XboxOneGameOsOverridePath: 592 | XboxOnePackagingOverridePath: 593 | XboxOneAppManifestOverridePath: 594 | XboxOneVersion: 1.0.0.0 595 | XboxOnePackageEncryption: 0 596 | XboxOnePackageUpdateGranularity: 2 597 | XboxOneDescription: 598 | XboxOneLanguage: 599 | - enus 600 | XboxOneCapability: [] 601 | XboxOneGameRating: {} 602 | XboxOneIsContentPackage: 0 603 | XboxOneEnableGPUVariability: 0 604 | XboxOneSockets: {} 605 | XboxOneSplashScreen: {fileID: 0} 606 | XboxOneAllowedProductIds: [] 607 | XboxOnePersistentLocalStorageSize: 0 608 | XboxOneXTitleMemory: 8 609 | xboxOneScriptCompiler: 0 610 | XboxOneOverrideIdentityName: 611 | vrEditorSettings: 612 | daydream: 613 | daydreamIconForeground: {fileID: 0} 614 | daydreamIconBackground: {fileID: 0} 615 | cloudServicesEnabled: 616 | UNet: 1 617 | luminIcon: 618 | m_Name: 619 | m_ModelFolderPath: 620 | m_PortalFolderPath: 621 | luminCert: 622 | m_CertPath: 623 | m_PrivateKeyPath: 624 | luminIsChannelApp: 0 625 | luminVersion: 626 | m_VersionCode: 1 627 | m_VersionName: 628 | facebookSdkVersion: 7.9.4 629 | facebookAppId: 630 | facebookCookies: 1 631 | facebookLogging: 1 632 | facebookStatus: 1 633 | facebookXfbml: 0 634 | facebookFrictionlessRequests: 1 635 | apiCompatibilityLevel: 6 636 | cloudProjectId: 637 | framebufferDepthMemorylessMode: 0 638 | projectName: 639 | organizationId: 640 | cloudEnabled: 0 641 | enableNativePlatformBackendsForNewInputSystem: 0 642 | disableOldInputManagerSupport: 0 643 | legacyClampBlendShapeWeights: 1 644 | -------------------------------------------------------------------------------- /ProjectSettings/ProjectVersion.txt: -------------------------------------------------------------------------------- 1 | m_EditorVersion: 2019.3.0f6 2 | m_EditorVersionWithRevision: 2019.3.0f6 (27ab2135bccf) 3 | -------------------------------------------------------------------------------- /ProjectSettings/QualitySettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!47 &1 4 | QualitySettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 5 7 | m_CurrentQuality: 5 8 | m_QualitySettings: 9 | - serializedVersion: 2 10 | name: Very Low 11 | pixelLightCount: 0 12 | shadows: 0 13 | shadowResolution: 0 14 | shadowProjection: 1 15 | shadowCascades: 1 16 | shadowDistance: 15 17 | shadowNearPlaneOffset: 3 18 | shadowCascade2Split: 0.33333334 19 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 20 | shadowmaskMode: 0 21 | skinWeights: 1 22 | textureQuality: 1 23 | anisotropicTextures: 0 24 | antiAliasing: 0 25 | softParticles: 0 26 | softVegetation: 0 27 | realtimeReflectionProbes: 0 28 | billboardsFaceCameraPosition: 0 29 | vSyncCount: 0 30 | lodBias: 0.3 31 | maximumLODLevel: 0 32 | streamingMipmapsActive: 0 33 | streamingMipmapsAddAllCameras: 1 34 | streamingMipmapsMemoryBudget: 512 35 | streamingMipmapsRenderersPerFrame: 512 36 | streamingMipmapsMaxLevelReduction: 2 37 | streamingMipmapsMaxFileIORequests: 1024 38 | particleRaycastBudget: 4 39 | asyncUploadTimeSlice: 2 40 | asyncUploadBufferSize: 16 41 | asyncUploadPersistentBuffer: 1 42 | resolutionScalingFixedDPIFactor: 1 43 | excludedTargetPlatforms: [] 44 | - serializedVersion: 2 45 | name: Low 46 | pixelLightCount: 0 47 | shadows: 0 48 | shadowResolution: 0 49 | shadowProjection: 1 50 | shadowCascades: 1 51 | shadowDistance: 20 52 | shadowNearPlaneOffset: 3 53 | shadowCascade2Split: 0.33333334 54 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 55 | shadowmaskMode: 0 56 | skinWeights: 2 57 | textureQuality: 0 58 | anisotropicTextures: 0 59 | antiAliasing: 0 60 | softParticles: 0 61 | softVegetation: 0 62 | realtimeReflectionProbes: 0 63 | billboardsFaceCameraPosition: 0 64 | vSyncCount: 0 65 | lodBias: 0.4 66 | maximumLODLevel: 0 67 | streamingMipmapsActive: 0 68 | streamingMipmapsAddAllCameras: 1 69 | streamingMipmapsMemoryBudget: 512 70 | streamingMipmapsRenderersPerFrame: 512 71 | streamingMipmapsMaxLevelReduction: 2 72 | streamingMipmapsMaxFileIORequests: 1024 73 | particleRaycastBudget: 16 74 | asyncUploadTimeSlice: 2 75 | asyncUploadBufferSize: 16 76 | asyncUploadPersistentBuffer: 1 77 | resolutionScalingFixedDPIFactor: 1 78 | excludedTargetPlatforms: [] 79 | - serializedVersion: 2 80 | name: Medium 81 | pixelLightCount: 1 82 | shadows: 1 83 | shadowResolution: 0 84 | shadowProjection: 1 85 | shadowCascades: 1 86 | shadowDistance: 20 87 | shadowNearPlaneOffset: 3 88 | shadowCascade2Split: 0.33333334 89 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 90 | shadowmaskMode: 0 91 | skinWeights: 2 92 | textureQuality: 0 93 | anisotropicTextures: 1 94 | antiAliasing: 0 95 | softParticles: 0 96 | softVegetation: 0 97 | realtimeReflectionProbes: 0 98 | billboardsFaceCameraPosition: 0 99 | vSyncCount: 1 100 | lodBias: 0.7 101 | maximumLODLevel: 0 102 | streamingMipmapsActive: 0 103 | streamingMipmapsAddAllCameras: 1 104 | streamingMipmapsMemoryBudget: 512 105 | streamingMipmapsRenderersPerFrame: 512 106 | streamingMipmapsMaxLevelReduction: 2 107 | streamingMipmapsMaxFileIORequests: 1024 108 | particleRaycastBudget: 64 109 | asyncUploadTimeSlice: 2 110 | asyncUploadBufferSize: 16 111 | asyncUploadPersistentBuffer: 1 112 | resolutionScalingFixedDPIFactor: 1 113 | excludedTargetPlatforms: [] 114 | - serializedVersion: 2 115 | name: High 116 | pixelLightCount: 2 117 | shadows: 2 118 | shadowResolution: 1 119 | shadowProjection: 1 120 | shadowCascades: 2 121 | shadowDistance: 40 122 | shadowNearPlaneOffset: 3 123 | shadowCascade2Split: 0.33333334 124 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 125 | shadowmaskMode: 1 126 | skinWeights: 2 127 | textureQuality: 0 128 | anisotropicTextures: 1 129 | antiAliasing: 0 130 | softParticles: 0 131 | softVegetation: 1 132 | realtimeReflectionProbes: 1 133 | billboardsFaceCameraPosition: 1 134 | vSyncCount: 1 135 | lodBias: 1 136 | maximumLODLevel: 0 137 | streamingMipmapsActive: 0 138 | streamingMipmapsAddAllCameras: 1 139 | streamingMipmapsMemoryBudget: 512 140 | streamingMipmapsRenderersPerFrame: 512 141 | streamingMipmapsMaxLevelReduction: 2 142 | streamingMipmapsMaxFileIORequests: 1024 143 | particleRaycastBudget: 256 144 | asyncUploadTimeSlice: 2 145 | asyncUploadBufferSize: 16 146 | asyncUploadPersistentBuffer: 1 147 | resolutionScalingFixedDPIFactor: 1 148 | excludedTargetPlatforms: [] 149 | - serializedVersion: 2 150 | name: Very High 151 | pixelLightCount: 3 152 | shadows: 2 153 | shadowResolution: 2 154 | shadowProjection: 1 155 | shadowCascades: 2 156 | shadowDistance: 70 157 | shadowNearPlaneOffset: 3 158 | shadowCascade2Split: 0.33333334 159 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 160 | shadowmaskMode: 1 161 | skinWeights: 4 162 | textureQuality: 0 163 | anisotropicTextures: 2 164 | antiAliasing: 2 165 | softParticles: 1 166 | softVegetation: 1 167 | realtimeReflectionProbes: 1 168 | billboardsFaceCameraPosition: 1 169 | vSyncCount: 1 170 | lodBias: 1.5 171 | maximumLODLevel: 0 172 | streamingMipmapsActive: 0 173 | streamingMipmapsAddAllCameras: 1 174 | streamingMipmapsMemoryBudget: 512 175 | streamingMipmapsRenderersPerFrame: 512 176 | streamingMipmapsMaxLevelReduction: 2 177 | streamingMipmapsMaxFileIORequests: 1024 178 | particleRaycastBudget: 1024 179 | asyncUploadTimeSlice: 2 180 | asyncUploadBufferSize: 16 181 | asyncUploadPersistentBuffer: 1 182 | resolutionScalingFixedDPIFactor: 1 183 | excludedTargetPlatforms: [] 184 | - serializedVersion: 2 185 | name: Ultra 186 | pixelLightCount: 4 187 | shadows: 2 188 | shadowResolution: 2 189 | shadowProjection: 1 190 | shadowCascades: 4 191 | shadowDistance: 150 192 | shadowNearPlaneOffset: 3 193 | shadowCascade2Split: 0.33333334 194 | shadowCascade4Split: {x: 0.06666667, y: 0.2, z: 0.46666667} 195 | shadowmaskMode: 1 196 | skinWeights: 4 197 | textureQuality: 0 198 | anisotropicTextures: 2 199 | antiAliasing: 2 200 | softParticles: 1 201 | softVegetation: 1 202 | realtimeReflectionProbes: 1 203 | billboardsFaceCameraPosition: 1 204 | vSyncCount: 1 205 | lodBias: 2 206 | maximumLODLevel: 0 207 | streamingMipmapsActive: 0 208 | streamingMipmapsAddAllCameras: 1 209 | streamingMipmapsMemoryBudget: 512 210 | streamingMipmapsRenderersPerFrame: 512 211 | streamingMipmapsMaxLevelReduction: 2 212 | streamingMipmapsMaxFileIORequests: 1024 213 | particleRaycastBudget: 4096 214 | asyncUploadTimeSlice: 2 215 | asyncUploadBufferSize: 16 216 | asyncUploadPersistentBuffer: 1 217 | resolutionScalingFixedDPIFactor: 1 218 | excludedTargetPlatforms: [] 219 | m_PerPlatformDefaultQuality: 220 | Android: 2 221 | Lumin: 5 222 | Nintendo 3DS: 5 223 | Nintendo Switch: 5 224 | PS4: 5 225 | PSP2: 2 226 | Standalone: 5 227 | WebGL: 3 228 | Windows Store Apps: 5 229 | XboxOne: 5 230 | iPhone: 2 231 | tvOS: 2 232 | -------------------------------------------------------------------------------- /ProjectSettings/TagManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!78 &1 4 | TagManager: 5 | serializedVersion: 2 6 | tags: [] 7 | layers: 8 | - Default 9 | - TransparentFX 10 | - Ignore Raycast 11 | - 12 | - Water 13 | - UI 14 | - 15 | - 16 | - 17 | - 18 | - 19 | - 20 | - 21 | - 22 | - 23 | - 24 | - 25 | - 26 | - 27 | - 28 | - 29 | - 30 | - 31 | - 32 | - 33 | - 34 | - 35 | - 36 | - 37 | - 38 | - 39 | - 40 | m_SortingLayers: 41 | - name: Default 42 | uniqueID: 0 43 | locked: 0 44 | -------------------------------------------------------------------------------- /ProjectSettings/TimeManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!5 &1 4 | TimeManager: 5 | m_ObjectHideFlags: 0 6 | Fixed Timestep: 0.02 7 | Maximum Allowed Timestep: 0.33333334 8 | m_TimeScale: 1 9 | Maximum Particle Timestep: 0.03 10 | -------------------------------------------------------------------------------- /ProjectSettings/UnityConnectSettings.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!310 &1 4 | UnityConnectSettings: 5 | m_ObjectHideFlags: 0 6 | serializedVersion: 1 7 | m_Enabled: 0 8 | m_TestMode: 0 9 | m_EventOldUrl: https://api.uca.cloud.unity3d.com/v1/events 10 | m_EventUrl: https://cdp.cloud.unity3d.com/v1/events 11 | m_ConfigUrl: https://config.uca.cloud.unity3d.com 12 | m_TestInitMode: 0 13 | CrashReportingSettings: 14 | m_EventUrl: https://perf-events.cloud.unity3d.com 15 | m_Enabled: 0 16 | m_LogBufferSize: 10 17 | m_CaptureEditorExceptions: 1 18 | UnityPurchasingSettings: 19 | m_Enabled: 0 20 | m_TestMode: 0 21 | UnityAnalyticsSettings: 22 | m_Enabled: 0 23 | m_TestMode: 0 24 | m_InitializeOnStartup: 1 25 | UnityAdsSettings: 26 | m_Enabled: 0 27 | m_InitializeOnStartup: 1 28 | m_TestMode: 0 29 | m_IosGameId: 30 | m_AndroidGameId: 31 | m_GameIds: {} 32 | m_GameId: 33 | PerformanceReportingSettings: 34 | m_Enabled: 0 35 | -------------------------------------------------------------------------------- /ProjectSettings/VFXManager.asset: -------------------------------------------------------------------------------- 1 | %YAML 1.1 2 | %TAG !u! tag:unity3d.com,2011: 3 | --- !u!937362698 &1 4 | VFXManager: 5 | m_ObjectHideFlags: 0 6 | m_IndirectShader: {fileID: 0} 7 | m_CopyBufferShader: {fileID: 0} 8 | m_SortShader: {fileID: 0} 9 | m_RenderPipeSettingsPath: 10 | m_FixedTimeStep: 0.016666668 11 | m_MaxDeltaTime: 0.05 12 | -------------------------------------------------------------------------------- /ProjectSettings/XRSettings.asset: -------------------------------------------------------------------------------- 1 | { 2 | "m_SettingKeys": [ 3 | "VR Device Disabled", 4 | "VR Device User Alert" 5 | ], 6 | "m_SettingValues": [ 7 | "False", 8 | "False" 9 | ] 10 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UnityTerrainErosionGPU 2 | Hydraulic and thermal erosion implement in Unity using compute shaders. 3 | 4 | ![UnityTerrainErosionGPU](https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/master/Resources/screen1.png) 5 | 6 | This is an example implementation of hydraulic and thermal erosion with shallow water equations. My initial motivation was to implement a game mechanic like in the [From Dust](https://en.wikipedia.org/wiki/From_Dust) game. 7 | 8 | 9 | ## Disclaimer 10 | This project is still in progress. Hydraulic erosion requires a bit more parameter tweaking and revisiting the actual implementation. But overall it works. 11 | 12 | ## Demo 13 | Just run `Main` Scene and use the mouse to draw modify terrain/water. 14 | 15 | ## How it works 16 | Explanation is still in progress... 17 | 18 | ### Data / notation 19 | We first need to list all the data we will operate with during the simulation. Since we are using a grid-based simulation we will need some per-cell information. Assuming we have a grid of size W \times H and current cell coordinates are (i, j). 20 | 21 | - Simulation parameters 22 | - W - grid width 23 | - H - grid height 24 | - \Delta t - simulation time delta 25 | - g - gravity 26 | - l_x - cell size along x axis 27 | - l_y - cell size along y axis 28 | - l - pipe length 29 | - A - pip cross-section area 30 | - K_e - evaporation rate 31 | - K_r - rain rate 32 | - Hydraulic erosion parameters 33 | - K_c - sediment capacity 34 | - K_s - soil suspension rate 35 | - K_d - soil deposition rate 36 | - l_{max} - erosion depth limit 37 | - Thermal erosion parameters 38 | - K_t - thermal erosion rate 39 | - K^s_\alpha - talus angle scale 40 | - K^b_\alpha - talus angle bias 41 | - Grid-values 42 | - h^{terrain}_{i,j} - height of terrain in cell (i, j), must be positive 43 | - h^{water}_{i,j} - height of water in cell (i, j), must be positive 44 | - s_{i,j} - suspended sediment amount in cell (i, j) 45 | - r_{i,j} - terrain hardness in cell (i, j) 46 | - f^{left}_{i,j}, f^{right}_{i,j}, f^{up}_{i,j}, f^{down}_{i,j} - water flow (flux) in each direction in cell (i, j) 47 | - p^{left}_{i,j}, p^{right}_{i,j}, p^{up}_{i,j}, p^{down}_{i,j} - terrain mass flow (flux) in each direction in cell (i, j) 48 | - v^x_{i,j} - water velocity in x direction in cell (i, j) 49 | - v^y_{i,j} - water velocity in y direction in cell (i, j) 50 | 51 | ### Step 1. Water sources 52 | We need to increase the water amount from water sources (e.g. rain). Right now the brush-drawing is omitted for clarity, but it happens in this step. 53 | 54 | h^{water}_{i,j} := h^{water}_{i,j} + \Delta t K_e 55 | 56 | ### Step 2. Water flow computation 57 | Water flow is proportional to the height difference in each cell because of pressure emerging from the height of water. Thus, to compute flow in each direction of cell we need to calculate the height differences: 58 | 59 | \Delta h^{left}_{i,j} := (h^{terrain}_{i,j} + h^{water}_{i,j}) - (h^{terrain}_{i-1,j} + h^{water}_{i-1,j}) 60 | 61 | And repeat for other directions. Then we need to compute the outgoing amount of water from the current cell to the neighbors (in each direction) which is proportional to the volume diefference - height difference \Delta h^{left}_{i,j} multiplied by cell area (l_x \times l_y): 62 | 63 | f^{left}_{i,j} := k \cdot max\Big(0,f^{left}_{i,j} + \frac{\Delta t g l_x l_y h^{left}_{i,j}}{l}  \Big) 64 | 65 | and also repeat the computation for each direction. k - is a special scaling factor to prevent situations when total outflow in 4 directions is higher than water volume in cell (since each direction is computed independently). Thus k is defined to split the scale the outflow accordingly - cell water volume divided by total outflow per single step: 66 | 67 | k = min\Big(1, \frac{h^{water}_{i,j} l_x l_y}{\Delta t \big[f^{left}_{i,j} + f^{right}_{i,j} + f^{up}_{i,j} +f^{down}_{i,j} \big]}\Big) 68 | 69 | If outflow will exceed the total volume, the fraction will be less than 1 thus flow will be reduced. 70 | 71 | #### Boundaries 72 | If we need the water to bounce off the walls we need to disable outgouing flow at the boundaries: 73 | 74 | f^{left}_{0,j} := 0 75 | 76 | f^{right}_{W-1,j} := 0 77 | 78 | f^{down}_{i,0} := 0 79 | 80 | f^{up}_{i,H-1} := 0 81 | 82 | At the end of this step, we got all the outgouing flow computed at each cell so we now need to use this flow information to adjust the height of the water. 83 | 84 | 85 | ### Step 3. Appling the water flow 86 | The water height in each should increase by the total amount of incoming flow and decrease by the amount of total outgoing flow. 87 | 88 | f^{out} = f^{left}_{i,j} + f^{right}_{i,j} + f^{up}_{i,j} +f^{down}_{i,j} 89 | 90 | outgoing flow is the same as at the previous step. 91 | 92 | f^{in} = f^{right}_{i-1,j} + f^{left}_{i+1,j}+ f^{up}_{i,j-1} + f^{down}_{i,j+1} 93 | 94 | incoming flow is the outgoing flow from neighbor cells in opposite directions. 95 | 96 | The total volume change of the column is: 97 | 98 | \Delta V =\Delta t ( f^{in} - f^{out} ) 99 | 100 | Finally apply the volume change to the water column, since we store the height and not the volume we need to divide by cell area: 101 | 102 | h^{water}_{i,j} := h^{water}_{i,j} + \frac{\Delta V}{l_x l_y} 103 | 104 | And that's it for water flow. It is also called shallow water equations using pipe model. At the end of this step, the water can slide down the terrain, create vertical waves and so on. But to apply erosion we will need to do more stuff. 105 | 106 | ### Step 3.5. Compute water velocity 107 | In further computation we will need the information about the water velocity in each cell. We can compute it using information about the water flow: 108 | 109 | v^{x}_{i,j} := \frac{f^{right}_{i-1,j} - f^{left}_{i,j} + f^{right}_{i,j} - f^{left}_{i+1,j}}{2} 110 | 111 | v^{y}_{i,j} := \frac{f^{up}_{i,j-1} - f^{down}_{i,j} + f^{up}_{i,j} - f^{left}_{i,j+1}}{2} 112 | 113 | \vec{v}_{i,j} = \{v^{x}_{i,j}; v^{y}_{i,j} \} 114 | 115 | the velocity in each axis is the average total flow in each pipe along that axis. So for x axis we have 2 neighbor cells: (i-1, j) and (i+1, j), thus we can compute the total flow for each neighbor and average across neighbors. 116 | 117 | **Note**: This is only partially physically accurate. For the true velocity - this amount should be scaled by something (include pipe area and length). 118 | 119 | ### Step 4. Hydraulic erosion and deposition 120 | While water flows over terrain it takes (erodes) and transports some amount of soil. After a while, some suspended sediment will be deposited to the ground. This process is mostly defined by the sediment transport capacity of the water flow. There are many complex models regarding these processes, but we will use the simple empirical equation: 121 | 122 | C_{i,j}=K_c \cdot sin(\alpha_{i,j}) \cdot |\vec{v}_{i,j}| 123 | 124 | ### Step 5. Thermal Erosion 125 | ... 126 | 127 | 128 | ## Project structure 129 | - `Shaders` 130 | - [`Shaders/Erosion.compute`](https://github.com/bshishov/UnityTerrainErosionGPU/blob/master/Assets/Shaders/Erosion.compute) - all computational stuff happening there in form of separate compute kernels (functions) acting like passes and responsible for different things. Look through that file if you are interested in the actual algorithm implementation. 131 | - [`Shaders/Water.shader`](https://github.com/bshishov/UnityTerrainErosionGPU/blob/master/Assets/Shaders/Water.shader) - Surface shader for rendering water plane. In vertex shader vertex positions are updated from state texture and normals are computed. It has basic lighting and alpha decay depending on depth. 132 | - [`Shaders/Surface.shader`](https://github.com/bshishov/UnityTerrainErosionGPU/blob/master/Assets/Shaders/Surface.shader) - A lit shader to render the terrain surface. In vertex shader vertex positions are updated from state texture and normals are computed. 133 | - [`Shaders/InitHeightmap.shader`](https://github.com/bshishov/UnityTerrainErosionGPU/blob/master/Assets/Shaders/InitHeightmap.shader) - A special shader to initialize initial state from common grayscale heightmap texture. Since state texture is a float texture and operates with values higher than 1 the original heightmap texture should be scaled. This shader is used in the special material used in `Simulation.cs`. 134 | - [`Scripts/Simulation.cs`](https://github.com/bshishov/UnityTerrainErosionGPU/blob/master/Assets/Scripts/Simulation.cs) - main Monobehavior responsible for compute shader setup, dispatching computation to the GPU, texture creation, parameter sharing, and dispatching drawing. 135 | - [`Scripts/ChunkedPlane.cs`](https://github.com/bshishov/UnityTerrainErosionGPU/blob/master/Assets/Scripts/ChunkedPlane.cs) - main Monobehavior responsible for terrain mesh creation. 136 | 137 | ## References 138 | - Mei, Xing, Philippe Decaudin, and Bao-Gang Hu. "**Fast hydraulic erosion simulation and visualization on GPU.**" 15th Pacific Conference on Computer Graphics and Applications (PG'07). IEEE, 2007. http://www.nlpr.ia.ac.cn/2007papers/gjhy/gh116.pdf 139 | - Jákó, Balázs, and Balázs Tóth. "**Fast Hydraulic and Thermal Erosion on GPU.**" Eurographics (Short Papers). 2011. http://old.cescg.org/CESCG-2011/papers/TUBudapest-Jako-Balazs.pdf 140 | *Warning: poor paper quality along with math mistakes. But has nice ideas.* 141 | - Št'ava, Ondřej, et al. "**Interactive terrain modeling using hydraulic erosion.**" Proceedings of the 2008 ACM SIGGRAPH/Eurographics Symposium on Computer Animation. Eurographics Association, 2008. http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.173.5239&rep=rep1&type=pdf 142 | 143 | 144 | ## TODO: 145 | - Better explanation of the implementation 146 | - More descriptive comments in code 147 | - Quality of life: 148 | - Better editor - camera controls and better brush controls 149 | - Different initial state loaders (from terrain data, from 16bit textures, from `.raw`) 150 | - Terrain chunks to simplify rendering of distant terrain parts -------------------------------------------------------------------------------- /Resources/screen1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bshishov/UnityTerrainErosionGPU/0e59f7c42b5ccbc8bc637b7a6435c3af648bc8b6/Resources/screen1.png --------------------------------------------------------------------------------