Skip to content

Instantly share code, notes, and snippets.

@drawcode
Last active July 1, 2019 10:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save drawcode/7f937818642e95863fa34c15157afe62 to your computer and use it in GitHub Desktop.
Save drawcode/7f937818642e95863fa34c15157afe62 to your computer and use it in GitHub Desktop.
maskunity.cs
/*
https://answers.unity.com/questions/316064/can-i-obscure-an-object-using-an-invisible-object.html
You can use a special shader that only writes to the depth buffer. That's not so difficult, but you may end with a black area in the screen! The problem is: since this shader doesn't actually draw anything, the area behind the object will remain with the original image, which is defined by the camera's Clear Flags. In order to avoid this, you must handle the rendering order so that the background items are rendered first, then the invisible object, and finally the objects that may be obscured. You can do that by setting the property material.renderQueue of each object, assigning greater values to the ones that should be rendered last (read more about renderQueue values in the shader docs).
The shader itself could be as simple as this one:
*/
Shader "Custom/InvisibleMask" {
SubShader {
// draw after all opaque objects (queue = 2001):
Tags { "Queue"="Geometry+1" }
Pass {
Blend Zero One // keep the image behind it
}
}
}
/*
Save this shader as "InvisibleMask.shader" (or other suitable name) somewhere in the Assets folder, then create a new material (InvisibleMat, for instance), select this shader and assign the material to the invisible mask object.
Now you must set the rendering order for the "obscurable" objects: they must have a renderQueue value >= 2002, since the shader above has a render queue value = Geometry+1 (2001). You can do this easily by attaching the script below to any "obscurable" object:
*/
function Start(){
// get all renderers in this object and its children:
var renders = GetComponentsInChildren(Renderer);
for (var rendr: Renderer in renders){
rendr.material.renderQueue = 2002; // set their renderQueue
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment