5
$\begingroup$

I have an object:

enter image description here

That object has an object inside of it:

enter image description here

I'd like to get a map on the cube, based on where the internal object is in relation to the camera, such that I can make it transparent where needed to make the inside object visible:

enter image description here

This is going to be animated, so can't be a static map.

My use case is to reduce to IOR in the following brain object such that it's easier to see the red internal object:

enter image description here

$\endgroup$
  • $\begingroup$ You could split it up into different render layers, then blur an alpha mask of the "red stuff" that can be used to increase the transparency of that region of the brain smoothly. $\endgroup$ – JakeD Sep 3 '16 at 1:07
  • $\begingroup$ You could also add an object to a mask layer in the brain's render layer that is tracked to the camera (it would have to be in front of the brain). This would not be as good though, as it couldn't be faded. $\endgroup$ – JakeD Sep 3 '16 at 1:24
  • $\begingroup$ I fear it's going to be tricky to get the effect looking good in the compositor. Was hoping that I could get a map on the brain object that is a projection of the red object onto the camera.. would then still need to be blurred of course. Guess I could bake it. $\endgroup$ – ajwood Sep 3 '16 at 2:12
  • $\begingroup$ You can also look into dynamic paint if you are fine baking it, but you still want it to be animated. $\endgroup$ – JakeD Sep 3 '16 at 2:24
  • $\begingroup$ The mathematical approach would be to test if the camera's projection of the sampled point on the outer mesh overlaps with an approximated (i.e. spherical) projection of the inner object. (That's not really a good explanation, I'll see if I can set up a working version tomorrow if you don't get a better solution by then.) $\endgroup$ – PGmath Sep 3 '16 at 2:55
6
$\begingroup$

Here is the result of my mathematical approach:

enter image description here

And the nodes for the outer object:

enter image description here

The value nodes on the far left are driven by the positions of the target (inner) object (top three) and camera (bottom three).

And here are the contents of the Norm node group, which returns the norm (i.e. magnitude) of the input vector:

enter image description here

The basic idea of my approach is to take the ray vector (from the camera to the sampled point on the mesh) and extend it to the inner object, then test how far this extended ray vector is away from the center of the inner object and use that information to adjust the outer object accordingly. (In my example I reduced the IOR and made the glass lighter to make the inner object more visible.)

See below for a more thorough look at the math.

The only downside here is that the "hole" in the outer mesh will not be the exact shape of the inner object since I am basically approximating the inner object to be a sphere.

And here's the .blend:


The Math

Note, this answer is already fairly long and defining all the mathematical terms and concepts I am using here would make it much longer. So to understand this section you should have decent precalculus grasp of vector math. If you don't understand this part fully you can still just copy my nodes, or feel free to open a chat room with me and I would be more than happy to explain whatever you want.

  • Call the camera's position $\vec{C} = (Cx,Cy,Cz)$.
  • Call the center of the target (inner) object $\vec{T} = (Tx,Ty,Tz)$.
  • Call the sampled point on the outer object $\vec{P} = (Px,Py,Pz)$.
  • Call the radius of the inner object $R$.
  • The vector of the incoming ray is $\vec{CP}$, for simplicity I will call it $\vec{r}$.

enter image description here

The idea now is to determine if $\vec{r}$ is aiming towards the inner object. To do this, normalize $\vec{r}$ and multiply it by the norm of $\vec{CT}$. This will result in a new vector $\vec{r}^{\,\prime}$ in the same direction as $\vec{r}$ and length as $\vec{CT}$.

enter image description here

The last step is to determine if $\vec{r}^{\,\prime}$ intersects the inner object. This is pretty simple, just take the difference $\vec{r}^{\,\prime}-\vec{CT}$ to make a new vector $\vec{D}$.

enter image description here

This gives the final formula for the distance to compare to $R$:

