/* returns the point seen through specified pixel */ extern "C" bool device_pick(const float x, const float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p, Vec3fa& hitPos) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = g_debug; /* intersect ray with scene */ rtcIntersect(g_scene,ray); PRINT2(x,y); PRINT(ray.geomID); PRINT(ray.primID); /* shade pixel */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) { hitPos = Vec3fa(0.0f,0.0f,0.0f); return false; } else { hitPos = ray.org + ray.tfar*ray.dir; return true; } }
char embree_intersect(Ray *ray, EmbreeScene *scene) { DISABLE_FPE; rtcIntersect(scene->scene,*reinterpret_cast<RTCRay*>(ray)); ENABLE_FPE; return ray->geomID != static_cast<u32>(-1); }
osg::Vec4f Raytracer::renderPixel(int x, int y, const osg::Vec3f& eye, const osg::Vec3f& dir) { osg::Vec3f lightPos(-338.572, 0, 400); RTCRay ray; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.instID = RTC_INVALID_GEOMETRY_ID; ray.tnear = 0.0f; ray.tfar = 100000.0f; ray.org[0] = eye.x(); ray.org[1] = eye.y(); ray.org[2] = eye.z(); ray.dir[0]= dir.x(); ray.dir[1] = dir.y(); ray.dir[2] = dir.z(); rtcIntersect(_scene, ray); if(ray.primID != -1) { osg::Vec3f pos = eye + dir*ray.tfar; osg::Vec4f diffuse = getSurfaceColor(ray.geomID, ray.primID,ray.u,ray.v); osg::Vec3 normal = getNormal(ray.geomID,ray.primID,ray.u,ray.v); osg::Vec3f lightDir = lightPos - pos; lightDir.normalize(); float NdotL = std::max(normal * lightDir,0.0f); return diffuse * NdotL; } return _backgroundColor; }
/* renders a single pixel with wireframe shading */ Vec3fa renderPixelWireframe(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = g_debug; /* intersect ray with scene */ rtcIntersect(g_scene,ray); /* return black if nothing hit */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return Vec3fa(1.0f); /* calculate wireframe around triangles */ const float border = 0.05f; Vec3fa color = Vec3fa(1.0f); if (ray.u < border) color = Vec3fa(0.0f); if (ray.v < border) color = Vec3fa(0.0f); if (1.0f-ray.u-ray.v < border) color = Vec3fa(0.0f); /* perform eyelight shading */ return color*Vec3fa(embree::abs(dot(ray.dir,normalize(ray.Ng)))); }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = 0; /* intersect ray with scene */ rtcIntersect(g_scene,ray); /* shade pixels */ Vec3fa color = Vec3fa(0.0f); if (ray.geomID != RTC_INVALID_GEOMETRY_ID) { Vec3fa diffuse = ray.geomID != 0 ? Vec3fa(0.9f,0.6f,0.5f) : Vec3fa(0.8f,0.0f,0.0f); color = color + diffuse*0.5f; Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); Vec3fa Ng = normalize(ray.Ng); #if ENABLE_SMOOTH_NORMALS Vec3fa P = ray.org + ray.tfar*ray.dir; if (ray.geomID > 0) { Vec3fa dPdu,dPdv; int geomID = ray.geomID; { rtcInterpolate(g_scene,geomID,ray.primID,ray.u,ray.v,RTC_VERTEX_BUFFER,nullptr,&dPdu.x,&dPdv.x,3); } Ng = normalize(cross(dPdv,dPdu)); dPdu = dPdu + Ng*displacement_du(P,dPdu); dPdv = dPdv + Ng*displacement_dv(P,dPdv); Ng = normalize(cross(dPdv,dPdu)); } #endif /* initialize shadow ray */ RTCRay shadow; shadow.org = ray.org + ray.tfar*ray.dir; shadow.dir = neg(lightDir); shadow.tnear = 0.001f; shadow.tfar = inf; shadow.geomID = RTC_INVALID_GEOMETRY_ID; shadow.primID = RTC_INVALID_GEOMETRY_ID; shadow.mask = -1; shadow.time = 0; /* trace shadow ray */ rtcOccluded(g_scene,shadow); /* add light contribution */ if (shadow.geomID == RTC_INVALID_GEOMETRY_ID) color = color + diffuse*clamp(-(dot(lightDir,Ng)),0.0f,1.0f); } return color; }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(float x, float y, const ISPCCamera& camera) { /* initialize ray */ RTCRay ray; ray.org = Vec3fa(camera.xfm.p); ray.dir = Vec3fa(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz)); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = 0; /* intersect ray with scene */ rtcIntersect(g_scene,ray); /* shade pixels */ Vec3fa color = Vec3fa(0.0f); if (ray.geomID != RTC_INVALID_GEOMETRY_ID) { /* interpolate diffuse color */ Vec3fa diffuse = Vec3fa(1.0f,0.0f,0.0f); if (ray.geomID > 0) { unsigned int geomID = ray.geomID; { rtcInterpolate(g_scene,geomID,ray.primID,ray.u,ray.v,RTC_USER_VERTEX_BUFFER0,&diffuse.x,nullptr,nullptr,3); } diffuse = 0.5f*diffuse; } /* calculate smooth shading normal */ Vec3fa Ng = normalize(ray.Ng); color = color + diffuse*0.5f; Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); /* initialize shadow ray */ RTCRay shadow; shadow.org = ray.org + ray.tfar*ray.dir; shadow.dir = neg(lightDir); shadow.tnear = 0.001f; shadow.tfar = inf; shadow.geomID = 1; shadow.primID = 0; shadow.mask = -1; shadow.time = 0; /* trace shadow ray */ rtcOccluded(g_scene,shadow); /* add light contribution */ if (shadow.geomID) { Vec3fa r = normalize(reflect(ray.dir,Ng)); float s = pow(clamp(dot(r,lightDir),0.0f,1.0f),10.0f); float d = clamp(-dot(lightDir,Ng),0.0f,1.0f); color = color + diffuse*d + 0.5f*Vec3fa(s); } } return color; }
MSC_NAMESPACE_BEGIN void RayIntersect::operator()(const tbb::blocked_range< size_t >& r) const { // Test packing data for sse vectorization for(size_t index = r.begin(); index < r.end(); ++index) rtcIntersect(m_scene->rtc_scene, m_data[index].rtc_ray); }
/* renders a single pixel with ambient occlusion shading */ Vec3fa renderPixelAmbientOcclusion(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = 0; /* intersect ray with scene */ rtcIntersect(g_scene,ray); /* return black if nothing hit */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return Vec3fa(0.0f); /* calculate hit point */ float intensity = 0; Vec3fa hitPos = ray.org + ray.tfar*ray.dir; /* trace some ambient occlusion rays */ int seed = 34*x+12*y; for (int i=0; i<32; i++) { Vec3fa dir; const float oneOver10000f = 1.f/10000.f; seed = 1103515245 * seed + 12345; dir.x = (seed%10000)*oneOver10000f; seed = 1103515245 * seed + 12345; dir.y = (seed%10000)*oneOver10000f; seed = 1103515245 * seed + 12345; dir.z = (seed%10000)*oneOver10000f; /* initialize shadow ray */ RTCRay shadow; shadow.org = hitPos; shadow.dir = dir; shadow.tnear = 0.001f; shadow.tfar = inf; shadow.geomID = 1; shadow.primID = 0; shadow.mask = -1; shadow.time = 0; /* trace shadow ray */ rtcOccluded(g_scene,shadow); /* add light contribution */ intensity += shadow.geomID; } intensity *= 1.0f/32.0f; /* shade pixel */ return Vec3fa(intensity); }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(float x, float y, const ISPCCamera& camera, RayStats& stats) { /* initialize ray */ RTCRay ray; ray.org = Vec3fa(camera.xfm.p); ray.dir = Vec3fa(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz)); ray.tnear = 0.0f; ray.tfar = (float)(inf); ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.instID = -1; ray.mask = -1; ray.time = 0; /* intersect ray with scene */ rtcIntersect(g_scene,ray); RayStats_addRay(stats); /* shade pixels */ Vec3fa color = Vec3fa(0.0f); if (ray.geomID != RTC_INVALID_GEOMETRY_ID) { /* calculate shading normal in world space */ Vec3fa Ns = ray.Ng; if (ray.instID != RTC_INVALID_GEOMETRY_ID) Ns = xfmVector(normal_xfm[ray.instID],Ns); Ns = normalize(Ns); /* calculate diffuse color of geometries */ Vec3fa diffuse = Vec3fa(1,1,1); if (ray.instID != RTC_INVALID_GEOMETRY_ID) diffuse = colors[ray.instID][ray.geomID]; color = color + diffuse*0.5; /* initialize shadow ray */ Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); RTCRay shadow; shadow.org = ray.org + ray.tfar*ray.dir; shadow.dir = neg(lightDir); shadow.tnear = 0.001f; shadow.tfar = (float)(inf); shadow.geomID = 1; shadow.primID = 0; shadow.mask = -1; shadow.time = 0; /* trace shadow ray */ rtcOccluded(g_scene,shadow); RayStats_addShadowRay(stats); /* add light contribution */ if (shadow.geomID) color = color + diffuse*clamp(-dot(lightDir,Ns),0.0f,1.0f); } return color; }
void instanceIntersectFunc(LazyGeometry* instance, RTCRay& ray, size_t item) { /* create the object if it is not yet created */ if (instance->state != LAZY_VALID) lazyCreate(instance); /* trace ray inside object */ const int geomID = ray.geomID; ray.geomID = RTC_INVALID_GEOMETRY_ID; rtcIntersect(instance->object,ray); if (ray.geomID == RTC_INVALID_GEOMETRY_ID) ray.geomID = geomID; else ray.instID = instance->userID; }
void instanceIntersectFunc(const Instance* instance, RTCRay& ray, size_t item) { const Vec3f ray_org = ray.org; const Vec3f ray_dir = ray.dir; const int geomID = ray.geomID; ray.org = xfmPoint (instance->world2local,ray_org); ray.dir = xfmVector(instance->world2local,ray_dir); ray.geomID = RTC_INVALID_GEOMETRY_ID; rtcIntersect(instance->object,ray); ray.org = ray_org; ray.dir = ray_dir; if (ray.geomID == RTC_INVALID_GEOMETRY_ID) ray.geomID = geomID; else ray.instID = instance->userID; }
Vec3fa renderPixelTestEyeLight(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { RandomSampler sampler; RandomSampler_init(sampler, x, y, g_accu_count); x += RandomSampler_get1D(sampler); y += RandomSampler_get1D(sampler); /* initialize ray */ RTCRay2 ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); Vec3fa dir1 = normalize((x+1)*vx + (y+1)*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = 0; Vec3fa color = Vec3fa(0.0f); float weight = 1.0f; rtcIntersect(g_scene,*((RTCRay*)&ray)); ray.filter = nullptr; if (ray.primID == -1) return Vec3fa(0.0f); Vec3fa Ng; ISPCGeometry* geometry = g_ispc_scene->geometries[ray.geomID]; if (geometry->type == HAIR_SET) { const Vec3fa dx = normalize(ray.Ng); const Vec3fa dy = normalize(cross(ray.dir,dx)); const Vec3fa dz = normalize(cross(dy,dx)); Ng = dz; } else { if (dot(ray.dir,ray.Ng) > 0) ray.Ng = neg(ray.Ng); const Vec3fa dz = normalize(ray.Ng); const Vec3fa dx = normalize(cross(dz,ray.dir)); const Vec3fa dy = normalize(cross(dz,dx)); Ng = dz; } color = color + Vec3fa(0.2f + 0.5f * abs(dot(ray.dir,Ng))); return color; }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(int x, int y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(add(mul(x,vx), mul(y,vy), vz)); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.instID = 4; // set default instance ID ray.mask = -1; ray.time = 0; /* intersect ray with scene */ rtcIntersect(g_scene,ray); /* shade pixels */ Vec3f color = Vec3f(0.0f); if (ray.geomID != RTC_INVALID_GEOMETRY_ID) { Vec3f diffuse = Vec3f(0.0f); if (ray.instID == 0) diffuse = colors[ray.instID][ray.primID]; else diffuse = colors[ray.instID][ray.geomID]; color = add(color,mul(diffuse,0.5)); Vec3f lightDir = normalize(Vec3f(-1,-1,-1)); /* initialize shadow ray */ RTCRay shadow; shadow.org = add(ray.org,mul(ray.tfar,ray.dir)); shadow.dir = neg(lightDir); shadow.tnear = 0.001f; shadow.tfar = inf; shadow.geomID = 1; shadow.primID = 0; shadow.mask = -1; shadow.time = 0; /* trace shadow ray */ rtcOccluded(g_scene,shadow); /* add light contribution */ if (shadow.geomID) color = add(color,mul(diffuse,clamp(-dot(lightDir,normalize(ray.Ng)),0.0f,1.0f))); } return color; }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.instID = -1; ray.mask = -1; ray.time = 0; /* intersect ray with scene */ rtcIntersect(g_scene,ray); /* shade pixels */ Vec3fa color = Vec3fa(0.0f); if (ray.geomID != RTC_INVALID_GEOMETRY_ID) { Vec3fa diffuse = Vec3fa(1,1,1); if (ray.instID != -1) diffuse = colors[ray.instID][ray.geomID]; color = color + diffuse*0.5; // FIXME: += Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); /* initialize shadow ray */ RTCRay shadow; shadow.org = ray.org + ray.tfar*ray.dir; shadow.dir = neg(lightDir); shadow.tnear = 0.001f; shadow.tfar = inf; shadow.geomID = 1; shadow.primID = 0; shadow.mask = -1; shadow.time = 0; /* trace shadow ray */ rtcOccluded(g_scene,shadow); /* add light contribution */ if (shadow.geomID) color = color + diffuse*clamp(-dot(lightDir,normalize(ray.Ng)),0.0f,1.0f); // FIXME: += } return color; }
bool SingleRayDevice::rtPick(Device::RTCamera camera_i, float x, float y, Device::RTScene scene_i, float& px, float& py, float& pz) { RT_COMMAND_HEADER; /* extract objects from handles */ Ref<InstanceHandle<Camera> > camera = castHandle<InstanceHandle<Camera> >(camera_i,"camera"); Ref<BackendScene::Handle > scene = castHandle<BackendScene::Handle> (scene_i ,"scene" ); /* trace ray */ Ray ray; camera->getInstance()->ray(Vec2f(x,y), Vec2f(0.5f, 0.5f), ray); //scene->getInstance()->intersector->intersect(ray); rtcIntersect(scene->getInstance()->scene,(RTCRay&)ray); PRINT(ray.id0); Vector3f p = ray.org + ray.tfar * ray.dir; px = p.x; py = p.y; pz = p.z; return (bool)ray; }
Vec3fa renderPixelTestEyeLight(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay2 ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); Vec3fa dir1 = normalize((x+1)*vx + (y+1)*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = 0; Vec3fa color = Vec3fa(0.0f); float weight = 1.0f; rtcIntersect(g_scene,*((RTCRay*)&ray)); // FIXME: use (RTCRay&) cast ray.filter = NULL; if (ray.primID == -1) return Vec3fa(0.0f); Vec3fa Ng; if (ray.geomID < g_ispc_scene->numHairSets) { const Vec3fa dx = normalize(ray.Ng); const Vec3fa dy = normalize(cross(ray.dir,dx)); const Vec3fa dz = normalize(cross(dy,dx)); Ng = dz; } else { if (dot(ray.dir,ray.Ng) > 0) ray.Ng = neg(ray.Ng); const Vec3fa dz = normalize(ray.Ng); const Vec3fa dx = normalize(cross(dz,ray.dir)); const Vec3fa dy = normalize(cross(dz,dx)); Ng = dz; } color = color + Vec3fa(0.2f + 0.5f * abs(dot(ray.dir,Ng))); // FIXME: use += operator return color; }
/* geometry ID and primitive ID shading */ Vec3fa renderPixelGeomIDPrimID(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = 0; /* intersect ray with scene */ rtcIntersect(g_scene,ray); /* shade pixel */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return Vec3fa(0.0f); else return randomColor(ray.geomID ^ ray.primID); }
/* renders a single pixel with eyelight shading */ Vec3fa renderPixelEyeLight(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = g_debug; /* intersect ray with scene */ rtcIntersect(g_scene,ray); /* shade pixel */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return Vec3fa(0.0f); else return Vec3fa(embree::abs(dot(ray.dir,normalize(ray.Ng)))); }
/* vizualizes the traversal cost of a pixel */ Vec3fa renderPixelCycles(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = g_debug; /* intersect ray with scene */ int64_t c0 = get_tsc(); rtcIntersect(g_scene,ray); int64_t c1 = get_tsc(); /* shade pixel */ return Vec3fa((float)(c1-c0)*scale,0.0f,0.0f); }
/* renders a single pixel with UV shading */ Vec3fa renderPixelUV16(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = g_debug; /* intersect ray with scene */ for (int i=0; i<16; i++) { ray.tfar = inf; rtcIntersect(g_scene,ray); } /* shade pixel */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return Vec3fa(0.0f); else return Vec3fa(ray.u,ray.v,1.0f-ray.u-ray.v); }
/* renders a single screen tile */ void renderTileStandard(int taskIndex, int* pixels, const int width, const int height, const float time, const ISPCCamera& camera, const int numTilesX, const int numTilesY) { const int tileY = taskIndex / numTilesX; const int tileX = taskIndex - tileY * numTilesX; const int x0 = tileX * TILE_SIZE_X; const int x1 = min(x0+TILE_SIZE_X,width); const int y0 = tileY * TILE_SIZE_Y; const int y1 = min(y0+TILE_SIZE_Y,height); RTCRay rays[TILE_SIZE_X*TILE_SIZE_Y]; /* generate stream of primary rays */ int N = 0; for (int y=y0; y<y1; y++) for (int x=x0; x<x1; x++) { /* ISPC workaround for mask == 0 */ if (all(1 == 0)) continue; RandomSampler sampler; RandomSampler_init(sampler, x, y, 0); /* initialize ray */ RTCRay& ray = rays[N++]; ray.org = Vec3fa(camera.xfm.p); ray.dir = Vec3fa(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz)); bool mask = 1; { // invalidates inactive rays ray.tnear = mask ? 0.0f : (float)(pos_inf); ray.tfar = mask ? (float)(inf) : (float)(neg_inf); } ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = RandomSampler_get1D(sampler); } RTCIntersectContext context; context.flags = RAYN_FLAGS; /* trace stream of rays */ #if USE_INTERFACE == 0 rtcIntersect1M(g_scene,&context,rays,N,sizeof(RTCRay)); #elif USE_INTERFACE == 1 for (size_t i=0; i<N; i++) rtcIntersect(g_scene,rays[i]); #else for (size_t i=0; i<N; i++) rtcIntersect1M(g_scene,&context,&rays[i],1,sizeof(RTCRay)); #endif /* shade stream of rays */ N = 0; for (int y=y0; y<y1; y++) for (int x=x0; x<x1; x++) { /* ISPC workaround for mask == 0 */ if (all(1 == 0)) continue; RTCRay& ray = rays[N++]; /* eyelight shading */ Vec3fa color = Vec3fa(0.0f); if (ray.geomID != RTC_INVALID_GEOMETRY_ID) //color = Vec3fa(abs(dot(ray.dir,normalize(ray.Ng)))); color = ambientOcclusionShading(x,y,ray); /* write color to framebuffer */ unsigned int r = (unsigned int) (255.0f * clamp(color.x,0.0f,1.0f)); unsigned int g = (unsigned int) (255.0f * clamp(color.y,0.0f,1.0f)); unsigned int b = (unsigned int) (255.0f * clamp(color.z,0.0f,1.0f)); pixels[y*width+x] = (b << 16) + (g << 8) + r; } }
Color vplIntegrator::Li(LightPath& lightPath, const Ref<BackendScene>& scene, IntegratorState& state) { /*! Traverse ray. */ DifferentialGeometry dg; //scene->intersector->intersect(lightPath.lastRay); rtcIntersect(scene->scene,(RTCRay&)lightPath.lastRay); scene->postIntersect(lightPath.lastRay,dg); state.numRays++; Color L = zero; const Vector3f wo = -lightPath.lastRay.dir; BRDFType directLightingBRDFTypes = (BRDFType)(ALL); /*! Environment shading when nothing hit. */ if (!lightPath.lastRay) { if (backplate && lightPath.unbend) { const int x = clamp(int(state.pixel.x * backplate->width ), 0, int(backplate->width )-1); const int y = clamp(int(state.pixel.y * backplate->height), 0, int(backplate->height)-1); L = backplate->get(x, y); } else { if (!lightPath.ignoreVisibleLights) for (size_t i=0; i<scene->envLights.size(); i++) L += scene->envLights[i]->Le(wo); } return L; } /*! face forward normals */ bool backfacing = false; if (dot(dg.Ng, lightPath.lastRay.dir) > 0) { backfacing = true; dg.Ng = -dg.Ng; dg.Ns = -dg.Ns; } /*! Shade surface. */ CompositedBRDF brdfs; if (dg.material) dg.material->shade(lightPath.lastRay, lightPath.lastMedium, dg, brdfs); /*! Add light emitted by hit area light source. */ if (!lightPath.ignoreVisibleLights && dg.light && !backfacing) L += dg.light->Le(dg,wo); /*! Check if any BRDF component uses direct lighting. */ bool useDirectLighting = false; for (size_t i=0; i<brdfs.size(); i++) useDirectLighting |= (brdfs[i]->type & directLightingBRDFTypes) != NONE; /*! Direct lighting. Shoot shadow rays to all light sources. */ if (useDirectLighting) { for (size_t i=0; i<scene->vpls.size(); i++) { LightSample ls; ls.L = scene->vpls[i].sample(dg, ls.wi, ls.tMax); /*! Ignore zero radiance or illumination from the back. */ //if (ls.L == Color(zero) || ls.wi.pdf == 0.0f || dot(dg.Ns,Vector3f(ls.wi)) <= 0.0f) continue; if (ls.L == Color(zero) || ls.wi.pdf == 0.0f) continue; /*! Evaluate BRDF */ Color brdf = brdfs.eval(wo, dg, ls.wi, ALL); if (brdf == Color(zero)) continue; /*! Test for shadows. */ Ray shadowRay(dg.P, ls.wi, dg.error*epsilon, ls.tMax-dg.error*epsilon, lightPath.lastRay.time,dg.shadowMask); TIMESTART(stats.atomic.timeRT,rt0); rtcOccluded(scene->scene,(RTCRay&)shadowRay); TIMESTOP(stats.atomic.timeRT,rt0); state.numRays++; if (shadowRay) continue; /*! Evaluate BRDF. */ L += ls.L * brdf * rcp(ls.wi.pdf); } } return L; }
extern "C" void ispcIntersect1 (RTCScene scene, RTCRay& ray) { rtcIntersect(scene,ray); }
/* renders a single pixel casting with ambient occlusion */ Vec3fa renderPixelAmbientOcclusion(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { /* initialize ray */ RTCRay ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = g_debug; /* intersect ray with scene */ rtcIntersect(g_scene,ray); /* shade pixel */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return Vec3fa(0.0f); Vec3fa Ng = normalize(ray.Ng); Vec3fa col = Vec3fa(min(1.f,.3f+.8f*abs(dot(Ng,normalize(ray.dir))))); /* calculate hit point */ float intensity = 0; Vec3fa hitPos = ray.org + ray.tfar * ray.dir; #define AMBIENT_OCCLUSION_SAMPLES 64 /* trace some ambient occlusion rays */ int seed = 34*x+12*y; for (int i=0; i<AMBIENT_OCCLUSION_SAMPLES; i++) { Vec3fa dir; const float oneOver10000f = 1.f/10000.f; seed = 1103515245 * seed + 12345; dir.x = (seed%10000)*oneOver10000f; seed = 1103515245 * seed + 12345; dir.y = (seed%10000)*oneOver10000f; seed = 1103515245 * seed + 12345; dir.z = (seed%10000)*oneOver10000f; /* initialize shadow ray */ RTCRay shadow; shadow.org = hitPos; shadow.dir = dir; shadow.tnear = 0.001f; shadow.tfar = inf; shadow.geomID = RTC_INVALID_GEOMETRY_ID; shadow.primID = RTC_INVALID_GEOMETRY_ID; shadow.mask = -1; shadow.time = 0; /* trace shadow ray */ rtcOccluded(g_scene,shadow); /* add light contribution */ if (shadow.geomID == RTC_INVALID_GEOMETRY_ID) intensity += 1.0f; } intensity *= 1.0f/AMBIENT_OCCLUSION_SAMPLES; /* shade pixel */ return col * intensity; }
/* task that renders a single screen tile */ Vec3fa renderPixelPathTrace(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { RandomSampler sampler; RandomSampler_init(sampler, x, y, g_accu_count); x += RandomSampler_get1D(sampler); y += RandomSampler_get1D(sampler); float time = RandomSampler_get1D(sampler); /* initialize ray */ RTCRay2 ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = time; ray.filter = nullptr; Vec3fa color = Vec3fa(0.0f); Vec3fa weight = Vec3fa(1.0f); size_t depth = 0; while (true) { /* terminate ray path */ if (reduce_max(weight) < 0.01 || depth > 20) return color; /* intersect ray with scene and gather all hits */ rtcIntersect(g_scene,*((RTCRay*)&ray)); /* exit if we hit environment */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return color + weight*Vec3fa(g_ambient_intensity); /* calculate transmissivity of hair */ AnisotropicBlinn brdf; float tnear_eps = 0.0001f; ISPCGeometry* geometry = g_ispc_scene->geometries[ray.geomID]; if (geometry->type == HAIR_SET) { /* calculate tangent space */ const Vec3fa dx = normalize(ray.Ng); const Vec3fa dy = normalize(cross(ray.dir,dx)); const Vec3fa dz = normalize(cross(dy,dx)); /* generate anisotropic BRDF */ AnisotropicBlinn__Constructor(&brdf,hair_Kr,hair_Kt,dx,20.0f,dy,2.0f,dz); brdf.Kr = hair_Kr; Vec3fa p = evalBezier(ray.geomID,ray.primID,ray.u); tnear_eps = 1.1f*p.w; } else if (geometry->type == TRIANGLE_MESH) { ISPCTriangleMesh* mesh = (ISPCTriangleMesh*) geometry; ISPCTriangle* triangle = &mesh->triangles[ray.primID]; OBJMaterial* material = (OBJMaterial*) &g_ispc_scene->materials[triangle->materialID]; if (dot(ray.dir,ray.Ng) > 0) ray.Ng = neg(ray.Ng); /* calculate tangent space */ const Vec3fa dz = normalize(ray.Ng); const Vec3fa dx = normalize(cross(dz,ray.dir)); const Vec3fa dy = normalize(cross(dz,dx)); /* generate isotropic BRDF */ AnisotropicBlinn__Constructor(&brdf,Vec3fa(1.0f),Vec3fa(0.0f),dx,1.0f,dy,1.0f,dz); } /* sample directional light */ RTCRay2 shadow; shadow.org = ray.org + ray.tfar*ray.dir; shadow.dir = neg(Vec3fa(g_dirlight_direction)); shadow.tnear = tnear_eps; shadow.tfar = inf; shadow.time = time; Vec3fa T = occluded(g_scene,shadow); Vec3fa c = AnisotropicBlinn__eval(&brdf,neg(ray.dir),neg(Vec3fa(g_dirlight_direction))); color = color + weight*c*T*Vec3fa(g_dirlight_intensity); #if 1 /* sample BRDF */ Vec3fa wi; float ru = RandomSampler_get1D(sampler); float rv = RandomSampler_get1D(sampler); float rw = RandomSampler_get1D(sampler); c = AnisotropicBlinn__sample(&brdf,neg(ray.dir),wi,ru,rv,rw); if (wi.w <= 0.0f) return color; /* calculate secondary ray and offset it out of the hair */ float sign = dot(Vec3fa(wi),brdf.dz) < 0.0f ? -1.0f : 1.0f; ray.org = ray.org + ray.tfar*ray.dir + sign*tnear_eps*brdf.dz; ray.dir = Vec3fa(wi); ray.tnear = 0.001f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = time; ray.filter = nullptr; weight = weight * c/wi.w; #else /* continue with transparency ray */ ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.tnear = 1.001f*ray.tfar; ray.tfar = inf; weight *= brdf.Kt; #endif depth++; } return color; }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(float x, float y, const ISPCCamera& camera, RayStats& stats) { float weight = 1.0f; Vec3fa color = Vec3fa(0.0f); /* initialize ray */ RTCRay2 primary; primary.org = Vec3fa(camera.xfm.p); primary.dir = Vec3fa(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz)); primary.tnear = 0.0f; primary.tfar = (float)(inf); primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.mask = -1; primary.time = 0; primary.transparency = 0.0f; while (true) { /* intersect ray with scene */ rtcIntersect(g_scene,*((RTCRay*)&primary)); RayStats_addRay(stats); /* shade pixels */ if (primary.geomID == RTC_INVALID_GEOMETRY_ID) break; float opacity = 1.0f-primary.transparency; Vec3fa diffuse = colors[primary.primID]; Vec3fa La = diffuse*0.5f; color = color + weight*opacity*La; Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); /* initialize shadow ray */ RTCRay2 shadow; shadow.org = primary.org + primary.tfar*primary.dir; shadow.dir = neg(lightDir); shadow.tnear = 0.001f; shadow.tfar = (float)(inf); shadow.geomID = RTC_INVALID_GEOMETRY_ID; shadow.primID = RTC_INVALID_GEOMETRY_ID; shadow.mask = -1; shadow.time = 0; shadow.transparency = 1.0f; shadow.firstHit = 0; shadow.lastHit = 0; /* trace shadow ray */ rtcOccluded(g_scene,*((RTCRay*)&shadow)); RayStats_addShadowRay(stats); /* add light contribution */ if (shadow.geomID) { Vec3fa Ll = diffuse*shadow.transparency*clamp(-dot(lightDir,normalize(primary.Ng)),0.0f,1.0f); color = color + weight*opacity*Ll; } /* shoot transmission ray */ weight *= primary.transparency; primary.tnear = 1.001f*primary.tfar; primary.tfar = (float)(inf); primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.transparency = 0.0f; } return color; }
void BackendScene::generateVPL( size_t vplNum, const char* vplFile,size_t vpldepth ) { this->vpls.clear(); SET_CLAMPING_DISTANCE( 0.05 * sceneradius ); //------------------------- READ FILE IF IT DOES EXIST-------------------------------------- if( strcmp(vplFile,"")){ FILE *ptr; ptr = fopen(vplFile,"rb"); if (ptr) { size_t siz; fread(&siz,sizeof(size_t),1,ptr); vpls.resize(siz); for (size_t i = 0 ; i<siz; ++i) vpls[i].read(ptr); fclose(ptr); std::cout << "Vpl file read. Total # of vpls:"<< vpls.size()<<std::endl; return; } else std::cout << "Unable to read vpl file."<< std::endl; } //------------------------- OTHERWISE GENERATE VPLS-------------------------------------- Random rnd(RND_SEED); // Place VPLs that substitute the original lights (direct VPLs) std::vector<Ref<Light> >::iterator it = allLights.begin(); for ( ; it !=allLights.end(); ++it) { // Replace TriangleLight if( (*it).dynamicCast<TriangleLight>() ) { Ref<TriangleLight> tr = (*it).dynamicCast<TriangleLight>(); Color I = tr->L * length(cross(tr->e1,tr->e2)) * 0.5; int triangleSamples = 1024; // HACK to avoid too many VPLs for many quads... if (allLights.size() > 2000) triangleSamples = 100; for (int i=0 ; i < triangleSamples ; ++i) { Vector3f pos = uniformSampleTriangle(rnd.getFloat(),rnd.getFloat(),tr->v0,tr->v1,tr->v2); this->vpls.push_back(vplVPL(pos, -tr->Ng, I * rcp((float)triangleSamples) ) ); } } // Replace SpotLight else if ((*it).dynamicCast<SpotLight>()) { Ref<SpotLight> sl = (*it).dynamicCast<SpotLight>(); if ( sl->cosAngleMax >= 0.05 || sl->cosAngleMin <= 0.95 ) throw std::runtime_error("Not supporting spotlights with other than 90 degree falloff for VPL generation."); this->vpls.push_back(vplVPL(sl->P,sl->_D,sl->I)); } // Replace environment map else if ((*it).dynamicCast<HDRILight>()) { Ref<HDRILight> hd = (*it).dynamicCast<HDRILight>(); int envmapSamples = 32768; float dirlightdistance = DIR_LIGHT_DISTANCE; for (int i=0 ; i < envmapSamples ; ++i) { Vector3f pos(uniformSampleSphere(rnd.getFloat(),rnd.getFloat())); Vector3f dir = -pos; pos *= dirlightdistance; pos += scenecenter; // CHECK below line later it is not completely precise Color I = hd->Le(-dir) * four_pi * rcp((float)envmapSamples) * dirlightdistance * dirlightdistance; this->vpls.push_back(vplVPL(pos, -dir , I )); } } else if ((*it).dynamicCast<DirectionalLight>()) { Ref<DirectionalLight> sl = (*it).dynamicCast<DirectionalLight>(); float distance = 100000; this->vpls.push_back(vplVPL(sl->_wo*distance,sl->_wo,sl->E*distance*distance)); } else throw std::runtime_error("Not supported light type for VPL generation."); } // Place VPLs (indirect VPLs) size_t direct = this->vpls.size(); size_t orig = this->allLights.size(); if (vpldepth <=1) return; while (this->vpls.size() < (vplNum+direct)) { // Sample orig lights for photons Ref<Light> vp = this->allLights[rnd.getInt(orig)]; Vector3f pos; Sample3f dir; Vec2f vr(rnd.getFloat(),rnd.getFloat()); Vec2f vs(rnd.getFloat(),rnd.getFloat()); Color I = vp->samplePhoton(dir,pos,vr,vs,sceneradius,scenecenter); if (dir.pdf==0.0f) continue; I *= (float) orig * rcp(dir.pdf); // Generate a path for the photon and add VPLs int maxdepth = int(vpldepth) - 1; // -1 because 1 for pt means only direct light while ( maxdepth-- && (I != zero ) ) { Ray ray (pos,dir,32*std::numeric_limits<float>::epsilon(), inf); DifferentialGeometry dg; rtcIntersect(this->scene,(RTCRay&)ray); this->postIntersect(ray,dg); if (!ray)//nothing is hit break; /*! face forward normals */ if (dot(dg.Ng, ray.dir) > 0) { dg.Ng = -dg.Ng; dg.Ns = -dg.Ns; } CompositedBRDF brdfs; if (dg.material) dg.material->shade(ray, Medium::Vacuum(), dg, brdfs); BRDFType diffuseBRDFTypes = (BRDFType)(DIFFUSE); Vec2f s = Vec2f(rnd.getFloat(),rnd.getFloat()); Color c = brdfs.sample(-ray.dir,dg, dir,diffuseBRDFTypes,s,rnd.getFloat(),diffuseBRDFTypes); if (c==zero || dir.pdf==0.0f) break; // the dot prod should not be zero since then c would be zero float dott = dot(dir,dg.Ns); if (dott==0.0f) break; Color contrib = I * c * rcp(dott) * rcp((float)vplNum) ; //if (std::isnan(contrib.r) || std::isnan(contrib.g) || std::isnan(contrib.b)) // break; this->vpls.push_back(vplVPL(dg.P,-dg.Ns,contrib)); Color contribScale = c * rcp(dir.pdf); float rrProb = min(1.0f, reduce_avg(contribScale)); if(rrProb == 0.0f)break; if (rnd.getFloat() > rrProb) break; I *= contribScale * rcp(rrProb); pos = dg.P; } } //------------------------------PERTURB VPLS WITH THE SAME POSITION----------------------------------------------------------- auto vplComp = [] (const vplVPL& vp1,const vplVPL& vp2) { return vp1.P < vp2.P; }; std::sort(this->vpls.begin(),this->vpls.end(),vplComp); std::vector<vplVPL>::iterator itt = this->vpls.begin(); while(itt != ( vpls.end() - 1 ) && itt != vpls.end()) { vplVPL& v1 = *itt, & v2 = *(itt+1); if(v1.P == v2.P) { v2.I += v1.I; itt = this->vpls.erase(itt); } else ++itt; } //------------------------------WRITE OUT VPLS INTO A FILE----------------------------------------------------------- // writing out the VPLs FILE *ptr; ptr = fopen(vplFile,"wb"); if (ptr) { size_t siz = this->vpls.size(); fwrite(&siz,sizeof(size_t),1,ptr); if (vpls.size()) for (size_t i = 0 ; i<siz; ++i) vpls[i].write(ptr); fclose(ptr); std::cout << "Vpl file written. Total # of vpls:"<< vpls.size()<<std::endl; } else std::cout << "Unable to write vpl file. Total # of vpls: "<<vpls.size() << std::endl; return; }
/* task that renders a single screen tile */ Vec3fa renderPixelPathTrace(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { int seed = 21344*x+121233*y+234532*g_accu_count; float time = frand(seed); /* initialize ray */ RTCRay2 ray; ray.org = p; ray.dir = normalize(x*vx + y*vy + vz); ray.tnear = 0.0f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = time; ray.filter = NULL; Vec3fa color = Vec3fa(0.0f); Vec3fa weight = Vec3fa(1.0f); size_t depth = 0; while (true) { /* terminate ray path */ if (reduce_max(weight) < 0.01 || depth > 20) return color; /* intersect ray with scene and gather all hits */ rtcIntersect(g_scene,*((RTCRay*)&ray)); // FIXME: use (RTCRay&) cast /* exit if we hit environment */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) return color + weight*Vec3fa(g_ambient_intensity); /* calculate transmissivity of hair */ AnisotropicBlinn brdf; float tnear_eps = 0.0001f; if (ray.geomID < g_ispc_scene->numHairSets) { /* calculate tangent space */ const Vec3fa dx = normalize(ray.Ng); const Vec3fa dy = normalize(cross(ray.dir,dx)); const Vec3fa dz = normalize(cross(dy,dx)); /* generate anisotropic BRDF */ AnisotropicBlinn__Constructor(&brdf,hair_Kr,hair_Kt,dx,20.0f,dy,2.0f,dz); brdf.Kr = hair_Kr; Vec3fa p = evalBezier(ray.geomID,ray.primID,ray.u); tnear_eps = 1.1f*p.w; } else { int meshID = ray.geomID-g_ispc_scene->numHairSets; ISPCMesh* mesh = g_ispc_scene->meshes[meshID]; ISPCTriangle* triangle = &mesh->triangles[ray.primID]; ISPCMaterial* material = &g_ispc_scene->materials[triangle->materialID]; if (material->illum == 1) { /* calculate tangent space */ const Vec3fa dx = normalize(Vec3fa(mesh->normals[triangle->v0])); const Vec3fa dy = normalize(cross(ray.dir,dx)); const Vec3fa dz = normalize(cross(dy,dx)); /* generate anisotropic BRDF */ AnisotropicBlinn__Constructor(&brdf,hair_Kr,hair_Kt,dx,20.0f,dy,2.0f,dz); brdf.Kr = hair_Kr; tnear_eps = 1.1f*mesh->texcoords[triangle->v0].x; } else { if (dot(ray.dir,ray.Ng) > 0) ray.Ng = neg(ray.Ng); /* calculate tangent space */ const Vec3fa dz = normalize(ray.Ng); const Vec3fa dx = normalize(cross(dz,ray.dir)); const Vec3fa dy = normalize(cross(dz,dx)); /* generate isotropic BRDF */ AnisotropicBlinn__Constructor(&brdf,Vec3fa(1.0f),Vec3fa(0.0f),dx,1.0f,dy,1.0f,dz); } } /* sample directional light */ RTCRay2 shadow; shadow.org = ray.org + ray.tfar*ray.dir; shadow.dir = neg(Vec3fa(g_dirlight_direction)); shadow.tnear = tnear_eps; shadow.tfar = inf; shadow.time = time; Vec3fa T = occluded(g_scene,shadow); Vec3fa c = AnisotropicBlinn__eval(&brdf,neg(ray.dir),neg(Vec3fa(g_dirlight_direction))); color = color + weight*c*T*Vec3fa(g_dirlight_intensity); // FIXME: use += operator #if 1 /* sample BRDF */ Vec3fa wi; c = AnisotropicBlinn__sample(&brdf,neg(ray.dir),wi,frand(seed),frand(seed),frand(seed)); if (wi.w <= 0.0f) return color; /* calculate secondary ray and offset it out of the hair */ float sign = dot(Vec3fa(wi),brdf.dz) < 0.0f ? -1.0f : 1.0f; ray.org = ray.org + ray.tfar*ray.dir + sign*tnear_eps*brdf.dz; ray.dir = Vec3fa(wi); ray.tnear = 0.001f; ray.tfar = inf; ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.primID = RTC_INVALID_GEOMETRY_ID; ray.mask = -1; ray.time = time; ray.filter = NULL; weight = weight * c/wi.w; // FIXME: use *= operator #else /* continue with transparency ray */ ray.geomID = RTC_INVALID_GEOMETRY_ID; ray.tnear = 1.001f*ray.tfar; ray.tfar = inf; weight *= brdf.Kt; #endif depth++; } return color; }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(float x, float y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { float weight = 1.0f; Vec3f color = Vec3f(0.0f); /* initialize ray */ RTCRay2 primary; primary.org = p; primary.dir = normalize(x*vx + y*vy + vz); primary.tnear = 0.0f; primary.tfar = inf; primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.mask = -1; primary.time = 0; primary.transparency = 0.0f; while (true) { /* intersect ray with scene */ rtcIntersect(g_scene,*((RTCRay*)&primary)); // FIXME: use (RTCRay&) cast /* shade pixels */ if (primary.geomID == RTC_INVALID_GEOMETRY_ID) break; float opacity = 1.0f-primary.transparency; Vec3f diffuse = colors[primary.primID]; Vec3f La = diffuse*0.5f; color = color + weight*opacity*La; // FIXME: += Vec3f lightDir = normalize(Vec3f(-1,-1,-1)); /* initialize shadow ray */ RTCRay2 shadow; shadow.org = primary.org + primary.tfar*primary.dir; shadow.dir = neg(lightDir); shadow.tnear = 0.001f; shadow.tfar = inf; shadow.geomID = RTC_INVALID_GEOMETRY_ID; shadow.primID = RTC_INVALID_GEOMETRY_ID; shadow.mask = -1; shadow.time = 0; shadow.transparency = 1.0f; /* trace shadow ray */ rtcOccluded(g_scene,*((RTCRay*)&shadow)); // FIXME: use (RTCRay&) cast /* add light contribution */ if (shadow.geomID) { Vec3f Ll = diffuse*shadow.transparency*clamp(-dot(lightDir,normalize(primary.Ng)),0.0f,1.0f); color = color + weight*opacity*Ll; // FIXME: += } /* shoot transmission ray */ weight *= primary.transparency; primary.tnear = 1.001f*primary.tfar; primary.tfar = inf; primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.transparency = 0.0f; } return color; }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(int x, int y, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p) { float weight = 1.0f; Vec3f color = Vec3f(0.0f); /* initialize ray */ RTCRay2 primary; primary.org = p; primary.dir = normalize(add(mul(x,vx), mul(y,vy), vz)); primary.tnear = 0.0f; primary.tfar = inf; primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.mask = -1; primary.time = 0; primary.transparency = 0.0f; while (true) { /* intersect ray with scene */ rtcIntersect(g_scene,*((RTCRay*)&primary)); /* shade pixels */ if (primary.geomID == RTC_INVALID_GEOMETRY_ID) break; float opacity = 1.0f-primary.transparency; Vec3f diffuse = colors[primary.primID]; Vec3f La = mul(diffuse,0.5f); color = add(color,mul(weight*opacity,La)); Vec3f lightDir = normalize(Vec3f(-1,-1,-1)); /* initialize shadow ray */ RTCRay2 shadow; shadow.org = add(primary.org,mul(primary.tfar,primary.dir)); shadow.dir = neg(lightDir); shadow.tnear = 0.001f; shadow.tfar = inf; shadow.geomID = RTC_INVALID_GEOMETRY_ID; shadow.primID = RTC_INVALID_GEOMETRY_ID; shadow.mask = -1; shadow.time = 0; shadow.transparency = 1.0f; /* trace shadow ray */ rtcOccluded(g_scene,*((RTCRay*)&shadow)); /* add light contribution */ if (shadow.geomID) { Vec3f Ll = mul(diffuse,shadow.transparency*clamp(-dot(lightDir,normalize(primary.Ng)),0.0f,1.0f)); color = add(color,mul(weight*opacity,Ll)); } /* shoot transmission ray */ weight *= primary.transparency; primary.tnear = 1.001f*primary.tfar; primary.tfar = inf; primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.transparency = 0.0f; } return color; }