Masking off certian portions

I’m trying to make a round minimap which, so far as I can tell, will require getting a subset of my large map to display on the screen and then masking off the edges of that square map to make it round. Is there a way to apply an overlay to a texture that will modify that texture’s alpha channel on a per pixel basis?

Also, if there’s a simpler way I’m very open to hearing about that as well.

I’ve been looking around for two days now and I can’t find a single reference to this sort of functionality anywhere, and I can’t imagine why.

There is no way to do that unless you write your own system.
The images are used as they are without any option to modify them before beeing shown on screen.

Well, I did find this thread but I’m not sure if it is possible to apply a shader to a GUIObject. Anyone know?

Easiest is to try so.

For GUI.xxx you definitely can’t as they are no game objects or even objects at all

After much reading and a good deal of experimentation I have managed to make a shader that can be applied to a texture on a plane. That plane can then be put in front of an orthographic camera… ect. ect.

So my question is this: Can anyone tell me how to improve my shader so that I can use a gradient of transparency? Currently, because of AlphaTest, I can only define a visible section and a not visible section, with no partial visibility in between.

Also, am I correct in assuming that this shader would be compatible with all graphic cards?

Shader "Library/Cull Mask"
{
	Properties
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_Mask ("Culling Mask", 2D) = "white" {}
		_Cutoff ("Alpha cutoff", Range (0,1)) = 0.9


	}
	SubShader
	{

      Blend One Zero
      Pass
      {
		AlphaTest LEqual [_Cutoff]
		SetTexture [_Mask] {combine texture}
		SetTexture [_MainTex] {combine texture, previous}
      }
	}
}

Try this:

Shader "MaskedTexture"
{
	Properties
	{
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_Mask ("Culling Mask", 2D) = "white" {}
		_Cutoff ("Alpha cutoff", Range (0,1)) = 0.1
	}
	SubShader
	{
		Tags {"Queue"="Transparent"}
		ZWrite Off
		Blend SrcAlpha OneMinusSrcAlpha
		AlphaTest GEqual [_Cutoff]
		Pass
		{
			SetTexture [_Mask] {combine texture}
			SetTexture [_MainTex] {combine texture, previous}
		}
	}
}

Note that I flipped your cut-off, as you were using LEqual, which works opposite to conventional blending. This means you’ll probably have to invert your test mask to work with this shader.

Thanks tom. Most helpful. :slight_smile: I turned off lighting as well and posted this to the wiki.

I don’t think this actually creates a helpful map. Sure, you can use it to mask off edges of a texture, but the mask is locked to that texture. Generally in games, the circle crops only a portion of the map that you’re currently in and the map moves as you move. With this technique, there’s no way to move the map independent of it’s mask. Am I missing something?

It depends how the map is created. If it is generated from an overhead view using a render texture, then this would be exactly what you want.

Unfortunately, I’m not. I’m using a Grand Theft Auto/Assassin’s Creed style graphical map with icons. What I have been working with (unsuccessfully) was to combine the CullAll shader with this shader. My idea is to make a texture that’s essentially an “invisible hole.” I have the culling functionality, working to knock out everything behind, outside of my hole, with the texture cropped within the circle. This is my existing shader code:

Shader "MaskedTexture"
{
	Properties
	{
		_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
		_Mask ("Culling Mask", 2D) = "white" {}
		_Cutoff ("Alpha cutoff", Range (0,1)) = 0.1
	}
	SubShader
	{
		Tags {"Queue"="Background"}
		Lighting Off
		ZTest Always
		ZWrite Off
		AlphaTest GEqual [_Cutoff]
		Blend SrcAlpha OneMinusSrcAlpha
		Pass
		{
			SetTexture [_Mask] {combine texture}
			SetTexture [_MainTex] {combine texture, previous}
       	}
	}
}

Now, the last element I need is for the _MainTex to take advantage of an alpha channel. So the resulting shader would be one that has a mask to cull everything that shouldn’t be seen, while using a main texture with an alpha channel that would allow you to see through the hole to whatever is immediately beneath it. Does that make sense?

I know very little about shaders and it took me the better part of a day just to get to this point. If anyone can create what I’m theorizing here, I think we’d have the ultimate solution to masked minimaps.[/quote]

1 Like

Shader Noob Makes Good!

I seem to have solved my issue. After a lot of experimentation and a little bit of blind luck, I’ve created a masking shader for minimaps and any other masking needs. This is not a GUI solution, but requires a separate camera and 2 texture planes, one for the mask, one for the map. This also does not require RenderTexture (which is only available to Pro users).

Use this shader on your mask plane with a bitmap imported with format “Alpha 8” and “Build Alpha From Grayscale” selected.

Shader "TextureMask"
{
   Properties
   {
      _Mask ("Culling Mask", 2D) = "white" {}
   }
   SubShader
   {
		Tags {"Queue" = "Background"} 
		Blend SrcAlpha OneMinusSrcAlpha 
		Lighting Off 
		ZWrite On 
		ZTest Always
		Alphatest LEqual 0
		Pass
		{
			SetTexture [_Mask] {combine texture}
		}
   }
}

As I mentioned, I really don’t know a whole lot about what was done here, so if it looks like there’s any extraneous data here or something that can be improved, please let me know.

Hey guys I’ve found this thread very helpful, unfortunately I think I’m doing something wrong. I have the same issue as MultimediaPlusGreg in that I want to have a circular minimap that is part of a larger map. So the way I’ve tried to do it was by using MPG’s shader with this mask and then setting its coordinates to be the same as the camera except the Y position which is 1 in front of it:

Mask:

How it looks on the map

The problem is that while it does mask off the corners, it still displays the masked off area. I’m using the normalized view port rect on the camera to display the minimap.

Is this not correct or is there a way to not display the masked area in the view port rect?

Try setting the minimap camera’s clear flags to Depth Only in the inspector.

It worked! Thanks for the help :slight_smile:

Hello,

I am trying this and for some reason, even when I set my mini map camera clear flags to depth only, it doesn’t make a difference. I have copied the shader used here and have a similar image I created in Photoshop elements. The transparency works, the only difference is that I am using the following code in a script to render the second camera:

camera.pixelRect = Rect(fl_screen_width - fl_map_width, fl_screen_height - fl_map_height, fl_map_width, fl_map_height);

. Any tips.

thanks,
Donald

When you say it doesn’t work, does the plane block out the minimap view altogether or do you just not see the mask image at all?

Hi Andee,

Thanks for responding, what I see the white part of the image, the black part is invisible. So I see see the rectangle region and I see the white circle and the black part is all invisible.

Here are the camera settings (2 cameras):

mini map camera
depth = 2
clear flags = solid color

game camera
depth = 1
clear flags = depth only

The minimap camera is the one that should have its clear flags set to depth only. The meaning of the setting is that the camera’s background doesn’t get cleared during the overlay, only its depth buffer.

Hi I want to make an scrollable content and have to mask the content with a masker, so that the viewable area can be limited to a certain bounds. Can anyone suggest me how to do this. The basic idea is to have a panel with number of items and the viewable area size is limited to half of the screen size.

Thanks in advance