Selective Mirroring

For this raytracing project we are to write a shader that uses the gather() function to implement a reflective (mirror) surface. Rather than reflecting all objects in its "field of view", your shader will be selective. Via the use of gather() your shader will querry an attribute of the object struck by the gather ray. For example, the shader attached to the object hit by a ray may assign either the name of the shader, or the name of the surface, to an output variable. The mirror shader would then be able to "retrieve" the assigned name, or some other significant value, and thereby decide whether or not to ignore the color returned by the gather ray.


To start on this project I have started with understanding how to get information from one shader to other. This is called shader to shader messenging. This allows us to collect information from one shader and pass this on to another shader. Using "output varying float" allows for whatever float information to be parsed out. In these shaders we use a number of different functions to get the information we need. Starting with the suface shader of the object we want or don't want to reflect, we have to look at a number of things that this shader must do: (these points are reiterated on Malcom Kesson's website)

1. Use the RSL attribute() function to get the name of the object to which the shader has been applied.

2. Decide if the shader has been hit by a gather ray that originated from the the emitting shader.

3. If the shader has been hit by a gather ray, assign a value to a special variable that will be gathered by the shader that emitted the ray.

4. if hit by any other gather rays that have been emitted from other shaders or objects (i.e. camera, lights, specular...) colorize the surface in the normal way.

Once we have this information we are able to move on to the emitting shader. And again, there are a number of things that the shader must be able to do: ( once again, these points are reiterated on Malcom Kesson's website)

1. Use the RSL gather() function to emit the rays.

2. Name therays so that they can be identified by the object shader above.

3. For every gather ray that strikes a surface check to see if we have been able to gather the special variable known only to the shader above
4. If we've gathered the variable as a result of a ray hit simply ignore the hit - effectively ignoring the surface that was struck.

Essentially with all of this we are able to get a shader that will ignore the object that the first shader is applied to as long as the name is equal to the name we have set within the shader to match() against. In these images, the first set of spheres are named at the object level to "reflect". The second, the sphere to the right is set to "no_reflect" and the left set still to reflect. no_reflect is what the shader is matching to which in turn "tells" the emitting shader not to reflect the object.

object name = reflect for both right and left spheres

object name = no_reflect for right sphere reflect for left sphere




Since this is a WIP (Work In Progress), I will be attempting to get the object to cast a reflection and not be visible to the camera. Also I will be work on using "maxdist" within gather() to collect object distances which in turn can be used to change reflectivity among other things.

click here for the object shader code

click here for the emitter shader code


By using a clever idea of having a surface shader that "senses" which emitted ray (i.e. camera, specular...) we are able to disclude the idea of having a shader that gathers information from one shader to figure out if it should or should not reflect the object. With using an If test within the shader we are able to tell the object to be or not to be visible depending on the ray which strikes the object. With this in hand I was able to get to a point, using Malcolm's shader as a base, to get the idea of seen by the camera and not reflecting and vise versa. By controlling the opacity (Oi) over time I was able to get the effect of the unreflected and unseen object slow appearing. Below shows a still image and an animation of this shader.





Moving on to the distance verses reflectivity, This idea seemed to be simple but became difficult to solve. By employing a smoothstep() based on the length(I) and plugging these values in for the Oi, I was able to get a reflection that becomes fully opaque as the object moves away from a relective surface. This is also more believeable when I take the color trace(P, I) and mix it with the surface color or Cs. the trace is allowing for the information from the surrounding environment to be included in the Ci of the reflection. If this isn't used then you get a situation where the ray from the mirror surface is ignored and black is used in place of the environment color. This movie shows visually what is happening as the object moves away from the mirrored surface.


Adjusting the smoothstep() minimum and maximum values will make the ojbect "appear" quicker or slower.

With this working, it seemed logical that if you take the inverse of smoothstep that you would get the inverse of the visual, disappear as the object moves away from the mirrored surface. But this is where I ran into a problem. It seemed that when you took the inverse that the trace() was only tracing to the inside of the top part of the surface and in this case I was only returning black on the mix. Working with James Van Allen, we were able to discern that if we do an If test stating that we only want to deal with any face point foward or, n == nf. Any other face is ignored or the Oi is set to 0. By using this idea we are able to only calculate the Ci for the reflection with the front of the object and allow the trace() to trace out to the environment. This took a while to get our heads around, but it seemed to be a good solution. Below is a movie that shows this in action.


The next step in this process would be to incorporate the two shaders into one and give the artist the ability to choose which invisibility they would like the object to produce. I would like to take this to another level and see if there is a way of controlling other things within the scene (i.e. displacement, color change...). Eventhough this is a straight forward project, there seems to be some underlying ideas for this that could be explored.

click here for the visibility shader one

click here for the visibility shader two