$$ \left\vert\left\vert \vec{D} \right\vert\right\vert = \left\vert\left\vert \frac{\vec{r}}{\left\vert\left\vert \vec{r} \right\vert\right\vert} - \vec{CT} \right\vert\right\vert $$

The node layout is just this formula, then sent through an RGB Curves node to tweak the falloff (the Add node right after the RGB Curves adds 0, it's purpose is to clamp the value to $[0,1]$), then used to mix the two glass shaders. The Less Than math node at the very bottom compares the norms of $\vec{CT}$ and $\vec{r}$ (not $\vec{r}^{\,\prime}$) to apply the effect only in front of the target object.

Ping me in chat if you have any questions about the nodes or the math, I'm happy to explain further there if needed!

$\endgroup$
  • $\begingroup$ Cool! Can you think of a way to disable the effect out the back of the outer object? It's a little tricky, because there can be backfacing faces before the inner object, due to the foldy nature of my brain object. $\endgroup$ – ajwood Sep 4 '16 at 20:00
  • $\begingroup$ @ajwood I finally finished an explanation of the math if you are interested, and I included a .blend in case you haven't already taken the time to copy my node spaghetti from the screenshot (I should have done that in the first place). $\endgroup$ – PGmath Sep 5 '16 at 21:34
  • $\begingroup$ Love the explanation! With I could upvote again :) $\endgroup$ – ajwood Sep 6 '16 at 12:02
3
$\begingroup$

A (not perfect) solution is to use an UV project modifier.

enter image description here

Above :

  • 1/ The scene setup. The camera location is guided by the sphere on left (not mandatory, see below). The camera points to the little sphere inside the cube
  • 2/ What is seen through the camera
  • 3/ The 'UV project' modifier setup. It is set on the cube
  • 4/ Drivers to handle the scales in 3 (one driver per scale X and Y)
  • 5/ The material setup
  • 6/ A texture used to make "the hole" inside the cube, so that the inner sphere is visible

How it works :

  • The UV project modifier is based on an additional UV map created for it (called 'seeThrough')
  • The camera point to the cube, looking at the inner sphere. And the camera is used to project the UVs. So these UVs conforms to this projection
  • The drivers are here to handle the scale, so that the hole size stays constant, even if the camera moves. They calculate the distance between the camera and cube (or between camera and inner sphere if you feel it better)

  • The UV project modifier uses a texture (in 6) and maps the projected UVs to it

  • So in the Cycle node setup (5), we can rely on the texture color (black and white) to mix between the cube shader and transparency
  • Depending on the texture, the hole will be more or less clear/blury, and the hole size can be tuned using the drivers

The camera constraints are the following :

  • Copy location of the little sphere used to handle easily the camera (not mandatory)
  • Damped track to the inner sphere

enter image description here

Here is the result :

enter image description here

What is not perfect (at least that) is the hole is also visible on the back side of the cube. But as we see through the camera, this does not appears.

$\endgroup$
  • $\begingroup$ What's the purpose of transparency.png in the UV Projection? $\endgroup$ – ajwood Sep 3 '16 at 17:23
  • $\begingroup$ @ajwood, you mean the other image files in the blend ? they were for test purpose. If you mean the texture, itself (whatever it is), this is to oriented where the hole will be. The UV project keeps the center of the texture projected from where is the camera as the camera is used to project it $\endgroup$ – lemon Sep 3 '16 at 17:56
  • $\begingroup$ so the UV Project modifier doesn't need an image and Override Image checked? $\endgroup$ – ajwood Sep 3 '16 at 17:57
  • $\begingroup$ @ajwood, I think this is needed : we want this image (with its color) to be projected so that it can be used in the mix shader node. Without this 'visible' image, that does not work (or there is something I am missing) $\endgroup$ – lemon Sep 3 '16 at 17:59
  • $\begingroup$ Note : this is not sure to be what you really need (even if I think this is close to). Maybe someone else will give a more accurate solution (I dont know)... $\endgroup$ – lemon Sep 3 '16 at 18:00

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.