From 65b158f3878979e5d213b20b138c25a7fcd5d84d Mon Sep 17 00:00:00 2001 From: PopSlime Date: Fri, 4 Jul 2025 23:20:55 +0800 Subject: [PATCH] feat: Implement hillshade layer --- Assets/Cryville.EEW.Unity/Config.cs | 2 + .../Map/CameraController.cs | 25 ++++- .../Map/HillshadeMapTileCacheManager.cs | 15 +++ .../Map/HillshadeMapTileCacheManager.cs.meta | 11 ++ Assets/Cryville.EEW.Unity/Map/MapTile.cs | 14 ++- .../Map/MapTileBitmapHolder.cs | 13 +++ .../Map/MapTileBitmapHolderBehaviour.cs | 68 ++++++++++-- .../Map/MapTileCacheManager.cs | 21 +++- Assets/Cryville.EEW.Unity/SharedSettings.cs | 2 + Assets/Main.unity | 34 ++++++ Assets/Materials/Multiply.mat | 91 ++++++++++++++++ Assets/Materials/Multiply.mat.meta | 8 ++ Assets/Prefabs/TileMultiply.prefab | 100 ++++++++++++++++++ Assets/Prefabs/TileMultiply.prefab.meta | 7 ++ Assets/Shaders/Multiply.shader | 54 ++++++++++ Assets/Shaders/Multiply.shader.meta | 9 ++ 16 files changed, 453 insertions(+), 21 deletions(-) create mode 100644 Assets/Cryville.EEW.Unity/Map/HillshadeMapTileCacheManager.cs create mode 100644 Assets/Cryville.EEW.Unity/Map/HillshadeMapTileCacheManager.cs.meta create mode 100644 Assets/Materials/Multiply.mat create mode 100644 Assets/Materials/Multiply.mat.meta create mode 100644 Assets/Prefabs/TileMultiply.prefab create mode 100644 Assets/Prefabs/TileMultiply.prefab.meta create mode 100644 Assets/Shaders/Multiply.shader create mode 100644 Assets/Shaders/Multiply.shader.meta diff --git a/Assets/Cryville.EEW.Unity/Config.cs b/Assets/Cryville.EEW.Unity/Config.cs index cc3127d..101a1fe 100644 --- a/Assets/Cryville.EEW.Unity/Config.cs +++ b/Assets/Cryville.EEW.Unity/Config.cs @@ -12,6 +12,7 @@ namespace Cryville.EEW.Unity { float SeverityColorMappingLuminanceMultiplier, bool UseContinuousColor, string ColorScheme, + float HillshadeLayerOpacity, string LocationNamer, string OverrideTimeZone, @@ -31,6 +32,7 @@ namespace Cryville.EEW.Unity { 1f, false, "Default", + 1, "FERegionLong", null, diff --git a/Assets/Cryville.EEW.Unity/Map/CameraController.cs b/Assets/Cryville.EEW.Unity/Map/CameraController.cs index 6cc92f1..766af48 100644 --- a/Assets/Cryville.EEW.Unity/Map/CameraController.cs +++ b/Assets/Cryville.EEW.Unity/Map/CameraController.cs @@ -1,3 +1,4 @@ +using Cryville.EEW.Core.Map; using System; using System.Drawing; using UnityEngine; @@ -10,12 +11,16 @@ namespace Cryville.EEW.Unity.Map { [SerializeField] Transform m_layerTile; [SerializeField] + Transform m_layerTileHillshade; + [SerializeField] MapElementManager m_layerElement; [SerializeField] MapElementManager m_layerElementSub; [SerializeField] GameObject m_prefabTile; [SerializeField] + GameObject m_prefabTileHillshade; + [SerializeField] GameObject m_prefabBitmapHolder; [SerializeField] int m_maxMapTileZoom = 10; @@ -23,6 +28,7 @@ namespace Cryville.EEW.Unity.Map { bool m_isEditor; MapTileCacheManager _tiles; + MapTileCacheManager _tilesHillshade; float _elementLayerZ; void Start() { @@ -33,12 +39,23 @@ namespace Cryville.EEW.Unity.Map { _tiles.PrefabTile = m_prefabTile; _tiles.PrefabBitmapHolder = m_prefabBitmapHolder; _tiles.CacheDir = Application.temporaryCachePath; + if (m_layerTileHillshade) { + m_prefabTileHillshade.GetComponent().sharedMaterial.color = new UnityEngine.Color(1, 1, 1, SharedSettings.Instance.HillshadeLayerOpacity); + _tilesHillshade = new HillshadeMapTileCacheManager { + ExtraCachedZoomLevel = 20, + Parent = m_layerTileHillshade, + PrefabTile = m_prefabTileHillshade, + PrefabBitmapHolder = m_prefabBitmapHolder, + CacheDir = Application.temporaryCachePath, + }; + } _camera.orthographicSize = 0.5f / MathF.Max(1, (float)_camera.pixelWidth / _camera.pixelHeight); if (m_layerElement != null) _elementLayerZ = m_layerElement.transform.position.z; _mapElementUpdated = true; } void OnDestroy() { _tiles.Dispose(); + _tilesHillshade?.Dispose(); } float Scale { @@ -104,10 +121,10 @@ namespace Cryville.EEW.Unity.Map { var bounds = new Bounds((Vector2)transform.position, new Vector2(w, h)); int zoom = Math.Clamp((int)Math.Log(vz / 256, 2) + 1, 0, m_maxMapTileZoom); int zoomScale = 1 << zoom; - _tiles.MoveTo( - new(Mathf.FloorToInt(bounds.min.x * zoomScale), Mathf.FloorToInt(-bounds.max.y * zoomScale), zoom), - new(Mathf.CeilToInt(bounds.max.x * zoomScale), Mathf.CeilToInt(-bounds.min.y * zoomScale), zoom) - ); + var a = new MapTileIndex(Mathf.FloorToInt(bounds.min.x * zoomScale), Mathf.FloorToInt(-bounds.max.y * zoomScale), zoom); + var b = new MapTileIndex(Mathf.CeilToInt(bounds.max.x * zoomScale), Mathf.CeilToInt(-bounds.min.y * zoomScale), zoom); + _tiles.MoveTo(a, b); + _tilesHillshade?.MoveTo(a, b); if (m_layerElement != null) { m_layerElement.Scale = h; diff --git a/Assets/Cryville.EEW.Unity/Map/HillshadeMapTileCacheManager.cs b/Assets/Cryville.EEW.Unity/Map/HillshadeMapTileCacheManager.cs new file mode 100644 index 0000000..a5bd94f --- /dev/null +++ b/Assets/Cryville.EEW.Unity/Map/HillshadeMapTileCacheManager.cs @@ -0,0 +1,15 @@ +using Cryville.EEW.Core.Map; +using System.IO; +using UnityEngine; + +namespace Cryville.EEW.Unity.Map { + sealed class HillshadeMapTileCacheManager : MapTileCacheManager { + protected override MapTileBitmapHolder CreateBitmapHolder(MapTileIndex index) => new( + index, + GameObject.Instantiate(PrefabBitmapHolder, Parent, false), + new($"https://services.arcgisonline.com/arcgis/rest/services/Elevation/World_Hillshade/MapServer/tile/{index.Z}/{index.NY}/{index.NX}.png") + ); + + protected override string GetCacheFilePath(MapTileIndex index) => Path.Combine(CacheDir, $"map_hillshade/{index.Z}/{index.NX}/{index.NY}"); + } +} diff --git a/Assets/Cryville.EEW.Unity/Map/HillshadeMapTileCacheManager.cs.meta b/Assets/Cryville.EEW.Unity/Map/HillshadeMapTileCacheManager.cs.meta new file mode 100644 index 0000000..391b4d6 --- /dev/null +++ b/Assets/Cryville.EEW.Unity/Map/HillshadeMapTileCacheManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: d5fed9b884a4ff54f837aa0f2265ad36 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Cryville.EEW.Unity/Map/MapTile.cs b/Assets/Cryville.EEW.Unity/Map/MapTile.cs index f9ac4e6..92c6765 100644 --- a/Assets/Cryville.EEW.Unity/Map/MapTile.cs +++ b/Assets/Cryville.EEW.Unity/Map/MapTile.cs @@ -19,10 +19,12 @@ namespace Cryville.EEW.Unity.Map { float z = 1 << index.Z; transform.localPosition = new(index.X / z, -(index.Y + 1) / z, -index.Z / 100f); transform.localScale = new Vector3(1 / z, 1 / z, 1); - _idView.gameObject.SetActive(true); - byte e = SharedSettings.Instance.IdBytes[((index.X << 2) + index.Y) & 0x1f]; - int ex = e >> 4, ey = e & 0xf; - _idView.localPosition = new(ex / 16f, 1 - ey / 16f, -1 / 200f); + if (_idView) { + _idView.gameObject.SetActive(true); + byte e = SharedSettings.Instance.IdBytes[((index.X << 2) + index.Y) & 0x1f]; + int ex = e >> 4, ey = e & 0xf; + _idView.localPosition = new(ex / 16f, 1 - ey / 16f, -1 / 200f); + } } public void Set(Sprite sprite) { @@ -40,5 +42,9 @@ namespace Cryville.EEW.Unity.Map { Destroy(gameObject); } } + + public void SetVisible(bool v) { + _renderer.enabled = v; + } } } diff --git a/Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolder.cs b/Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolder.cs index d2a5bf3..ec8e9e1 100644 --- a/Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolder.cs +++ b/Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolder.cs @@ -12,6 +12,7 @@ namespace Cryville.EEW.Unity.Map { public MapTileBitmapHolder(MapTileIndex index, GameObject gameObject, Uri uri) : base(index) { _behaviour = gameObject.GetComponent(); + _behaviour.Index = index; _uri = uri; } @@ -32,5 +33,17 @@ namespace Cryville.EEW.Unity.Map { public void Bind(MapTile tile) { _behaviour.Bind(tile); } + + public void Unbind(MapTile tile) { + _behaviour.Unbind(tile); + } + + public void AddChild(MapTileBitmapHolder bitmapHolder) { + _behaviour.AddChild(bitmapHolder._behaviour); + } + + public void RemoveChild(MapTileBitmapHolder bitmapHolder) { + _behaviour.RemoveChild(bitmapHolder._behaviour); + } } } diff --git a/Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolderBehaviour.cs b/Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolderBehaviour.cs index 53b69e5..a73ad8b 100644 --- a/Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolderBehaviour.cs +++ b/Assets/Cryville.EEW.Unity/Map/MapTileBitmapHolderBehaviour.cs @@ -1,16 +1,39 @@ +using Cryville.EEW.Core.Map; using System; +using System.Collections.Generic; using System.IO; using UnityEngine; using UnityEngine.Networking; namespace Cryville.EEW.Unity.Map { sealed class MapTileBitmapHolderBehaviour : MonoBehaviour { - Action _callback; + public MapTileIndex Index { get; set; } + + readonly List _tiles = new(); public void Bind(MapTile tile) { - if (_isDone) + _tiles.Add(tile); + if (_sprite) { tile.Set(_sprite); - else - _callback += tile.Set; + } + } + public void Unbind(MapTile tile) { + _tiles.Remove(tile); + } + + readonly List _children = new(); + public void AddChild(MapTileBitmapHolderBehaviour behaviour) { + _children.Add(behaviour); + foreach (var tile in _tiles) { + tile.SetVisible(false); + } + SetChildSprite(behaviour); + } + public void RemoveChild(MapTileBitmapHolderBehaviour behaviour) { + _children.Remove(behaviour); + bool isActive = _children.Count == 0; + foreach (var tile in _tiles) { + tile.SetVisible(isActive); + } } UnityWebRequest _req; @@ -20,7 +43,6 @@ namespace Cryville.EEW.Unity.Map { FileInfo _localFile; bool _isReady; - bool _isDone; public void Load(FileInfo file) { _localFile = file; _isReady = true; @@ -48,7 +70,7 @@ namespace Cryville.EEW.Unity.Map { if (_texHandler.isDone && _texHandler.texture != null) { _tex = _texHandler.texture; _tex.wrapMode = TextureWrapMode.Clamp; - _sprite = Sprite.Create(_tex, new Rect(0, 0, _tex.width, _tex.height), Vector2.zero, _tex.height, 0, SpriteMeshType.FullRect, Vector4.zero, false); + SetSprite(_tex, 0, 0, 0); } else { App.MainLogger.Log(4, "Map", null, "An error occurred when loading map tile {0}: {1}", _localFile, _texHandler.error); @@ -57,10 +79,32 @@ namespace Cryville.EEW.Unity.Map { _req.Dispose(); _texHandler.Dispose(); _req = null; - _callback?.Invoke(_sprite); - _isDone = true; } + int _minDz = int.MaxValue; + int _x, _y; + void SetSprite(Texture2D tex, int dz, int x, int y) { + if (dz >= 8) return; + if (dz > _minDz) return; + _tex = tex; + _x = x; _y = y; + _minDz = dz; + if (_sprite) Destroy(_sprite); + int sx = x << (8 - dz), sy = 256 - ((y + 1) << (8 - dz)); + _sprite = Sprite.Create(tex, new Rect(sx, sy, 1 << (8 - dz), 1 << (8 - dz)), Vector2.zero, 1 << (8 - dz), 0, SpriteMeshType.FullRect, Vector4.zero, false); + foreach (var tile in _tiles) + tile.Set(_sprite); + foreach (var child in _children) { + SetChildSprite(child); + } + } + + void SetChildSprite(MapTileBitmapHolderBehaviour child) { + if (!_tex) return; + int cdz = child.Index.Z - Index.Z; + int cx = child.Index.X % (1 << cdz) | (_x << cdz), cy = child.Index.Y % (1 << cdz) | (_y << cdz); + child.SetSprite(_tex, cdz + _minDz, cx, cy); + } bool _isDestroyed; public void Destroy() { @@ -69,11 +113,15 @@ namespace Cryville.EEW.Unity.Map { void OnDestroy() { if (_req != null) { _req.Abort(); + if (_texHandler != null) { + var tex = _texHandler.texture; + if (tex) Destroy(tex); + _texHandler.Dispose(); + } _req.Dispose(); - _texHandler.Dispose(); } if (_sprite) Destroy(_sprite); - if (_tex) Destroy(_tex); + if (_tex && _minDz == 0) Destroy(_tex); } } } diff --git a/Assets/Cryville.EEW.Unity/Map/MapTileCacheManager.cs b/Assets/Cryville.EEW.Unity/Map/MapTileCacheManager.cs index 38bcb53..6436b98 100644 --- a/Assets/Cryville.EEW.Unity/Map/MapTileCacheManager.cs +++ b/Assets/Cryville.EEW.Unity/Map/MapTileCacheManager.cs @@ -1,4 +1,5 @@ using Cryville.EEW.Core.Map; +using System; using System.Collections.Generic; using System.IO; using UnityEngine; @@ -17,7 +18,7 @@ namespace Cryville.EEW.Unity.Map { GameObject.Instantiate(PrefabBitmapHolder, Parent, false), new($"https://server.arcgisonline.com/ArcGIS/rest/services/Ocean/World_Ocean_Base/MapServer/tile/{index.Z}/{index.NY}/{index.NX}") ); - + protected override string GetCacheFilePath(MapTileIndex index) => Path.Combine(CacheDir, $"map/{index.Z}/{index.NX}/{index.NY}"); readonly Dictionary, MapTile> _map = new(); @@ -26,16 +27,30 @@ namespace Cryville.EEW.Unity.Map { var gameObject = GameObject.Instantiate(PrefabTile, Parent, false); var uTile = gameObject.GetComponent(); _map.Add(tile, uTile); - uTile.Init(tile.Index); - tile.BitmapHolder.Bind(uTile); + var index = tile.Index; + uTile.Init(index); + var bitmapHolder = tile.BitmapHolder; + bitmapHolder.Bind(uTile); + + if (index.Z <= 0) return; + var maybeTile = FindTile(index.ZoomToLevel(index.Z - 1, Math.Floor), false); + if (maybeTile is not MapTile parentTile) return; + parentTile.BitmapHolder.AddChild(bitmapHolder); } protected override void OnTileDestroyed(MapTile tile) { base.OnTileDestroyed(tile); + var bitmapHolder = tile.BitmapHolder; if (_map.TryGetValue(tile, out var uTile)) { uTile.Destroy(); + bitmapHolder.Unbind(uTile); _map.Remove(tile); } + var index = tile.Index; + if (index.Z <= 0) return; + var maybeTile = FindTile(index.ZoomToLevel(index.Z - 1, Math.Floor), false); + if (maybeTile is not MapTile parentTile) return; + parentTile.BitmapHolder.RemoveChild(bitmapHolder); } } } diff --git a/Assets/Cryville.EEW.Unity/SharedSettings.cs b/Assets/Cryville.EEW.Unity/SharedSettings.cs index 7b388dc..a4df64b 100644 --- a/Assets/Cryville.EEW.Unity/SharedSettings.cs +++ b/Assets/Cryville.EEW.Unity/SharedSettings.cs @@ -26,6 +26,7 @@ namespace Cryville.EEW.Unity { public IColorScheme ColorScheme { get; private set; } = new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.Instance); public ISubColorScheme BorderColorScheme { get; private set; } = new WrappedColorScheme(new SeverityBasedColorScheme(DefaultSeverityScheme.Instance, DefaultSeverityColorMapping.SecondaryInstance)); public ISubColorScheme TextColorScheme { get; private set; } = new DefaultTextColorScheme(Color.White, Color.Black); + public float HillshadeLayerOpacity { get; private set; } = 1; public TimeSpan NowcastWarningDelayTolerance { get; private set; } = TimeSpan.FromMinutes(60); public CultureInfo RVMCulture { get; private set; } = SharedCultures.CurrentUICulture; @@ -117,6 +118,7 @@ namespace Cryville.EEW.Unity { "SREV" => new DefaultTextColorScheme(Color.White, Color.FromArgb(28, 28, 28), 0.555f), _ => new DefaultTextColorScheme(Color.White, Color.Black), }; + HillshadeLayerOpacity = config.HillshadeLayerOpacity; _locationNamer.Namer = config.LocationNamer switch { "FERegionShort" => new FERegionShortNamer(), _ => new FERegionLongNamer(), diff --git a/Assets/Main.unity b/Assets/Main.unity index 5d54147..69a80cb 100644 --- a/Assets/Main.unity +++ b/Assets/Main.unity @@ -677,9 +677,11 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: m_layerTile: {fileID: 1412061072} + m_layerTileHillshade: {fileID: 1089136493} m_layerElement: {fileID: 1602500234} m_layerElementSub: {fileID: 303098821} m_prefabTile: {fileID: 7683017549812261837, guid: e090edd328c6750478f5849a43a9d278, type: 3} + m_prefabTileHillshade: {fileID: 7683017549812261837, guid: d112aa7211e072e489ec497e34c5b57b, type: 3} m_prefabBitmapHolder: {fileID: 1455558857588368834, guid: 1a5cf693e0cf6b94390f72f521c151ba, type: 3} m_maxMapTileZoom: 10 m_isEditor: 0 @@ -1068,6 +1070,37 @@ MonoBehaviour: m_FlexibleWidth: 1 m_FlexibleHeight: -1 m_LayoutPriority: 1 +--- !u!1 &1089136492 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 1089136493} + m_Layer: 0 + m_Name: Map Tiles Hillshade + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &1089136493 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 1089136492} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: -0.5} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} --- !u!1 &1345962671 GameObject: m_ObjectHideFlags: 0 @@ -3860,6 +3893,7 @@ SceneRoots: m_Roots: - {fileID: 376792589} - {fileID: 1412061072} + - {fileID: 1089136493} - {fileID: 1602500233} - {fileID: 303098822} - {fileID: 1345962672} diff --git a/Assets/Materials/Multiply.mat b/Assets/Materials/Multiply.mat new file mode 100644 index 0000000..409d2a4 --- /dev/null +++ b/Assets/Materials/Multiply.mat @@ -0,0 +1,91 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!21 &2100000 +Material: + serializedVersion: 8 + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_Name: Multiply + m_Shader: {fileID: 4800000, guid: 0637d3d4bac33b34ea1fb084d1aa83c5, type: 3} + m_Parent: {fileID: 0} + m_ModifiedSerializedProperties: 0 + m_ValidKeywords: [] + m_InvalidKeywords: [] + m_LightmapFlags: 4 + m_EnableInstancingVariants: 0 + m_DoubleSidedGI: 0 + m_CustomRenderQueue: -1 + stringTagMap: {} + disabledShaderPasses: [] + m_LockedProperties: + m_SavedProperties: + serializedVersion: 3 + m_TexEnvs: + - _AlphaTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _BumpMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailAlbedoMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailMask: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _DetailNormalMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _EmissionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MainTex: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _MetallicGlossMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _OcclusionMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + - _ParallaxMap: + m_Texture: {fileID: 0} + m_Scale: {x: 1, y: 1} + m_Offset: {x: 0, y: 0} + m_Ints: [] + m_Floats: + - PixelSnap: 0 + - _BumpScale: 1 + - _Cutoff: 0.5 + - _DetailNormalMapScale: 1 + - _DstBlend: 0 + - _EnableExternalAlpha: 0 + - _GlossMapScale: 1 + - _Glossiness: 0.5 + - _GlossyReflections: 1 + - _Metallic: 0 + - _Mode: 0 + - _OcclusionStrength: 1 + - _Parallax: 0.02 + - _SmoothnessTextureChannel: 0 + - _SpecularHighlights: 1 + - _SrcBlend: 1 + - _UVSec: 0 + - _ZWrite: 1 + m_Colors: + - _Color: {r: 1, g: 1, b: 1, a: 0.5} + - _EmissionColor: {r: 0, g: 0, b: 0, a: 1} + - _Flip: {r: 1, g: 1, b: 1, a: 1} + - _RendererColor: {r: 1, g: 1, b: 1, a: 1} + m_BuildTextureStacks: [] diff --git a/Assets/Materials/Multiply.mat.meta b/Assets/Materials/Multiply.mat.meta new file mode 100644 index 0000000..104ce72 --- /dev/null +++ b/Assets/Materials/Multiply.mat.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: e2b4779e0934e3b45978a57b79d75597 +NativeFormatImporter: + externalObjects: {} + mainObjectFileID: 2100000 + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Prefabs/TileMultiply.prefab b/Assets/Prefabs/TileMultiply.prefab new file mode 100644 index 0000000..49c9807 --- /dev/null +++ b/Assets/Prefabs/TileMultiply.prefab @@ -0,0 +1,100 @@ +%YAML 1.1 +%TAG !u! tag:unity3d.com,2011: +--- !u!1 &7683017549812261837 +GameObject: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + serializedVersion: 6 + m_Component: + - component: {fileID: 7683017549812261838} + - component: {fileID: 7683017549812261832} + - component: {fileID: 3920659423852445223} + m_Layer: 0 + m_Name: TileMultiply + m_TagString: Untagged + m_Icon: {fileID: 0} + m_NavMeshLayer: 0 + m_StaticEditorFlags: 0 + m_IsActive: 1 +--- !u!4 &7683017549812261838 +Transform: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7683017549812261837} + serializedVersion: 2 + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_LocalPosition: {x: 0, y: 0, z: 0} + m_LocalScale: {x: 1, y: 1, z: 1} + m_ConstrainProportionsScale: 0 + m_Children: [] + m_Father: {fileID: 0} + m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} +--- !u!212 &7683017549812261832 +SpriteRenderer: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7683017549812261837} + m_Enabled: 1 + m_CastShadows: 0 + m_ReceiveShadows: 0 + m_DynamicOccludee: 1 + m_StaticShadowCaster: 0 + m_MotionVectors: 1 + m_LightProbeUsage: 1 + m_ReflectionProbeUsage: 1 + m_RayTracingMode: 0 + m_RayTraceProcedural: 0 + m_RenderingLayerMask: 1 + m_RendererPriority: 0 + m_Materials: + - {fileID: 2100000, guid: e2b4779e0934e3b45978a57b79d75597, type: 2} + m_StaticBatchInfo: + firstSubMesh: 0 + subMeshCount: 0 + m_StaticBatchRoot: {fileID: 0} + m_ProbeAnchor: {fileID: 0} + m_LightProbeVolumeOverride: {fileID: 0} + m_ScaleInLightmap: 1 + m_ReceiveGI: 1 + m_PreserveUVs: 0 + m_IgnoreNormalsForChartDetection: 0 + m_ImportantGI: 0 + m_StitchLightmapSeams: 1 + m_SelectedEditorRenderState: 0 + m_MinimumChartSize: 4 + m_AutoUVMaxDistance: 0.5 + m_AutoUVMaxAngle: 89 + m_LightmapParameters: {fileID: 0} + m_SortingLayerID: 0 + m_SortingLayer: 0 + m_SortingOrder: 0 + m_Sprite: {fileID: 0} + m_Color: {r: 1, g: 1, b: 1, a: 1} + m_FlipX: 0 + m_FlipY: 0 + m_DrawMode: 0 + m_Size: {x: 1.28, y: 1.28} + m_AdaptiveModeThreshold: 0.5 + m_SpriteTileMode: 0 + m_WasSpriteAssigned: 0 + m_MaskInteraction: 0 + m_SpriteSortPoint: 0 +--- !u!114 &3920659423852445223 +MonoBehaviour: + m_ObjectHideFlags: 0 + m_CorrespondingSourceObject: {fileID: 0} + m_PrefabInstance: {fileID: 0} + m_PrefabAsset: {fileID: 0} + m_GameObject: {fileID: 7683017549812261837} + m_Enabled: 1 + m_EditorHideFlags: 0 + m_Script: {fileID: 11500000, guid: 772f71bcdaaa2504d9e9a469c3100593, type: 3} + m_Name: + m_EditorClassIdentifier: + _idView: {fileID: 0} diff --git a/Assets/Prefabs/TileMultiply.prefab.meta b/Assets/Prefabs/TileMultiply.prefab.meta new file mode 100644 index 0000000..460967c --- /dev/null +++ b/Assets/Prefabs/TileMultiply.prefab.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: d112aa7211e072e489ec497e34c5b57b +PrefabImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Shaders/Multiply.shader b/Assets/Shaders/Multiply.shader new file mode 100644 index 0000000..fba3a58 --- /dev/null +++ b/Assets/Shaders/Multiply.shader @@ -0,0 +1,54 @@ +Shader "Map/Multiply" { + Properties { + _Color ("Color", Color) = (1, 1, 1, 1) + _MainTex ("Texture", 2D) = "white" { } + } + SubShader { + Tags { + "RenderType" = "Transparent" + "Queue" = "Transparent" + } + LOD 100 + + Blend Zero SrcColor + + Pass { + CGPROGRAM + #pragma vertex vert + #pragma fragment frag + + #include "UnityCG.cginc" + + struct appdata { + float4 vertex : POSITION; + float2 uv : TEXCOORD0; + fixed4 color : COLOR0; + }; + + struct v2f { + float2 uv : TEXCOORD0; + float4 vertex : SV_POSITION; + fixed4 color : COLOR0; + }; + + sampler2D _MainTex; + float4 _MainTex_ST; + fixed4 _Color; + + v2f vert (appdata v) { + v2f o; + o.vertex = UnityObjectToClipPos(v.vertex); + o.uv = TRANSFORM_TEX(v.uv, _MainTex); + o.color = v.color; + return o; + } + + fixed4 frag (v2f i) : SV_Target { + float a = i.color.a * _Color.a; + fixed4 col = 1 - a * (1 - tex2D(_MainTex, i.uv) * i.color * _Color); + return col; + } + ENDCG + } + } +} diff --git a/Assets/Shaders/Multiply.shader.meta b/Assets/Shaders/Multiply.shader.meta new file mode 100644 index 0000000..b843a68 --- /dev/null +++ b/Assets/Shaders/Multiply.shader.meta @@ -0,0 +1,9 @@ +fileFormatVersion: 2 +guid: 0637d3d4bac33b34ea1fb084d1aa83c5 +ShaderImporter: + externalObjects: {} + defaultTextures: [] + nonModifiableTextures: [] + userData: + assetBundleName: + assetBundleVariant: