- Home /
The question is answered, right answer was accepted
Can I obscure an object using an invisible object?
I'd like to have an object closer to the camera "cut-out" the object behind it. The closer object needs to be invisible though. Is this possible?
Answer by aldonaletto · Sep 11, 2012 at 02:44 AM
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 } }
Thanks for your prompt reply. I understand the first bit regarding the "Invisible$$anonymous$$ask" shader; however, as I am new to writing, I don't know what to do with the function part. Where does this fall in the script string? $$anonymous$$any thanks.
is there any way to do this same idea with a gradient ?
If you mean something like having soft borders in the mask, the answer is no: the mask just blocks rendering any pixel behind it due to the depth buffer (A$$anonymous$$A Z-buffer). Despite the mask itself doesn't render anything to the screen, the depth of each of its pixels is recorded in the Z-buffer. Once the mask has been "rendered", any further rendering behind it is blocked.
hey, I have changed the above code a little bit to avoid the black area in the screen.
I changed Tags { "Queue"="Geometry+1" } to Tags { "Queue"="Transparent+1" } and also rendr.material.renderQueue = 2002; to rendr.material.renderQueue = 3002;
this way my material is transparent and no black area is seen.
I don't care if this answer was made in 2012. You were awesome then and you are awesome now! THAN$$anonymous$$ YOU!
Follow this Question
Related Questions
using openGL to render simple line 1 Answer
Another Java to C# Conversion Question!! 1 Answer
how to render bothsides? 2 Answers
How to make a mini map? 1 Answer
hi all, Low-level Native Plugin Interface(for unity 3.5) 0 Answers