/** * Given a ray, find the first place it intersects the scene geometry. * @param ray [description] * @return */ Intersection getClosestIntersection(Ray ray, bool isShadowRay) { Intersection closestInters = Intersection(); for(std::vector<Object>::iterator obj = scene.objects.begin(); obj != scene.objects.end(); ++obj) { Intersection inters = obj->bvh.intersect(ray, 0.0f, 800.0f); // for(std::vector<Triangle>::iterator tris = obj->triangles.begin(); tris != obj->triangles.end(); ++tris) { // Intersection inters = tris->intersect(ray); if( inters.didHit() ) { if( inters.distanceTraveled < closestInters.distanceTraveled || !closestInters.didHit() ) { closestInters = inters; closestInters.object = &*obj; } } // } for(std::vector<Circle>::iterator circ = obj->circles.begin(); circ != obj->circles.end(); ++circ) { Intersection inters = circ->intersect(ray); if( inters.didHit() ) { if( inters.distanceTraveled < closestInters.distanceTraveled || !closestInters.didHit() ) { closestInters = inters; closestInters.object = &*obj; } } } } return closestInters; }
Spectrum DirectLightingIntegrator::Li(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Intersection &isect, const Sample *sample, RNG &rng, MemoryArena &arena) const { Spectrum L(0.f); // Evaluate BSDF at hit point BSDF *bsdf = isect.GetBSDF(ray, arena); Vector wo = -ray.d; const Point &p = bsdf->dgShading.p; const Normal &n = bsdf->dgShading.nn; // Compute emitted light if ray hit an area light source L += isect.Le(wo); // Compute direct lighting for _DirectLightingIntegrator_ integrator if (scene->lights.size() > 0) { // Apply direct lighting strategy switch (strategy) { case SAMPLE_ALL_UNIFORM: L += UniformSampleAllLights(scene, renderer, arena, p, n, wo, isect.rayEpsilon, ray.time, bsdf, sample, rng, lightSampleOffsets, bsdfSampleOffsets); break; case SAMPLE_ONE_UNIFORM: L += UniformSampleOneLight(scene, renderer, arena, p, n, wo, isect.rayEpsilon, ray.time, bsdf, sample, rng, lightNumOffset, lightSampleOffsets, bsdfSampleOffsets); break; } } if (ray.depth + 1 < maxDepth) { Vector wi; // Trace rays for specular reflection and refraction Spectrum reflection(0.f); Spectrum refraction(0.f); reflection = SpecularReflect(ray, bsdf, rng, isect, renderer, scene, sample,arena); refraction = SpecularTransmit(ray, bsdf, rng, isect, renderer, scene, sample, arena); L += reflection; L += refraction; } //printf("Size %i \n", NaiadFoam::cur->FoamPlane().size()); return L*bsdf->dgShading.mult; }
int main() { Sphere sphere(vec3(-3,0,0),2); Ray ray(vec3(10,1,1),vec3(-1,0,0),100,0,5); sphere.displayTTY(); ray.displayTTY(); Intersection inter; if(sphere.intersect(ray,inter)) { inter.displayTTY(); } else { cout<<"Pas d'intersection"<<endl; } return 0; }
MatrixXcf Circuit_Handler::calc_X(){ int startrow = 0; int startcol = 0; MatrixXcf tempM; MatrixXcf X(num_of_nodes,num_of_nodes); X.setZero(); Intersection *tempi; for (vector<Intersection *>::iterator it = intersections.begin() ; it != intersections.end(); ++it){ tempi = *it; tempM = tempi->calc_X(); X.block(startrow,startcol,tempM.rows(),tempM.cols()) = tempM; startrow += tempM.rows(); startcol += tempM.cols(); } return X; }
bool SphereIntersector<real>::Intersect( const Sphere<real>* sphere, const Ray<real>& ray, Intersection<real>& oIntersection ) { // Compute the equation corresponding to x²+y²+z²=0 with p+t*d to obtain a quadratic equation real a = ray.GetDirection().SquaredLength(); real b = 2.0 * ray.GetDirection() * ray.GetOrigin(); real c = ray.GetOrigin().SquaredLength() - sphere->GetRadius() * sphere->GetRadius(); real discriminant = b*b - 4*a*c; // Discriminant >= 0 => the must be at least one intersection if ( discriminant >= 0 ) { // Compute the two potential intersections and only keep the nearest real sqrtDisc = sqrt( discriminant ); real t = 0; real t1 = ( -b - sqrtDisc ) / ( 2.0 * a ); real t2 = ( -b + sqrtDisc ) / ( 2.0 * a ); if ( t1 >= 0 ) { t = t1; oIntersection.IsInside( false ); } else if ( t2 >= 0 ) { t = t2; oIntersection.IsInside( true ); } else return false; oIntersection.SetPosition( ray.GetOrigin() + t * ray.GetDirection() ); oIntersection.SetNormal( oIntersection.GetPosition().Normalized() ); oIntersection.SetTextureCoordinates( oIntersection.GetPosition().Normalized() ); // The normal must be flipped to coincide with the hit direction if ( oIntersection.IsInside() ) oIntersection.SetNormal( -oIntersection.GetNormal() ); return true; } return false; }
// MIS: sampling BRDF glm::vec3 BidirectionalIntegrator::MIS_SampleBRDF(Intersection &intersection, Ray &r, Geometry* &light) { if(Number_BRDF == 0) return glm::vec3(0); // Direct light estimator: sample BRDF glm::vec3 sum_brdf_sample(0.0f); for(int i = 0; i < Number_BRDF; i++) { glm::vec3 wo_local = intersection.ToLocalNormalCoordinate(-r.direction); glm::vec3 wj_local; float pdf_brdf; glm::vec3 F = intersection.object_hit->material->SampleAndEvaluateScatteredEnergy(intersection,wo_local,wj_local,pdf_brdf); glm::vec3 wj_world = intersection.ToWorldNormalCoordinate(wj_local); glm::vec3 wo_world = - r.direction; Intersection isxOnLight = intersection_engine->GetIntersection(Ray(intersection.point+float(1e-3)*intersection.normal, wj_world)); if(isxOnLight.t > 0 && isxOnLight.object_hit == light && pdf_brdf > 0) { float temp,pdf_light = light->RayPDF(intersection, Ray(intersection.point, wj_world)); float W = PowerHeuristic(pdf_brdf,float(Number_BRDF),pdf_light,float(Number_Light)); glm::vec3 Ld = light->material->EvaluateScatteredEnergy(isxOnLight,wo_world,-wj_world,temp); if(pdf_light > 0 ) { if(isinf(pdf_brdf)) // delta specular surface { sum_brdf_sample = sum_brdf_sample + F * Ld * float(fabs(glm::dot(wj_world, intersection.normal))) / pdf_light; } else { sum_brdf_sample = sum_brdf_sample + W * F * Ld * float(fabs(glm::dot(wj_world,intersection.normal))) / pdf_brdf; } } } } return sum_brdf_sample / float(Number_BRDF); }
const Vector3 RenderEngine::trace_ray(const Vector2& pi) { // NOTE: Vector2 'pi' stores the pixel coordinates in the range // pi[0] in [0, film->sizex-1], pi[1] in [0, film->sizey-1] Vector2 p = film->window_coords2image_coords(pi); Ray r = camera->get_ray(p); Intersection it; world->first_intersection(r, it); // Get the ray's first intersection in the scene (if exists) if (it.did_hit()) { return photon_mapping->shade(it); } else // ... or return background's color if the ray does not intersect. return world->get_background(); }
Intersection* CSGUnion::intersectLocalLimitedTime(const Ray &shoot, DBL tmax) const { assert(isclosed); stat.eval(); CSGUnionIntersection* i = 0; // fill Array with initial values for(unsigned int j=0; j<objects->listsize; j++) { Object3D* current = static_cast<Object3D*>(objects->list[j]); double t; if ( (t=current->intersectBounding(shoot,tmax))!=INTERSECTION_TIME_EPSILON ) { if (t > INTERSECTION_TIME_EPSILON) { // boundingbox hit if (i == 0) i = new CSGUnionIntersection(this,shoot,tmax); i->put(0,t,current); } } else { // there is no boundingbox or we are inside Intersection* ci = current->intersectLimitedTime(shoot,tmax); if (ci) { if (i == 0) i = new CSGUnionIntersection(this,shoot,tmax); i->put(ci,ci->currentTime(),current); } } } if (i) { // build up structure if (i->init() == false) {delete(i); return 0;} stat.success(); } return i; }
bool Intersection::isCloser(const Intersection& other) const { if (this->isMiss()) { return false; } else if (other.isMiss()) { return true; } else { return this->t < other.t; } }
Intersection World::trace(const Segment &segment, const FindFilter &filter) const { Intersection out; if(filter.m_flags & Flags::tile) { pair<int, float> isect = m_tile_map.trace(segment, -1, filter.m_flags); if(isect.first != -1) out = Intersection(ObjectRef(isect.first, false), isect.second); } if(filter.m_flags & Flags::entity) { int ignore_index = filterIgnoreIndex(filter); pair<int, float> isect = m_entity_map.trace(segment, ignore_index, filter.m_flags); if(isect.first != -1 && isect.second <= out.distance()) out = Intersection(ObjectRef(isect.first, true), isect.second); } return out; }
void PhotonMapper::forwardPassRay(Ray ray, int x, int y, float weight, int depth){ Intersection is; if (weight > 0 && depth < maxForwardPassDepth && mScene->intersect(ray, is)){ Hitpoint* hp = new Hitpoint(); hp->pixelX = x; hp->pixelY = y; hp->is = is; hp->radius = startRadius; Color reflectedC, refractedC, emittedC; Material* m = is.mMaterial; float reflectivity = m->getReflectivity(is); float transparency = m->getTransparency(is); float diffuse = (1.0f - reflectivity - transparency)*weight; hp->pixelWeight = (1.0f - reflectivity - transparency) * weight; if (reflectivity > 0.0f) { Ray reflectedRay = is.getReflectedRay(); forwardPassRay(reflectedRay, x, y, reflectivity * weight, depth+1); } if (transparency > 0.0f) { Ray refractedRay = is.getRefractedRay(); forwardPassRay(refractedRay, x, y, transparency * weight, depth+1); } if (diffuse){ for (int i = 0; i < mScene->getNumberOfLights(); ++i){ PointLight* l = mScene->getLight(i); if (!mScene->intersect(is.getShadowRay(l))){ Vector3D lightVec = l->getWorldPosition() - is.mPosition; float d2 = lightVec.length2(); lightVec.normalize(); Color radiance = l->getRadiance(); Color brdf = is.mMaterial->evalBRDF(is, lightVec); float angle = max(lightVec * is.mNormal, 0.0f); hp->directIllumination += radiance * brdf * angle / d2; } } vec.push_back(hp); } } }
Spectrum DipoleSubsurfaceIntegrator::Li(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Intersection &isect, const Sample *sample, RNG &rng, MemoryArena &arena) const { Spectrum L(0.); Vector wo = -ray.d; // Compute emitted light if ray hit an area light source L += isect.Le(wo); // Evaluate BSDF at hit point BSDF *bsdf = isect.GetBSDF(ray, arena); const Point &p = bsdf->dgShading.p; const Normal &n = bsdf->dgShading.nn; // Evaluate BSSRDF and possibly compute subsurface scattering BSSRDF *bssrdf = isect.GetBSSRDF(ray, arena); if (bssrdf && octree) { Spectrum sigma_a = bssrdf->sigma_a(); Spectrum sigmap_s = bssrdf->sigma_prime_s(); Spectrum sigmap_t = sigmap_s + sigma_a; if (!sigmap_t.IsBlack()) { // Use hierarchical integration to evaluate reflection from dipole model PBRT_SUBSURFACE_STARTED_OCTREE_LOOKUP(const_cast<Point *>(&p)); DiffusionReflectance Rd(sigma_a, sigmap_s, bssrdf->eta()); Spectrum Mo = octree->Mo(octreeBounds, p, Rd, maxError); FresnelDielectric fresnel(1.f, bssrdf->eta()); Spectrum Ft = Spectrum(1.f) - fresnel.Evaluate(AbsDot(wo, n)); float Fdt = 1.f - Fdr(bssrdf->eta()); L += (INV_PI * Ft) * (Fdt * Mo); PBRT_SUBSURFACE_FINISHED_OCTREE_LOOKUP(); } } L += UniformSampleAllLights(scene, renderer, arena, p, n, wo, isect.rayEpsilon, ray.time, bsdf, sample, rng, lightSampleOffsets, bsdfSampleOffsets); if (ray.depth < maxSpecularDepth) { // Trace rays for specular reflection and refraction L += SpecularReflect(ray, bsdf, rng, isect, renderer, scene, sample, arena); L += SpecularTransmit(ray, bsdf, rng, isect, renderer, scene, sample, arena); } return L; }
Intersection IntersectionGenerator::GetActualNextIntersection(const NodeID starting_node, const EdgeID via_edge, NodeID *resulting_from_node = nullptr, EdgeID *resulting_via_edge = nullptr) const { // This function skips over traffic lights/graph compression issues and similar to find the next // actual intersection Intersection result = GetConnectedRoads(starting_node, via_edge); // Skip over stuff that has not been compressed due to barriers/parallel edges NodeID node_at_intersection = starting_node; EdgeID incoming_edge = via_edge; // to prevent endless loops const auto termination_node = node_based_graph.GetTarget(via_edge); // using a maximum lookahead, we make sure not to end up in some form of loop std::unordered_set<NodeID> visited_nodes; while (visited_nodes.count(node_at_intersection) == 0 && (result.size() == 2 && node_based_graph.GetEdgeData(via_edge).IsCompatibleTo( node_based_graph.GetEdgeData(result[1].eid)))) { visited_nodes.insert(node_at_intersection); node_at_intersection = node_based_graph.GetTarget(incoming_edge); incoming_edge = result[1].eid; result = GetConnectedRoads(node_at_intersection, incoming_edge); // When looping back to the original node, we obviously are in a loop. Stop there. if (termination_node == node_based_graph.GetTarget(incoming_edge)) break; } // return output if requested if (resulting_from_node) *resulting_from_node = node_at_intersection; if (resulting_via_edge) *resulting_via_edge = incoming_edge; return result; }
SColor RayTracer::calculateShadowScalar(Light <, Intersection &in) { // cout << in.toString() << endl; Vect p = lt.getPos(); Vect ori = in.calculateIntersectionPoint();// + in.calculateSurfaceNormal().linearMult(0.0001f); Vect dir; if (lt.getType() == DIRECTIONAL_LIGHT) { dir = lt.getDir().invert(); } else { dir = p - ori; dir.normalize(); } ori = ori + dir.linearMult(0.001f); Ray shdw(ori, dir); Intersection ins = scene->calculateRayIntersection(shdw); Material *mat = ins.getMaterial(); if (!ins.hasIntersected()) { // The point is in direct light return SColor(1, 1, 1); } else if (mat->getTransparency() <= 0.00000001) { // The material is fully opaque Vect pos = ins.calculateIntersectionPoint(); if (lt.getType() == DIRECTIONAL_LIGHT || ori.euclideanDistance(pos) < ori.euclideanDistance(lt.getPos())) { // The ray intersects with an object before the light source return SColor(0, 0, 0); } else { // The ray intersects with an object behind the lightsource // or a direction light, thus fully in light return SColor(1, 1, 1); } } else { // The shape is transparent // Normalize the color for this material, and recursively trace for other // transparent objects SColor Cd = mat->getDiffColor(); float m = max(Cd.R(), max(Cd.G(), Cd.B())); Cd.R(Cd.R()/m); Cd.G(Cd.G()/m); Cd.B(Cd.B()/m); SColor Si = Cd.linearMult(mat->getTransparency()); return Si.linearMult(calculateShadowScalar(lt, ins)); } }
// WhittedIntegrator Method Definitions Spectrum WhittedIntegrator::Li(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Intersection &isect, const Sample *sample, MemoryArena &arena) const { Spectrum L(0.); // Compute emitted and reflected light at ray intersection point // Evaluate BSDF at hit point BSDF *bsdf = isect.GetBSDF(ray, arena); // Initialize common variables for Whitted integrator const Point &p = bsdf->dgShading.p; const Normal &n = bsdf->dgShading.nn; Vector wo = -ray.d; // Compute emitted light if ray hit an area light source L += isect.Le(wo); // Add contribution of each light source Vector wi; for (u_int i = 0; i < scene->lights.size(); ++i) { VisibilityTester visibility; float pdf; Spectrum Li = scene->lights[i]->Sample_L(p, isect.rayEpsilon, LightSample(*sample->rng), sample->time, &wi, &pdf, &visibility); if (Li.IsBlack() || pdf == 0.f) continue; Li /= pdf; Spectrum f = bsdf->f(wo, wi); if (!f.IsBlack() && visibility.Unoccluded(scene)) L += f * Li * AbsDot(wi, n) * visibility.Transmittance(scene, renderer, sample, NULL, arena); } if (ray.depth + 1 < maxDepth) { // Trace rays for specular reflection and refraction L += SpecularReflect(ray, bsdf, *sample->rng, isect, renderer, scene, sample, arena); L += SpecularTransmit(ray, bsdf, *sample->rng, isect, renderer, scene, sample, arena); } return L; }
SColor RayTracer::shadeIntersection(Intersection in, uint d) { if (d <= 0 || in.hasIntersected() == false) { // terminate recursion return SColor(0, 0, 0); } Vect shade(0, 0, 0); Material *mat = in.getMaterial(); float kt = mat->getTransparency(); SColor ks = mat->getSpecColor(); SColor ka = mat->getAmbColor(); SColor Cd = mat->getDiffColor(); SColor ambLight = Whitted::AmbientLightning(kt, ka, Cd); std::vector<Light *> lts = scene->getLights(); for (uint i = 0; i < lts.size(); i++) { Light *l = lts.at(i); SColor Sj = calculateShadowScalar(*l, in); shade = shade + Whitted::Illumination(l, in, Sj); } SColor reflection; if (ks.length() > 0) { Ray r = in.calculateReflection(); Intersection rin = scene->calculateRayIntersection(r); reflection = shadeIntersection(rin, d-1).linearMult(ks); } SColor refraction; if (kt > 0) { Ray r = in.calculateRefraction(); Intersection rin = scene->calculateRayIntersection(r); refraction = shadeIntersection(rin, d-1).linearMult(kt); } shade = ambLight + shade + reflection + refraction; return shade; }
int BidirIntegrator::generatePath(const Scene *scene, const Ray &r, const Sample *sample, const int *bsdfOffset, const int *bsdfCompOffset, BidirVertex *vertices, int maxVerts) const { int nVerts = 0; RayDifferential ray(r.o, r.d); while (nVerts < maxVerts) { // Find next vertex in path and initialize _vertices_ Intersection isect; if (!scene->Intersect(ray, &isect)) break; BidirVertex &v = vertices[nVerts]; v.bsdf = isect.GetBSDF(ray); // do before Ns is set! v.p = isect.dg.p; v.ng = isect.dg.nn; v.ns = v.bsdf->dgShading.nn; v.wi = -ray.d; ++nVerts; // Possibly terminate bidirectional path sampling if (nVerts > 2) { float rrProb = .2f; if (RandomFloat() > rrProb) break; v.rrWeight = 1.f / rrProb; } // Initialize _ray_ for next segment of path float u1 = sample->twoD[bsdfOffset[nVerts-1]][0]; float u2 = sample->twoD[bsdfOffset[nVerts-1]][1]; float u3 = sample->oneD[bsdfCompOffset[nVerts-1]][0]; Spectrum fr = v.bsdf->Sample_f(v.wi, &v.wo, u1, u2, u3, &v.bsdfWeight, BSDF_ALL, &v.flags); if (fr.Black() && v.bsdfWeight == 0.f) break; ray = RayDifferential(v.p, v.wo); } // Initialize additional values in _vertices_ for (int i = 0; i < nVerts-1; ++i) vertices[i].dAWeight = vertices[i].bsdfWeight * AbsDot(-vertices[i].wo, vertices[i+1].ng) / DistanceSquared(vertices[i].p, vertices[i+1].p); return nVerts; }
Vec3 DirectShader::getRadiance(const Vec3& direction, const Intersection& intersection, unsigned int depth) const { const size_t lightCount = scene.getLightCount(); Vec3 radiance(0.0f); for ( size_t i = 0; i < lightCount; ++i) { const Light& light = scene.getLight( i ); Vec3 l( light.getPosition() - intersection.getLocation() ); const float distance = l.normalizeRL(); const Vec3& normal = intersection.getNormal(); const float d1 = fmaxf(normal * l, 0.0f); const float d2 = fmaxf( d1 * ((l * -1.0f) * light.getDirection()), 0.0f); if ( d2 > 0.0f ) { const RaySegment shadowRay( intersection.getLocation() + l * 0.00001, l, 0.0, distance ); // const RaySegmentIgnore shadowRay( intersection.getLocation(), l, intersection.getPrimitive(), 0.0, distance ); if ( ! scene.hasIntersection( shadowRay ) ) radiance += (light.getColor() ^ color) * d2; } } return radiance; }
virtual Vec sample( Intersection const &isect, float u1, float u2, Vec& WiW, float& pdfResult, int &bxdfType) const { pdfResult = 1.f; WiW = isect.toWorld(cosineSampleHemisphere(u1, u2)); bxdfType = BxDF_DIFFUSE; return isect.texSample; }
bool OctreeScene::Intersect(const Ray& ray, Intersection& intersection, void* additional_data) const { float min_t = ray.EffectRange().Max; const OctreeNode* current = m_GeometryTree.Root(); std::priority_queue<Octree::QueueElement> queue; Intersection hit; if (current->Extents().Intersect(ray, hit, additional_data)) queue.push(Octree::QueueElement(hit.Distance(), current)); while (!queue.empty() && queue.top().t < min_t) { current = queue.top().node; queue.pop(); if (current->IsLeaf()) { for (auto iter = current->Triangles().begin(); iter != current->Triangles().end(); ++iter) { if ((*iter)->Intersect(ray, hit, additional_data) && hit.Distance() < min_t) { min_t = hit.Distance(); intersection = hit; } } } else { for (unsigned i = 0; i < 8; ++i) if (current->ChildAt(i) != nullptr) if (current->ChildAt(i)->Extents().Intersect(ray, hit, additional_data)) queue.push(Octree::QueueElement(hit.Distance(), current->ChildAt(i))); } } if (min_t != ray.EffectRange().Max) return true; else return false; }
int main(int argc, char **argv) { Intersection isec; if(argc!=3) { printf("needs: Q1phase Q2phase\n"); exit(0); } Q1phase=atoi(argv[1]); Q2phase=atoi(argv[2]); if(Q1phase < 30 || Q2phase < 30) { printf("Minimum time for each queue to be closed is 30 seconds\n"); exit(0); } isec.SetPhasing(0,Q1phase); isec.SetPhasing(1,Q2phase); isec.SetCarAdd(0,Q1arrive); isec.SetCarAdd(1,Q1arrive); while(isec.time()<=7200) { isec.Tick(); } printf("Queue 1 length: %d\n",isec.QueueLength(0)); printf("Queue 2 length: %d\n",isec.QueueLength(1)); return 0; }
Spectrum IrradianceCacheIntegrator::Li(const Scene *scene, const Renderer *renderer, const RayDifferential &ray, const Intersection &isect, const Sample *sample, RNG &rng, MemoryArena &arena) const { Spectrum L(0.); // Evaluate BSDF at hit point BSDF *bsdf = isect.GetBSDF(ray, arena); Vector wo = -ray.d; const Point &p = bsdf->dgShading.p; const Normal &n = bsdf->dgShading.nn; L += isect.Le(wo); // Compute direct lighting for irradiance cache L += UniformSampleAllLights(scene, renderer, arena, p, n, wo, isect.rayEpsilon, ray.time, bsdf, sample, rng, lightSampleOffsets, bsdfSampleOffsets); // Compute indirect lighting for irradiance cache if (ray.depth + 1 < maxSpecularDepth) { Vector wi; // Trace rays for specular reflection and refraction L += SpecularReflect(ray, bsdf, rng, isect, renderer, scene, sample, arena); L += SpecularTransmit(ray, bsdf, rng, isect, renderer, scene, sample, arena); } // Estimate indirect lighting with irradiance cache Normal ng = isect.dg.nn; ng = Faceforward(ng, wo); // Compute pixel spacing in world space at intersection point float pixelSpacing = sqrtf(Cross(isect.dg.dpdx, isect.dg.dpdy).Length()); BxDFType flags = BxDFType(BSDF_REFLECTION | BSDF_DIFFUSE | BSDF_GLOSSY); L += indirectLo(p, ng, pixelSpacing, wo, isect.rayEpsilon, bsdf, flags, rng, scene, renderer, arena); flags = BxDFType(BSDF_TRANSMISSION | BSDF_DIFFUSE | BSDF_GLOSSY); L += indirectLo(p, -ng, pixelSpacing, wo, isect.rayEpsilon, bsdf, flags, rng, scene, renderer, arena); return L; }
Intersection WorldViewer::trace(const Segment &segment, const FindFilter &filter) const { Intersection out; if(filter.flags() & Flags::tile) out = m_world->trace(segment, (filter.flags() & ~Flags::entity) | Flags::visible); if(filter.flags() & Flags::entity) { int ignore_index = m_world->filterIgnoreIndex(filter); for(int n = 0; n < (int)m_entities.size(); n++) { const Entity *entity = refEntity(n); if(!entity || !m_occluder_config.isVisible(m_entities[n].occluder_id) || !Flags::test(entity->flags(), filter.flags()) || n == ignore_index) continue; float distance = intersection(segment, entity->boundingBox()); if(distance < out.distance()) out = Intersection(ObjectRef(n, true), distance); } } return out; }
bool Sphere::intersect(const Ray &ray, Intersection &iSect) const { vec3 C, SP; float r, b, d, t; // Get sphere center in world space C = m_centerTransformed; // Transform ray origin to object space SP = C - ray.getOrigin(); // Get transformed radius r = m_radiusTransformed; // Solve the quadratic equation for t b = vec3::dot(SP, ray.getDirection()); d = b * b - vec3::dot(SP, SP) + r * r; if (d < 0.0f) { return false; } d = std::sqrt(d); t = (t = b - d) > EPSILON ? t : ((t = b + d) > EPSILON ? t : -1.0f); if (t == -1.0f) { return false; } // Set final surface intersection info iSect.setT(t); iSect.setPosition(ray(t)); iSect.setNormal((iSect.getPosition() - C) / r); iSect.setMaterial(m_material); return true; }
Intersection GridEntry::intersect(Ray r, bool computeNorm, unsigned int *int_test, unsigned int *int_hit) { Intersection bestIsect(9.9e99, false); if (objects.size()==0) { return bestIsect; } Intersection curIsect; for (ObjectList::iterator obj_iter = objects.begin(); obj_iter != objects.end(); ++obj_iter) { curIsect = (*obj_iter)->intersect(r, computeNorm); (*int_test)++; if (curIsect.hits()) { ++(*int_hit); if (curIsect.t()<bestIsect.t()) { bestIsect = curIsect; bestIsect.setGridEntry(this); } } } return bestIsect; }
Intersection PlanoY::Intercepta(const Raio& r_vis, IntersectionMode mode, float threshold) { float x,z; float t = (a - r_vis.Y0()) / r_vis.Dy(); Intersection lastIntersection; if ( t <0) return lastIntersection; x = r_vis.X0() + t * r_vis.Dx(); if (INSIDE(x,bmin,bmax)) { z = r_vis.Z0() + t *r_vis.Dz(); if (INSIDE(z,cmin,cmax)) { lastIntersection.setValues(this, t); return lastIntersection; } } return lastIntersection; }
virtual Vec sample( Intersection const &isect, float u1, float u2, Vec& WiW, float& pdfResult, int &bxdfType) const { Vec WoL = isect.toLocal(isect.WoW); Vec result; if (WoL.z() < 0.f) { Vec Wi = perfectSpecularRefraction(-WoL, 1.f / m_ior); result = Vec(1.f, 1.f, 1.f) * fresnelCoef(Wi * Vec(1.f, 1.f, -1.f), m_r0); WiW = isect.toWorld(-Wi); } else { Vec Wi = perfectSpecularRefraction(WoL, m_ior); result = Vec(1.f, 1.f, 1.f) * fresnelCoef(Wi * Vec(1.f, 1.f, -1.f), m_r0); WiW = isect.toWorld(Wi); } bxdfType = BxDF_SPECULAR; pdfResult = 1.f; return result; }
bool Plane::Intersect(const Ray& ray, Intersection& intersection, void* additional_data) const { float dir_norm = ray.Direction().DotProduct(m_Orientation); if (abs(dir_norm) < std::numeric_limits<float>::epsilon()) return false; float t = (m_Center - ray.Origin()).DotProduct(m_Orientation) / dir_norm; Range<float> range = ray.EffectRange(); if (Math::Contain(t, range)) { intersection.SetDistance(t); intersection.SetIntersectObject((IIntersectTarget*)this); intersection.SetTestObject(&ray); return true; } return false; }
void fillIntersectionRecord(const Ray &ray, const void *temp, Intersection &its) const { const Float *data = static_cast<const Float *>(temp); its.shFrame = its.geoFrame = m_frame; its.shape = this; its.dpdu = m_dpdu; its.dpdv = m_dpdv; its.uv = Point2(0.5f * (data[0]+1), 0.5f * (data[1]+1)); its.p = ray(its.t); its.wi = its.toLocal(-ray.d); its.hasUVPartials = false; its.instance = NULL; its.time = ray.time; }
/** * Computes the first intersection between a ray and all * the Objects of the scene. * @param ray the ray to be intersected * @param intersection the first intersection computed if * there is one * @return true if there is an intersection, false otherwise. **/ bool Scene::intersect(const ray::Ray & ray, scene::Intersection & intersection) { bool isIntersected=false; float minDistance=INFINITY; Intersection interTest; for(iterator_object it=_objects.begin(); it!=_objects.end();++it) { if((*it)->intersect(ray,interTest)) { float currentDistance=glm::distance2(interTest.getPoint(), ray.getOrigin()); if(currentDistance<minDistance) { isIntersected=true; minDistance=currentDistance; intersection=interTest; } } } return isIntersected; }