0
$\begingroup$

I have invisible circle in front of colored square. I need to make it that when circle intersects with a view of a square (not with a square itself) it becomes visible (only that part of circle which already intersected view, the other is still invisible). How can I do so?

Pic 1 is setup I have.

Pic 2 is what I need to achieve. enter image description hereenter image description here

$\endgroup$
1
  • $\begingroup$ Is this your complete setup or is it very simplified. $\endgroup$
    – Leander
    Commented Apr 10, 2019 at 11:57

1 Answer 1

1
$\begingroup$

You can use OSL to fire a ray forwards from the shading point, and return information about the next point hit. You can then use that information to control the response of a material at the shading point. To use OSL, you must set the render device to the CPU, and check 'OSL'.

This little OSL script fires a ray forwards continuing in the direction of the incident ray, and returns the Pass Index of the next object hit.

#include "stdosl.h"

shader NextObj(   
  output float nextObjIdx  = 0.0    
)
{  
    if (trace(P,-I,"mindist",0.0001)){
        getmessage("trace", "object:index", nextObjIdx);
    }  
}

It can be used, for example, in combination with these nodes to control the shading dependent on the next object:

enter image description here

With this sort of result.. the plane in the background has been given a Pass Index of 5:

enter image description here

.. and you can change the yellow Diffuse shader for a Transparent shader with color (1,1,1) to make the circle disappear when it's not between the camera and the plane. However, you'll find that then, it won't cast a shadow. That's because for a shadow ray, the incident ray I doesn't point towards the camera and so the forward ray points towards the environment, or a light-source, which doesn't have a Pass Index > 4, so as far as shadows are concerned, the object is always transparent.

That may be what you want .. if not, you can fix that as follows:

#include "stdosl.h"

shader NextObj(   
  output float nextObjIdx  = 0.0    
)

{  

    point cam_pos = transform("camera","world",point(0,0,0));
    vector viewdir  = P - cam_pos;

    if (trace(P,viewdir,"mindist",0.0001)){
        getmessage("trace", "object:index", nextObjIdx);
    }  
}

..which ensures the probing forward ray is cast onward in the camera viewing direction for all incoming rays, including shadow rays. That means the part of the circle that is between the eye and the plane casts a shadow. The rest doesn't, if it's transparent. There are quite a few more variations on the behavior you can achieve by tweaking the script and using a Light-Path node.. if these examples aren't right, perhaps you could specify more closely. You could, for example, use the material index rather than the object index; then all objects with that material would make the foreground circle appear.

$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .