Surface Shading
Basic Ray Tracing - Visibility (page in progress)


return to main index



related links
   Basic Ray Tracing - Reflections
   Basic Ray Tracing - Refractions
   Ambient Occlusion
   Surface Names & Ray Names
   Problem Quadrics

 
visibility_full

Figure 1


Introduction

The basic code for a shader that uses raytracing to implement, what might be called, selective visibility is shown in listing 1. Figure 1 shows a simple scene rendered by the RIB document shown in listing 2. A mirror shader is attached to the horizontal polygon.

The "visibility1" shader is attached to the two spheres and figure 2 shows the result of setting the "visToCamera" and "visToOthers" parameters so that the red sphere no longer has a reflected image (visToOthers = 0) while the green cannot be seen by the camera (visToCamera = 0).

 
visibility1

Figure 2


Listing 1

/*  This shader determines the visibility of a surface.
    By setting "visToOthers" to 0 a surface will not 
    appear in the reflections of mirror objects  - a  
    kind of vampire effect. When "visToCamera" is set
    to 0 the object becomes invisible to the camera.
*/
surface
visibility1(
   float  Kd = 1,         /* basic brightness */
          visToCamera = 1,/* [0 or 1] camera rays */
          visToOthers = 1 /* [0 or 1] non-camera rays */
          )
{
/* STEP 1
     Make a copy of the surface normal one unit 
     in length */
normal  n = normalize(N);
normal  nf = faceforward(n, I);
string  typename = "unknown";

/* STEP 2
    What type of ray caused shader execution? */
rayinfo("type", typename);

float isCameraRay = (typename == "camera") ? 1 : 0;

/* STEP 3
    Usual calculation of Oi and Ci even though the
    shader is only considering simple lighting */
if((isCameraRay == 1 && visToCamera == 1) ||
   (isCameraRay == 0 && visToOthers == 1))
    {
    color    diffusecolor = Kd * diffuse(nf);
    Oi = Os;
    Ci = Oi * Cs * diffusecolor;
    }     
else // Ignore the surface
    {
    Oi = 0;              
    Ci = 0;
    }
}

Listing 2

Option "searchpath" "shader" "@:PATH_TO_YOUR/shaders"
Option "searchpath" "texture" "PATH_TO_YOUR/textures"
Option "trace" "int maxdepth" [5]    

Display "untitled" "framebuffer" "rgb"
Format 427 240 1
Projection "perspective" "fov" 40
ShadingRate 1

LightSource "distantlight" 1 "intensity" 1.0
            "from" [0 0 0] "to" [0 0 1]
Translate  0 0 5
Rotate -30 1 0 0
Rotate 0   0 1 0
Scale 1 1 -1

WorldBegin
    ReverseOrientation
    Attribute "visibility" "trace" [1]
    Attribute "visibility" "transmission" ["opaque"]

    # Provide a simple wrap-around environment
    TransformBegin
        Surface "plastic" "Kd" 1
        Color 0.7 0.7 0.7
        Sphere 100 -100 100 360
    TransformEnd 
    AttributeBegin
        Color 0 1 0
        Translate 1 0.7 0
        Surface "visibility1" "visToCamera" 0
                              "visToOthers" 1
        ReverseOrientation
        Sphere 0.5 -0.5 0.5 360
    AttributeEnd 
    AttributeBegin
        Color 1 0 0
        Translate -1 0.7 0
        Surface "visibility1" "visToCamera" 1 
                              "visToOthers" 0
        ReverseOrientation
        Sphere 0.5 -0.5 0.5 360
    AttributeEnd
    TransformBegin
        Surface "mirror"
        Color 0.7 0.7 0.7
        Scale 4 4 4
        Polygon "P" [-0.5 0 -0.5   0.5 0 -0.5  
                      0.5 0 0.5  -0.5 0 0.5]
    TransformEnd
WorldEnd

Figure 3

Listing 3

/*  This shader determines the visibility of a surface.
    Visibility can be ramped between "minDist" and 
    "maxDist". The "fadeIn" parameter enables  
    visibility to increase or decrease between minDist 
    and maxDist.
*/
surface
vis_by_dist(
    float  Kd = 1, /* basic brightness */
    cameraVis = 1, /* [0 or 1] camera rays */
    othersVis = 1, /* [0 or 1] non-camera rays */
    minDist = 1,
    maxDist = 2,
    fadeIn = 1,
    flip = 0)
{
/* STEP 1
     Usual stuff */
normal  n = normalize(N);
normal  nf = faceforward(n, I);
string  typename = "unknown";
color   diffusecolor;

/* STEP 2
    What type of ray caused shader execution? */
rayinfo("type", typename);

float isCameraRay = (typename == "camera") ? 1 : 0;

/* STEP 3
        The calculation of Oi and Os depends on what 
        "visibilities" the user has selected */
if((isCameraRay == 1 && cameraVis == 1) ||
   (isCameraRay == 0 && othersVis == 1))
   {
   diffusecolor = Kd * diffuse(nf);
   Oi = Os;
   Ci = Oi * Cs * diffusecolor;
   }
else if(fadeIn == 1) // Ignore ourself - shoot a ray
   {
   float i = smoothstep(minDist, maxDist, length(I));
   Oi = Os * i;
   diffusecolor = Kd * diffuse(nf) * i;
   Ci = diffusecolor * 
        mix(color trace(P, I), Cs, i) * Oi;
   }
else
   {
   float isFront;
   if(flip == 0)
       isFront = (n == nf) ? 1 : 0;
   else
       isFront = (n == nf) ? 0 : 1; 
   if(isFront == 1)
       {
       float i = smoothstep(minDist, maxDist, length(I));
       Oi = Os * (1 - i);
       diffusecolor = Kd * diffuse(nf) * (1 - i);
       Ci = diffusecolor * 
            mix(Cs, color trace(P, I), i) * Oi;
       }
   else
       {
       Oi = 0;
       Ci = trace(P, I) * Oi;
       }
   }
}







© 2002-5 Malcolm Kesson. All rights reserved.