// Trace is the most fundamental of all the ray tracing functions. It // answers the query "What color do I see looking along the given ray // in the current scene?" This is an inherently recursive process, as // trace may again be called as a result of the ray hitting a reflecting // object. To prevent the possibility of infinite recursion, a maximum // depth is placed on the resulting ray tree. Color Raytracer::Trace( const Ray &ray, const Scene &scene, int max_tree_depth ) { Color color; // The color to return. HitInfo hitinfo; // Holds info to pass to shader. // Intitallizes hit distance to infinity to allow finding intersections in all ray length hitinfo.geom.distance = Infinity; if (Cast( ray, scene, hitinfo ) > 0.0f && max_tree_depth > -1 ) { // The ray hits an object, so shade the point that the ray hit. // Cast has put all necessary information for Shade in "hitinfo". // If the ray has no_emitters activated and the first hit is an emitter // this ray shouldn't contribute to the color of the current pixel if( hitinfo.material.Emitter() && ray.no_emitters == true ) color = Color (); // The ray hits an object, so shade the point that the ray hit. // Cast has put all necessary information for Shade in "hitinfo". else color = Shade( hitinfo, scene, max_tree_depth ); } else { // Either the ray has failed to hit anything, or // the recursion has bottomed out. color = scene.bgcolor; } return color; }
Color RayTracer::Render(const Ray& rRay, bool vIsReflecting, const Shape* pReflectingFrom ) { mRecursions++; Shape* closest_shape; Point intersect_point; Color result; if (vIsReflecting) closest_shape = QueryScene(rRay, intersect_point, vIsReflecting, pReflectingFrom); else closest_shape = QueryScene(rRay, intersect_point); if (closest_shape == NULL && !vIsReflecting) { mRecursions = 0; return mBackgroundColor; } if (closest_shape == NULL && vIsReflecting) { mRecursions = 0; return mAmbientColor*mAmbientIntensity; } if ( mRecursions > mRecursionLimit ) { mRecursions = 0; return Color(0,0,0); // mAmbientColor*mAmbientIntensity; } result = closest_shape->ShapeColor()*Shade(closest_shape, intersect_point); Ray backwards_ray(intersect_point,rRay.Direction()*-1); if ( closest_shape->DiffuseReflectivity() > 0.0 ) result = result + (Render( closest_shape->Reflect(intersect_point,backwards_ray), true, closest_shape )*closest_shape->DiffuseReflectivity()); return (result + mSpecularColor); }
void Raytracer::Trace(const Ray& aRay, Color* aColor, int aDepth) { aq_float T; Intersection RayIntersection; if (!mScene->Intersect(aRay, &T, &RayIntersection)) { *aColor = mScene->Properties.BackgroundColor; return; } *aColor = COLOR::BLACK; for (Light* light : mScene->GetLights()) { *aColor += Shade(aRay, RayIntersection, *light); } *aColor = clamp(*aColor, 0.0, 100.0); //Russian roulette for stopping recursive if (aDepth > mScene->Properties.RecursiveDepth) { aq_float AvgReflectance = sum(RayIntersection.Mat.kr) / 3; if (AvgReflectance < Utils::RandFloatInterval(0.0, 1.2)) { return; } } //Ambient occlusion //*aColor += 0.2 * IndirectLighting(aRay, RayIntersection, aDepth); //Reflection if (sum(RayIntersection.Mat.kr) > 0) { Ray ReflectedRay(RayIntersection.Local.Pos, reflect(aRay.Dir, RayIntersection.Local.Normal)); Color ReflectedColor; Trace(ReflectedRay, &ReflectedColor, aDepth + 1); *aColor = mix(*aColor, ReflectedColor, RayIntersection.Mat.kr); } ////Refraction if (RayIntersection.Mat.Transparency > 0) { Ray RefractedRay(RayIntersection.Local.Pos, refract(aRay.Dir, RayIntersection.Local.Normal, RayIntersection.Mat.RefractiveIndex)); Color RefractedColor; Trace(RefractedRay, &RefractedColor, aDepth + 1); *aColor = mix(*aColor, RefractedColor, RayIntersection.Mat.Transparency); } }
/************************************************ || trace() || Purpose: get color of closest intersection || or return a background color || ************************************************/ RGBColor trace(Ray ray) { ObjectAttributes obj; obj = closest_intersection(ray); //get nearest obj location & # //printf("Object # for if is: %d\n", obj.objNumber); if(obj.objNumber != -1) { //printf("Return color"); //return an rgbcolor after determining if its in shadow return Shade(obj, ray); } else //if nothing hit in shadow { //printf("Return BG\n"); return backgroundColor; } }
Color Trace(Ray& R, int lev) // trace a ray { RayHit hit = RayHit(MISS, 0, Vector(0, 0, 0), false); if (lev > MAX_RECURSION_LEVEL) return defColor; int hitObj = -1; for (int i = 0; i < nObjs; i++) { RayHit h = theShapes[i]->intersect(R); if (h.status != MISS && h.tValue < R.tValue) { hitObj = i; hit = h; R.tValue = h.tValue; } } if (hitObj < 0) return defColor; else return Shade(hitObj, R, hit, lev); }
void mainImage( out vec4 fragColor, in vec2 fragCoord ) { vec2 pixel = (gl_FragCoord.xy / iResolution.xy)*2.0-1.0; // compute ray origin and direction float asp = iResolution.x / iResolution.y; vec3 rd = normalize(vec3(asp*pixel.x, pixel.y, -4.0)); vec3 ro = vec3(0.0, 0.0, 20.0); // vec2 mouse = iMouse.xy / iResolution.xy; float a=iGlobalTime*0.25; ro = rotateY(ro, a); rd = rotateY(rd, a); // Trace ray bool hit; // Number of steps int s; float t = SphereTrace(ro, rd, hit,s); vec3 pos=ro+t*rd; // Shade background vec3 rgb = background(rd); if (hit) { // Compute normal vec3 n = ObjectNormal(pos); // Shade object with light rgb = Shade(pos, n); } // Uncomment this line to shade image with false colors representing the number of steps //rgb = ShadeSteps(s); fragColor=vec4(rgb, 1.0); }
void TestMap() { XSizeHints *hints; XWindowAttributes attr; Window w; /* Create the window. */ w = XCreateSimpleWindow(display, rootWindow, 100, 100, 200, 100, 0, 0, 0); XSelectInput(display, w, StructureNotifyMask | PropertyNotify); /* Map the window and wait for it. */ XMapWindow(display, w); Assert(AwaitEvent(MapNotify)); /* Unmap the window and wait for it. */ XUnmapWindow(display, w); Assert(AwaitEvent(UnmapNotify)); /* Map the window and wait for it (again). */ XMapWindow(display, w); Assert(AwaitEvent(MapNotify)); /* Minimize and wait. */ Minimize(w); Assert(AwaitEvent(UnmapNotify)); /* Restore and wait. */ Unminimize(w); Assert(AwaitEvent(MapNotify)); /* Maximize and wait. */ Maximize(w, 1, 1); Assert(AwaitEvent(ConfigureNotify)); /* Unmaximize and wait. */ Unmaximize(w, 0, 1); Assert(AwaitEvent(ConfigureNotify)); /* Unmaximize and wait. */ Unmaximize(w, 1, 0); Assert(AwaitEvent(ConfigureNotify)); /* Change the size hints. */ hints = XAllocSizeHints(); hints->flags = PMinSize; hints->min_width = 300; hints->min_height = 200; XSetWMNormalHints(display, w, hints); XFree(hints); XSync(display, False); sleep(1); IgnoreEvents(); XGetWindowAttributes(display, w, &attr); Assert(attr.width == 300); Assert(attr.height == 200); /* Shade and wait. */ Shade(w); Assert(AwaitEvent(UnmapNotify)); /* Maximize and wait. */ Maximize(w, 0, 1); Assert(AwaitEvent(MapNotify)); /* Shade and wait. */ Shade(w); Assert(AwaitEvent(UnmapNotify)); /* Unshade and wait. */ Unshade(w); Assert(AwaitEvent(MapNotify)); /* Destroy the window. */ XDestroyWindow(display, w); }
VOID RayTrace(INT pid) { INT j; INT x, y; /* Pixel address. */ REAL xx, yy; VEC3 N; /* Normal at intersection. */ VEC3 Ipoint; /* Intersection point. */ COLOR c; /* Color for storing background. */ RAY *ray; /* Ray pointer. */ RAY rmsg; /* Ray message. */ RAYJOB job; /* Ray job from work pool. */ OBJECT *po; /* Ptr to object. */ BOOL hit; /* An object hit? */ IRECORD hitrecord; /* Intersection record. */ ray = &rmsg; while (GetJobs(&job, pid) != WPS_EMPTY) { while (GetRayJobFromBundle(&job, &x, &y)) { /* Convert the ray job to the ray message format. */ xx = (REAL)x; yy = (REAL)y; if (AntiAlias) for (j = 0; j < NumSubRays; j++) { ConvertPrimRayJobToRayMsg(ray, xx + frand(), yy + frand()); PushRayTreeStack(ray, pid); } else { ConvertPrimRayJobToRayMsg(ray, xx, yy); PushRayTreeStack(ray, pid); } while (PopRayTreeStack(ray, pid) != RTS_EMPTY) { /* Find which object is closest along the ray. */ switch (TraversalType) { case TT_LIST: hit = Intersect(ray, &hitrecord); break; case TT_HUG: hit = TraverseHierarchyUniform(ray, &hitrecord, pid); break; } /* Process the object ray hit. */ if (hit) { /* * Get parent object to be able to access * object operations. */ po = hitrecord.pelem->parent; /* Calculate intersection point. */ RayPoint(Ipoint, ray, hitrecord.t); /* Calculate normal at this point. */ ((void (*)(IRECORD *, VEC3, VEC3))(*po->procs->normal))(&hitrecord, Ipoint, N); /* Make sure normal is pointing toward ray origin. */ if ((VecDot(ray->D, N)) > 0.0) VecNegate(N, N); /* * Compute shade at this point - will process * shadow rays and add secondary reflection * and refraction rays to ray tree stack */ Shade(Ipoint, N, ray, &hitrecord, pid); } else { /* Add background as pixel contribution. */ VecCopy(c, View.bkg); VecScale(c, ray->weight, c); AddPixelColor(c, ray->x, ray->y); } } } } }