/* main function in embree namespace */ int main(int argc, char** argv) { /* for best performance set FTZ and DAZ flags in MXCSR control and status register */ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); /* set default camera */ g_camera.from = Vec3fa(2.5f,2.5f,2.5f); g_camera.to = Vec3fa(0.0f,0.0f,0.0f); /* create stream for parsing */ Ref<ParseStream> stream = new ParseStream(new CommandLineStream(argc, argv)); /* parse command line */ parseCommandLine(stream, FileName()); if (g_numThreads) g_rtcore += ",threads=" + toString(g_numThreads); /* initialize ray tracing core */ init(g_rtcore.c_str()); /* render to disk */ if (outFilename.str() != "") { renderToFile(outFilename); return 0; } /* initialize GLUT */ initWindowState(argc,argv,tutorialName, g_width, g_height, g_fullscreen); /* enter the GLUT run loop */ enterWindowRunLoop(); return 0; }
void main(int argc, char **argv) { std::cout << " === Possible cmd line options: -lazy, -pregenerate, -cache === " << std::endl; /* set default camera */ g_camera.from = Vec3fa(1.5f,1.5f,-1.5f); g_camera.to = Vec3fa(0.0f,0.0f,0.0f); /*! Parse command line options. */ parseCommandLine(new ParseStream(new CommandLineStream(argc, argv)), FileName()); /*! Set the thread count in the Embree configuration string. */ if (g_numThreads) g_rtcore += ",threads=" + std::stringOf(g_numThreads); g_rtcore += g_subdiv_mode; /*! Initialize the task scheduler. */ #if !defined(RTCORE_EXPORT_ALL_SYMBOLS) TaskScheduler::create(g_numThreads); #endif /*! Initialize Embree state. */ init(g_rtcore.c_str()); /* render to disk */ if (outFilename.str() != "") renderToFile(outFilename); /* interactive mode */ if (g_interactive) { initWindowState(argc,argv,tutorialName, g_width, g_height, g_fullscreen); enterWindowRunLoop(); } }
/* main function in embree namespace */ int main(int argc, char** argv) { /* for best performance set FTZ and DAZ flags in MXCSR control and status register */ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); /* initialize ray tracing core and force bvh4.triangle4v hierarchy for triangles */ rtcInit("tri_accel=bvh4.triangle4v"); /* set error handler */ rtcSetErrorFunction(error_handler); /* create scene */ g_scene = rtcNewScene(RTC_SCENE_STATIC,RTC_INTERSECT1); addCube(g_scene,Vec3fa(-1,0,0)); addCube(g_scene,Vec3fa(1,0,0)); addCube(g_scene,Vec3fa(0,0,-1)); addCube(g_scene,Vec3fa(0,0,1)); addHair(g_scene); addGroundPlane(g_scene); rtcCommit (g_scene); /* print triangle BVH */ print_bvh(g_scene); /* cleanup */ rtcDeleteScene (g_scene); rtcExit(); return 0; }
/* called by the C++ code for initialization */ extern "C" void device_init (char* cfg) { /* create scene */ g_scene = rtcNewScene(g_device); rtcSetSceneFlags(g_scene,RTC_SCENE_FLAG_DYNAMIC | RTC_SCENE_FLAG_ROBUST); rtcSetSceneBuildQuality(g_scene,RTC_BUILD_QUALITY_LOW); /* create some triangulated spheres */ for (int i=0; i<numSpheres; i++) { const float phi = i*2.0f*float(pi)/numSpheres; const float r = 2.0f*float(pi)/numSpheres; const Vec3fa p = 2.0f*Vec3fa(sin(phi),0.0f,-cos(phi)); //RTCBuildQuality quality = i%3 == 0 ? RTC_BUILD_QUALITY_MEDIUM : i%3 == 1 ? RTC_BUILD_QUALITY_REFIT : RTC_BUILD_QUALITY_LOW; RTCBuildQuality quality = i%2 ? RTC_BUILD_QUALITY_REFIT : RTC_BUILD_QUALITY_LOW; //RTCBuildQuality quality = RTC_BUILD_QUALITY_REFIT; int id = createSphere(quality,p,r); position[id] = p; radius[id] = r; colors[id].x = (i%16+1)/17.0f; colors[id].y = (i%8+1)/9.0f; colors[id].z = (i%4+1)/5.0f; } /* add ground plane to scene */ int id = addGroundPlane(g_scene); colors[id] = Vec3fa(1.0f,1.0f,1.0f); /* commit changes to scene */ rtcCommitScene (g_scene); /* set start render mode */ renderTile = renderTileStandard; key_pressed_handler = device_key_pressed_default; }
Tutorial() : TutorialApplication("displacement_geometry",FEATURE_RTCORE) { /* set default camera */ camera.from = Vec3fa(1.5f,1.5f,-1.5f); camera.to = Vec3fa(0.0f,0.0f,0.0f); }
Tutorial() : TutorialApplication("intersection_filter",FEATURE_RTCORE) { /* set default camera */ camera.from = Vec3fa(2.5f,2.5f,2.5f); camera.to = Vec3fa(0.0f,0.0f,0.0f); }
static __forceinline bool occluded_vec3f(const Ray& ray, const Triangle1& tri, const void* geom) { /* load triangle */ STAT3(shadow.trav_prims,1,1,1); const Vec3f tri_v0 = tri.v0; const Vec3f tri_v1 = tri.v1; const Vec3f tri_v2 = tri.v2; const Vec3f tri_Ng = tri.Ng; /* calculate denominator */ const Vec3f O = Vec3fa(ray.org); const Vec3f D = Vec3fa(ray.dir); const Vec3f C = tri_v0 - O; const Vec3f R = cross(D,C); const float den = dot(tri_Ng,D); const float absDen = abs(den); const float sgnDen = den < 0.0f ? -1.0f : 1.0f; const Vec3fa e1 = tri_v0-tri_v1; const Vec3fa e2 = tri_v2-tri_v0; /* perform edge tests */ const float U = dot(R,e2) * sgnDen; if (unlikely(U < 0.0f)) return false; const float V = dot(R,e1) * sgnDen; if (unlikely(V < 0.0f)) return false; const float W = absDen-U-V; if (unlikely(W < 0.0f)) return false; /* perform depth test */ const float T = dot(tri_Ng,C) * sgnDen; if (unlikely(absDen*ray.tfar < T)) return false; if (unlikely(T < absDen*ray.tnear)) return false; return true; }
Ref<SceneGraph::Node> geometry() { OBJMaterial material(1.0f,Vec3fa(1.0f),Vec3fa(0.0f),1.0f); Ref<SceneGraph::MaterialNode> mnode = new SceneGraph::MaterialNode((Material&)material); Ref<SceneGraph::TriangleMeshNode> mesh = new SceneGraph::TriangleMeshNode(mnode); const size_t width = texture->width; const size_t height = texture->height; mesh->v.resize(height*width); for (size_t y=0; y<height; y++) for (size_t x=0; x<width; x++) mesh->v[y*width+x] = at(x,y); mesh->triangles.resize(2*(height-1)*(width-1)); for (size_t y=0; y<height-1; y++) { for (size_t x=0; x<width-1; x++) { const size_t p00 = (y+0)*width+(x+0); const size_t p01 = (y+0)*width+(x+1); const size_t p10 = (y+1)*width+(x+0); const size_t p11 = (y+1)*width+(x+1); const size_t tri = y*(width-1)+x; mesh->triangles[2*tri+0] = SceneGraph::TriangleMeshNode::Triangle(p00,p01,p10); mesh->triangles[2*tri+1] = SceneGraph::TriangleMeshNode::Triangle(p01,p11,p10); } } return mesh.dynamicCast<SceneGraph::Node>(); }
/* called by the C++ code for initialization */ extern "C" void device_init (int8* cfg) { /* initialize ray tracing core */ rtcInit(cfg); /* set error handler */ rtcSetErrorFunction(error_handler); /* set start render mode */ renderPixel = renderPixelStandard; /* create random bounding boxes */ const size_t N = 2300000; isa::PrimInfo pinfo(empty); vector_t<PrimRef> prims; for (size_t i=0; i<N; i++) { const Vec3fa p = 1000.0f*Vec3fa(drand48(),drand48(),drand48()); const BBox3fa b = BBox3fa(p,p+Vec3fa(1.0f)); pinfo.add(b); const PrimRef prim = PrimRef(b,i); prims.push_back(prim); } build_sah(prims,pinfo); build_morton(prims,pinfo); }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(float x, float y, const ISPCCamera& camera, RayStats& stats) { /* initialize ray */ Ray ray(Vec3fa(camera.xfm.p), Vec3fa(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz)), 0.0f, inf); /* intersect ray with scene */ RTCIntersectContext context; rtcInitIntersectContext(&context); rtcIntersect1(g_scene,&context,RTCRayHit_(ray)); RayStats_addRay(stats); /* shade pixels */ Vec3fa color = Vec3fa(0.0f); if (ray.geomID != RTC_INVALID_GEOMETRY_ID) { Vec3fa diffuse = colors[ray.geomID]; color = color + diffuse*0.1f; Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); /* initialize shadow ray */ Ray shadow(ray.org + ray.tfar*ray.dir, neg(lightDir), 0.001f, inf); /* trace shadow ray */ rtcOccluded1(g_scene,&context,RTCRay_(shadow)); RayStats_addShadowRay(stats); /* add light contribution */ if (shadow.tfar >= 0.0f) color = color + diffuse*clamp(-dot(lightDir,normalize(ray.Ng)),0.0f,1.0f); } return color; }
int main(int argc, char **argv) { /* for best performance set FTZ and DAZ flags in MXCSR control and status register */ _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); std::cout << " === Possible cmd line options: -pregenerate, -cache === " << std::endl; /* set default camera */ g_camera.from = Vec3fa(1.5f,1.5f,-1.5f); g_camera.to = Vec3fa(0.0f,0.0f,0.0f); /*! Parse command line options. */ parseCommandLine(new ParseStream(new CommandLineStream(argc, argv)), FileName()); /*! Set the thread count in the Embree configuration string. */ if (g_numThreads) g_rtcore += ",threads=" + std::to_string((long long)g_numThreads); g_rtcore += g_subdiv_mode; /*! Initialize Embree state. */ init(g_rtcore.c_str()); /* render to disk */ if (outFilename.str() != "") renderToFile(outFilename); /* interactive mode */ if (g_interactive) { initWindowState(argc,argv,tutorialName, g_width, g_height, g_fullscreen); enterWindowRunLoop(); } return 0; }
/* intersection filter function */ void intersectionFilterN(int* valid, void* ptr, const RTCIntersectContext* context, RTCRayN* ray, const RTCHitN* potentialHit, const size_t N) { /* avoid crashing when debug visualizations are used */ if (context == nullptr) return; /* iterate over all rays in ray packet */ for (unsigned int ui=0; ui<N; ui+=1) { /* calculate loop and execution mask */ unsigned int vi = ui+0; if (vi>=N) continue; /* ignore inactive rays */ if (valid[vi] != -1) continue; /* read ray from ray structure */ Vec3fa ray_org = Vec3fa(RTCRayN_org_x(ray,N,ui),RTCRayN_org_y(ray,N,ui),RTCRayN_org_z(ray,N,ui)); Vec3fa ray_dir = Vec3fa(RTCRayN_dir_x(ray,N,ui),RTCRayN_dir_y(ray,N,ui),RTCRayN_dir_z(ray,N,ui)); unsigned ray_mask = RTCRayN_mask(ray,N,ui); float hit_t = RTCHitN_t(potentialHit,N,ui); /* decode ray IDs */ int pid = (ray_mask & 0xFFFF) / 1; int rid = (ray_mask & 0xFFFF) % 1; /* calculate transparency */ Vec3fa h = ray_org + ray_dir*hit_t; float T = transparencyFunction(h); /* ignore hit if completely transparent */ if (T >= 1.0f) valid[vi] = 0; /* otherwise accept hit and remember transparency */ else { RTCRayN_instID(ray,N,ui) = RTCHitN_instID(potentialHit,N,ui); RTCRayN_geomID(ray,N,ui) = RTCHitN_geomID(potentialHit,N,ui); RTCRayN_primID(ray,N,ui) = RTCHitN_primID(potentialHit,N,ui); RTCRayN_u(ray,N,ui) = RTCHitN_u(potentialHit,N,ui); RTCRayN_v(ray,N,ui) = RTCHitN_v(potentialHit,N,ui); RTCRayN_tfar(ray,N,ui) = RTCHitN_t(potentialHit,N,ui); RTCRayN_Ng_x(ray,N,ui) = RTCHitN_Ng_x(potentialHit,N,ui); RTCRayN_Ng_y(ray,N,ui) = RTCHitN_Ng_y(potentialHit,N,ui); RTCRayN_Ng_z(ray,N,ui) = RTCHitN_Ng_z(potentialHit,N,ui); if (context) { RTCRay2* eray = (RTCRay2*) context->userRayExt; scatter(eray->transparency,sizeof(RTCRay2),pid,rid,T); } } } }
/* called by the C++ code for initialization */ extern "C" void device_init (char* cfg) { /* create new Embree device */ g_device = rtcNewDevice(cfg); error_handler(nullptr,rtcDeviceGetError(g_device)); /* set error handler */ rtcDeviceSetErrorFunction2(g_device,error_handler,nullptr); /* create scene */ RTCAlgorithmFlags aflags; if (g_mode == MODE_NORMAL) aflags = RTC_INTERSECT1; else aflags = RTC_INTERSECT1 | RTC_INTERSECT_STREAM; g_scene = rtcDeviceNewScene(g_device, RTC_SCENE_STATIC | RTC_SCENE_HIGH_QUALITY,aflags); /* add cube */ addCube(g_scene,Vec3fa(0.0f,0.0f,0.0f),Vec3fa(10.0f,1.0f,1.0f),45.0f); //addSubdivCube(g_scene); /* add ground plane */ addGroundPlane(g_scene); /* commit changes to scene */ rtcCommit (g_scene); /* set start render mode */ if (g_mode == MODE_NORMAL) renderTile = renderTileStandard; else renderTile = renderTileStandardStream; key_pressed_handler = device_key_pressed_default; }
/* main function in embree namespace */ int main(int argc, char** argv) { /* set default camera */ g_camera.from = Vec3fa(2.5f,2.5f,2.5f); g_camera.to = Vec3fa(0.0f,0.0f,0.0f); /* create stream for parsing */ Ref<ParseStream> stream = new ParseStream(new CommandLineStream(argc, argv)); /* parse command line */ parseCommandLine(stream, FileName()); if (g_numThreads) g_rtcore += ",threads=" + std::stringOf(g_numThreads); /* initialize ray tracing core */ init(g_rtcore.c_str()); /* render to disk */ if (outFilename.str() != "") { renderToFile(outFilename); return 0; } /* initialize GLUT */ initWindowState(argc,argv,tutorialName, g_width, g_height, g_fullscreen); /* enter the GLUT run loop */ enterWindowRunLoop(); return 0; }
/* called by the C++ code for initialization */ extern "C" void device_init (char* cfg) { /* create new Embree device */ g_device = rtcNewDevice(cfg); error_handler(rtcDeviceGetError(g_device)); /* set error handler */ rtcDeviceSetErrorFunction(g_device,error_handler); /* set start render mode */ renderTile = renderTileStandard; /* create random bounding boxes */ const size_t N = 2300000; isa::PrimInfo pinfo(empty); avector<PrimRef> prims; for (size_t i=0; i<N; i++) { const float x = float(drand48()); const float y = float(drand48()); const float z = float(drand48()); const Vec3fa p = 1000.0f*Vec3fa(x,y,z); const BBox3fa b = BBox3fa(p,p+Vec3fa(1.0f)); pinfo.add(b); const PrimRef prim = PrimRef(b,i); prims.push_back(prim); } build_sah(prims,pinfo); build_morton(prims,pinfo); }
/* 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; }
/* 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 sampler */ RandomSampler sampler; RandomSampler_init(sampler, (int)x, (int)y, 0); /* initialize ray */ Ray ray(Vec3fa(camera.xfm.p), Vec3fa(normalize(x*camera.xfm.l.vx + y*camera.xfm.l.vy + camera.xfm.l.vz)), 0.0f, inf, RandomSampler_get1D(sampler)); /* intersect ray with scene */ RTCIntersectContext context; rtcInitIntersectContext(&context); context.flags = g_iflags_coherent; rtcIntersect1(g_scene,&context,RTCRayHit_(ray)); RayStats_addRay(stats); /* shade background black */ if (ray.geomID == RTC_INVALID_GEOMETRY_ID) { return Vec3fa(0.0f); } /* shade all rays that hit something */ Vec3fa color = Vec3fa(0.5f); /* compute differential geometry */ DifferentialGeometry dg; dg.geomID = ray.geomID; dg.primID = ray.primID; dg.u = ray.u; dg.v = ray.v; dg.P = ray.org+ray.tfar*ray.dir; dg.Ng = ray.Ng; dg.Ns = ray.Ng; if (g_use_smooth_normals) if (ray.geomID != RTC_INVALID_GEOMETRY_ID) // FIXME: workaround for ISPC bug, location reached with empty execution mask { Vec3fa dPdu,dPdv; unsigned int geomID = ray.geomID; { rtcInterpolate1(rtcGetGeometry(g_scene,geomID),ray.primID,ray.u,ray.v,RTC_BUFFER_TYPE_VERTEX,0,nullptr,&dPdu.x,&dPdv.x,3); } dg.Ns = cross(dPdv,dPdu); } int materialID = postIntersect(ray,dg); dg.Ng = face_forward(ray.dir,normalize(dg.Ng)); dg.Ns = face_forward(ray.dir,normalize(dg.Ns)); /* shade */ if (g_ispc_scene->materials[materialID]->type == MATERIAL_OBJ) { ISPCOBJMaterial* material = (ISPCOBJMaterial*) g_ispc_scene->materials[materialID]; color = Vec3fa(material->Kd); } return color*dot(neg(ray.dir),dg.Ns); }
/* 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; }
//! Create an ispc-side PointLight object extern "C" void* PointLight_create() { PointLight* self = (PointLight*) alignedMalloc(sizeof(PointLight),16); Light_Constructor(&self->super); self->super.sample = PointLight_sample; self->super.eval = PointLight_eval; PointLight_set(self, Vec3fa(0.f), Vec3fa(1.f), 0.f); return self; }
//! Create an ispc-side DirectionalLight object extern "C" void* DirectionalLight_create() { DirectionalLight* self = (DirectionalLight*) alignedMalloc(sizeof(DirectionalLight)); Light_Constructor(&self->super); self->super.sample = DirectionalLight_sample; self->super.eval = DirectionalLight_eval; DirectionalLight_set(self, Vec3fa(0.f, 0.f, 1.f), Vec3fa(1.f), 1.f); return self; }
void instanceBoundsFunc(const LazyGeometry* instance, size_t item, RTCBounds* bounds_o) { Vec3fa lower = instance->center-Vec3fa(instance->radius); Vec3fa upper = instance->center+Vec3fa(instance->radius); bounds_o->lower_x = lower.x; bounds_o->lower_y = lower.y; bounds_o->lower_z = lower.z; bounds_o->upper_x = upper.x; bounds_o->upper_y = upper.y; bounds_o->upper_z = upper.z; }
/* occlusion filter function */ void occlusionFilter(void* ptr, RTCRay2& ray) { /* make all surfaces opaque */ if (ray.geomID >= g_ispc_scene->numHairSets) { ray.transparency = Vec3fa(0.0f); return; } Vec3fa T = hair_Kt; T = T * ray.transparency; // FIXME: use *= operator ray.transparency = T; if (ne(T,Vec3fa(0.0f))) ray.geomID = RTC_INVALID_GEOMETRY_ID; // FIXME: use != operator }
/* occlusion filter function */ void occlusionFilter(void* ptr, RTCRay2& ray) { /* make all surfaces opaque */ ISPCGeometry* geometry = g_ispc_scene->geometries[ray.geomID]; if (geometry->type == TRIANGLE_MESH) { ray.transparency = Vec3fa(0.0f); return; } Vec3fa T = hair_Kt; T = T * ray.transparency; ray.transparency = T; if (ne(T,Vec3fa(0.0f))) ray.geomID = RTC_INVALID_GEOMETRY_ID; }
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; }
Vec3fa noise3D(const Vec3fa& p) { float x = noise(p.x+128.0f); float y = noise(p.y+64.0f); float z = noise(p.z+192.0f); return Vec3fa(x,y,z); }
__noinline void setray(RTCRay& ray) { ray.u = ray.v = 0.001f; ray.Ng = Vec3fa(0,1,0); ray.geomID = 0; ray.primID = 0; }
/* 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; } }
/* task that renders a single screen tile */ void renderTile(int taskIndex, int* pixels, const int width, const int height, const float time, const Vec3fa& vx, const Vec3fa& vy, const Vec3fa& vz, const Vec3fa& p, 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); //int seed = tileY*numTilesX+tileX+0 + g_accu_count; int seed = (tileY*numTilesX+tileX+0) * g_accu_count; for (int y = y0; y<y1; y++) for (int x = x0; x<x1; x++) { /* calculate pixel color */ Vec3fa color = renderPixel(x,y,vx,vy,vz,p); //Vec3fa color = renderPixelTestEyeLight(x,y,vx,vy,vz,p); /* write color to framebuffer */ Vec3fa accu_color = g_accu[y*width+x] + Vec3fa(color.x,color.y,color.z,1.0f); g_accu[y*width+x] = accu_color; float f = rcp(max(0.001f,accu_color.w)); unsigned int r = (unsigned int) (255.0f * clamp(accu_color.x*f,0.0f,1.0f)); unsigned int g = (unsigned int) (255.0f * clamp(accu_color.y*f,0.0f,1.0f)); unsigned int b = (unsigned int) (255.0f * clamp(accu_color.z*f,0.0f,1.0f)); pixels[y*width+x] = (b << 16) + (g << 8) + r; } }
/*! Samples the distribution. \param s is the sample location * provided by the caller. */ inline Vec3fa AnisotropicBlinn__sample(const AnisotropicBlinn* This, const float sx, const float sy) { const float phi =float(two_pi)*sx; const float sinPhi0 = sqrtf(This->nx+1)*sinf(phi); const float cosPhi0 = sqrtf(This->ny+1)*cosf(phi); const float norm = rsqrt(sqr(sinPhi0)+sqr(cosPhi0)); const float sinPhi = sinPhi0*norm; const float cosPhi = cosPhi0*norm; const float n = This->nx*sqr(cosPhi)+This->ny*sqr(sinPhi); const float cosTheta = powf(sy,rcp(n+1)); const float sinTheta = cos2sin(cosTheta); const float pdf = This->norm1*powf(cosTheta,n); const Vec3fa h = Vec3fa(cosPhi * sinTheta, sinPhi * sinTheta, cosTheta); const Vec3fa wh = h.x*This->dx + h.y*This->dy + h.z*This->dz; return Vec3fa(wh,pdf); }