I have made a shader for my UI buttons, the sprites should be black and white, so they can be used as a mask when blending. They should allow for the image behind them to pass through the whiter pixels and be blocked by the darker ones.

I want to use this effect for my menu, have a black background and a colored one (like a gradient or a pattern), let the colored one pass only through the buttons and the black one everywhere else.

My shader does just that, but with one problem. I can't hide the colored background from the camera. If I change it's layer it is useless (I guess because it is the child of a canvas), and if I use a regular sprite (non UI) it is just ignored by the camera and the buttons don't pick up the color.

How can I achieve this effect, having the sprite be invisible to the camera but visible to the shaders of the buttons.


Although it may not be what you are looking for, I generated this to show how to use the stencil buffer to achieve what you want:

UI stenciling

The "black-shader" could just return (0,0,0,1); but could also sample from a texture (animated gradient, etc.)

  • \$\begingroup\$ I cannot check any of that rightaway, I will share my results as soon as I al able to try that. \$\endgroup\$ – user3195897 Apr 24 '15 at 20:35
  • \$\begingroup\$ @user3195897, I have yet to open Unity and would love to know how you actually implement this in it. (i.e. replace the GL references) \$\endgroup\$ – Jon Apr 24 '15 at 20:49
  • \$\begingroup\$ OK I'm totally new to shaders, I just copied the sprites-default shader and played with the blend value, so according to what I just read this method would be used instead of blending, am I right \$\endgroup\$ – user3195897 Apr 24 '15 at 22:40
  • \$\begingroup\$ I recommended using the stencil-buffer since you are doing 2D, but you could also do this with a stencil-texture, in 2D or 3D. You could also have buttons (only) output a second color to a second rendertarget and sample that texture later to choose between "black" and "button"; if the sampled color is 0, it's not button. There are many ways to do it, but I think the stencil will be the easiest. \$\endgroup\$ – Jon Apr 25 '15 at 6:40
  • \$\begingroup\$ You can still use alpha-blending for the color buffer, even while filling the stencil. The actual stenciling is done during the final pass where you just render a full-screen quad, twice. One of the final-pass shaders will output (0,0,0,1) and the other will output the color sampled from the same location as the current pixel. The stencil setup just selects between "fill the 0's" and "fill the not-0's". \$\endgroup\$ – Jon Apr 25 '15 at 6:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.