Jump to content

Invisibilty Cloak


Recommended Posts

I had an idea for a bit of a crazy shader.

Say you have a bunch of stuff that you don't want to show up in a render but its a pain to turn that stuff off, however it would be easy to sling a bounding box or other object around it as an invisibilty cloak.

This shader does just that. It hides anything that is inside the object with the shader applied to it.

To many this may seem like a pointless exercise, but it is if nothing else interesting what tricks you can pull with mantra... :)

invisibiltyShader.zip

Link to comment
Share on other sites

To many this may seem like a pointless exercise

Maybe.

Would it be possible to animate the process of getting invisible?

For performance reasons it would be more effective to do this on the object getting invisible, wouldn't it? The advantage of this design seems to be: it is independend on the other objects involved.

10 points for seeming pointless from me.

I think this is a good start for further experiments!

Georg

Link to comment
Share on other sites

Well say you render a pass with the thing invisible and and pass with everything else invisible then crossfade between them, then you can control how invisible they are...

The motivation for this was having tons of objects swing round in front of the camera, they are then blocking the view of the thing I want to see. Being able to hide them but see everything else behind without having to figure out which objects were doing the blocking seemed like a handy tool for a quick fix.

Link to comment
Share on other sites

The motivation for this was having tons of objects swing round in front of the camera, they are then blocking the view of the thing I want to see. Being able to hide them but see everything else behind without having to figure out which objects were doing the blocking seemed like a handy tool for a quick fix.

Nice trick Simon! :)

And yeah, I can see how this could be useful (the case you describe is a good example).

I didn't look very closely at the VOPs (trying to decipher shaders from VOPs gives me headaches ;)), but I did notice you have both a rayhittest() and a raytrace() in there, which struck me as a little odd.

I would have thought that a raytrace() with a scope of getobjectname() would be all that's needed (with Cf =Of=Af=0 on secondaries and Of=Af=1 on primaries). Maybe you can save yourself one trace? -- but I'm more likely missing something.

Link to comment
Share on other sites

Well I wrote it in about 5 minutes late at night, it was just a sketch of an idea so you may be right. :)

The rayhit test is a quick check to jump the ray tracing to the other side of the box, probably I can use getobjectname in the scope there so that the user doesn't need to supply it, the second full trace test is to get the scene the other side of the box, hence everything inside disappears because it is skipped by the first rayhit jump.

If I just put getobjectname in the scope of the raytrace call I think all it will do is find the box and not the rest of the scene behind it?

Two things have occured to me since doing this

1. I could potentially put another trace call in there to return the stuff inside the box and you could then control the transparency of it inside the shader.

2. When you do a raytrace call is the "rendered" colour that is returned going to be different from the surrounding area because its raytraced and the rest of the scene is rendered with micropolygons. That might cause issues. More testing needed there.

Link to comment
Share on other sites

Not having used this at all, but do you notice a marked difference in the look of the stuff beyond the cloak? i.e, I guess it'd be largely dependent on the surface shader attached to the objects but due to the fact that its raytraced as opposed to micropolygon rendering I'd expect a certain difference in the look. I suppose if the object you're tracing against has high frequency shader detail (some noise, for instance) then you might see a bigger difference.

Just thinking out loud here:

Not knowing how Mantra ray derivatives work, I wonder if it'd be useful to be able to get a little closer if you could supply derivatives to the trace() call especially because you know the rays are mere continuations of the I vector -so perhaps the original derivatives from the sample on the cloak object are perfectly applicable/usable? I suppose Mark and Andrew would know better if this would be helpful; perhaps it does this in the trace() call already.

Link to comment
Share on other sites

Well I wrote it in about 5 minutes late at night, it was just a sketch of an idea so you may be right. :)

I tried a little experiment to see if what I was talking about worked and... it does, but only in raytracing mode (mantra -r). For some weird reason, I get some internal error (no output to shell with -V 1) in MP mode...<shrug>

