- Home /
How to access Tilemap Tile's x-y-z positions from shader, to mask or move tiles
Hey there, I am trying to come up with ways to make a shader that masks out sprites that are overlapping the player when using 2D Tilemaps.
I found that when working with tilemaps, they are rendered flat. However, when rendering, the tilemaps do seem to have a z-value, because you can add new sprites in 3d space and move them around and they will sort correctly based on their y and z values as can be seen in this image:
Unity does seem to utilize a tile's x-y-z position from the grid, but rendering the tilemaps flat for performance reasons, while still allowing independent sprites and other tilemaps to sort properly in relation to the tilemap's depth.
Now the big question is: in isometric games, objects often obscure the player character and what is being done in many games is that the obejcts/tiles that are obscuring the player are then masked out in an area around the player. While it is possible to add custom shaders to the tiles, I have not figured out how to access a Tile's depth value that is being utilized by the Tilemap Renderer, in order to only mask out the ones that are in front and not also the ones that are in the back, as seen here:
My code for the shader that masks out the tilemap is currently this: (Please Keep in mind that I am an artist and not a professional coder and just try to make things work)
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
Shader "Sprites/Custom/SpriteMask1"
{
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_Color ("Tint", Color) = (1,1,1,1)
[MaterialToggle] PixelSnap ("Pixel snap", Float) = 0
[HideInInspector] _RendererColor ("RendererColor", Color) = (1,1,1,1)
[HideInInspector] _Flip ("Flip", Vector) = (1,1,1,1)
[PerRendererData] _AlphaTex ("External Alpha", 2D) = "white" {}
[PerRendererData] _EnableExternalAlpha ("Enable External Alpha", Float) = 0
_Mask ("Alpha Mask", 2D) = "white" {}
_DepthCull ("DepthCull", Float) = 0
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Cull Off
Lighting Off
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex my_SpriteVert
#pragma fragment my_SpriteFrag
#pragma target 2.0
#pragma multi_compile_instancing
#pragma multi_compile_local _ PIXELSNAP_ON
#pragma multi_compile _ ETC1_EXTERNAL_ALPHA
#include "UnitySprites.cginc"
sampler2D _Mask;
fixed _DepthCull;
struct my_appdata_t
{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
float2 depth : TEXCOORD2;
};
struct my_v2f
{
float4 vertex : SV_POSITION;
fixed4 color : COLOR;
float2 texcoord : TEXCOORD0;
float2 worldCoord : TEXCOORD1;
float2 depth : TEXCOORD2;
UNITY_VERTEX_OUTPUT_STEREO
};
my_v2f my_SpriteVert(my_appdata_t IN)
{
my_v2f OUT;
UNITY_SETUP_INSTANCE_ID (IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
OUT.vertex = UnityFlipSprite(IN.vertex, _Flip);
OUT.vertex = UnityObjectToClipPos(OUT.vertex);
OUT.texcoord = IN.texcoord;
OUT.worldCoord = UnityObjectToViewPos (IN.vertex);
UNITY_TRANSFER_DEPTH(OUT.depth);
float4 scaledVertex = float4(OUT.vertex.xy,0,0);
OUT.worldCoord = ComputeScreenPos (OUT.vertex);
OUT.color = IN.color * _Color * _RendererColor;
#ifdef PIXELSNAP_ON
OUT.vertex = UnityPixelSnap (OUT.vertex);
#endif
return OUT;
}
fixed4 my_SpriteFrag(my_v2f IN) : SV_Target
{
fixed4 c = SampleSpriteTexture (IN.texcoord);
fixed4 alpha = tex2D (_Mask, IN.worldCoord);
fixed depth = IN.depth;
c.a *= 1- alpha;
return c;
}
ENDCG
}
}
}
If anyone could help me out with this, it would be much appreciated and I would love to share the functional solution for free with other members of the community.
Wishing a great day to everyone reading <3
Your answer
Follow this Question
Related Questions
Shaders, how can I set a texture as the alpha of another? 0 Answers
Unity Advanced Shader Help 0 Answers
Find position of pixel that's currently being calculated in shadergraph custom function 0 Answers
Rule Tile which changes shader parameters 0 Answers
Only render stencil mask when behind maskable object 0 Answers