Here's the basic idea:

surface Cloaker( float dmax = -1;  float bias = 0.005; ) {
   string scope = (dot(N,I)&lt;=0) ? getobjectname() : "";
   trace(Cf,Of,Af,P,normalize(I),bias,1,"maxdist",dmax,"scope",scope);
   Of = 1-isshadowray(); // Stop cloaker from casting traced shadows
}

Instead of testing for primary/secondary, we test for entering/exiting coz I think it would otherwise break if a transmissive object was in front of the cloaker (didn't test this).

invisibiltyShader_v2.hipnc

Two things have occurred to me since doing this

1. I could potentially put another trace call in there to return the stuff inside the box and you could then control the transparency of it inside the shader.

Hmmmm.... my gut tells me you might not be able to do this (reliably, anyway) -- I'd think that as soon as a trace call runs the internal object's surface shader you might lose all control over the result (remember the internal object's shader could potentially run reflection, transmission, and/or shadow rays).... but maybe not...

2. When you do a raytrace call is the "rendered" colour that is returned going to be different from the surrounding area because its raytraced and the rest of the scene is rendered with micropolygons. That might cause issues. More testing needed there.

I would speculate that this might happen if the cloaker is faceted and you happen to trace across an edge (or some really discontinuous chunk'o'surface)... it's probably a good idea to make the cloaker a sphere/ellipsoid to minimize the potential for derivative-related artifacts (if there are any). Otherwise, in theory, there shouldn't be any big difference between a trace from cam and a trace from P (if they're both along I) -- at least I don't think so.

@Jason: I think Mantra takes care of the derivative issues you mention -- likely with better success in raytracing mode (mantra -r) than in MP mode (judging by my experiments with glass, though those problems had more to do with area filtering for secondary rays in MP mode than with derivatives IIRC).

Link to comment
Share on other sites

Haven't had a chance to give this a real test yet, but it got me thinking could I do CSG with this technique.

Initial results are mixed. Maybe Mario has some ideas about this? :)

The idea here is that having done the trace that makes the geometry inside the cloaker invisible you can then also test if the geometry beyond is back facing, if it is then shade the surface using the front face normal of the cloaker. This way you can do a simple subtraction cookie cutter style but all in the shader.

The first problem I'm having is that it works ok for a cloaker sphere but if I use a box then I get lots of artifacts on the oblique faces.

The second problem is that I can't use a light model to shade the "cut" face, using a constant or a simple dot product lighting model works but the lighting model vop or diffuse call just returns black.

csgShader_v1.zip

Link to comment
Share on other sites

Ok one issue is easily solved, of course a default box has consolidated corners so N isn't the face normal. Changing to Ng fixes the artifacts but I haven't found a solution to proper shading yet...

Hey Simon,

Hehe... you're not gonna like this...

The reason it was shading black with the models that actually sample lights was that... the cloaker object had a an empty light mask ("")... DOH! (I'll confess that I looked at just about everything else before checking that, so the "doh!" goes for me too).

csgShader_v3.hipnc

The only comment I have is that instead of using Ng, I think it would be better to simply make the user set faceted normals if that's what they want... after all, now the object is being shaded like any other, and so it's reasonable to expect the user to be responsible for how it looks (it *could* have a very complicated shader attached, instead of just the lighting model you're testing with, so...).

Anyway.. Cool trick #2! :thumbsup:

Link to comment
Share on other sites

Doh! :P I have no idea how that happened. :rolleyes:

I bet it was when I first started playing around and thought maybe if this thing isn't lit by any lights it won't cast shadows, which is obviously a good thing. My only defense of this flawed logic is that it was late :lol:

I've also had a play with making a "union" shader to remove the insides of intersecting objects, but at present that doesn't play nice with this cloaker "subtract" shader. I have a feeling that might be resolvable in the future.... fingers crossed ;)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...