int ray_tracking_cpu(const float* a, const float* b, const float* c, int sphere_num, unsigned char* ptr, int width, int height, float* elapsed_time) { auto start = std::chrono::steady_clock::now(); std::unique_ptr<Sphere[]> spheres(new Sphere[sphere_num]); for (int i = 0, t = 0; i < sphere_num; ++i, t+=3) { spheres[i].r = a[t]; spheres[i].g = a[t+1]; spheres[i].b = a[t+2]; spheres[i].x = b[t]; spheres[i].y = b[t+1]; spheres[i].z = b[t+2]; spheres[i].radius = c[i]; } for (int y = 0; y < height; ++y) { for (int x = 0; x < width; ++x) { int offset = x + y * width; float ox{ (x - width / 2.f) }; float oy{ (y - height / 2.f) }; float r{ 0 }, g{ 0 }, b{ 0 }; float maxz{ -INF }; for (int i = 0; i < sphere_num; ++i) { float n; float t = spheres[i].hit(ox, oy, &n); if (t > maxz) { float fscale = n; r = spheres[i].r * fscale; g = spheres[i].g * fscale; b = spheres[i].b * fscale; maxz = t; } } ptr[offset * 4 + 0] = static_cast<unsigned char>(r * 255); ptr[offset * 4 + 1] = static_cast<unsigned char>(g * 255); ptr[offset * 4 + 2] = static_cast<unsigned char>(b * 255); ptr[offset * 4 + 3] = 255; } } auto end = std::chrono::steady_clock::now(); auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start); *elapsed_time = duration.count() * 1.0e-6; return 0; }
void RayTraceRenderPass::UploadToGPU(const Camera &cam) const { const auto primitivesUB = UniformBuffers::Get().Primitives(); size_t offset = 0; primitivesUB.rectangles(mRectangles, offset); offset += mRectangles.size() * sizeof(RTRectangle); primitivesUB.boxes(mBoxes, offset); offset += mBoxes.size() * sizeof(RTBox); primitivesUB.spheres(mSpheres, offset); offset += mSpheres.size() * sizeof(RTSphere); primitivesUB.lights(mLights, offset); offset += mLights.size() * sizeof(RTLight); if (offset > PrimitivesUB::MAX_SIZE) { throw exception("PrimitivesUB size larger then max: " + offset); } }
std::vector<Sphere> readScene(const std::string& fileName, Vec& orig, Vec& target) { fprintf(stderr, "Reading scene: %s\n", fileName.c_str()); FILE *f = std::fopen(fileName.c_str(), "r"); if (!f) { fprintf(stderr, "Failed to open file: %s\n", fileName.c_str()); exit(-1); } /* Read the camera position */ int c = std::fscanf(f, "camera %f %f %f %f %f %f\n", &orig.x, &orig.y, &orig.z, &target.x, &target.y, &target.z); if (c != 6) { fprintf(stderr, "Failed to read 6 camera parameters: %d\n", c); exit(-1); } std::size_t sphereCount = 0; /* Read the sphere count */ c = std::fscanf(f, "size %u\n", &sphereCount); if (c != 1) { fprintf(stderr, "Failed to read sphere count: %d\n", c); exit(-1); } fprintf(stderr, "Scene size: %d\n", sphereCount); /* Read all spheres */ std::vector<Sphere> spheres(sphereCount); for (unsigned i = 0; i < sphereCount; ++i) { Sphere s; int mat = 0; int c = std::fscanf(f, "sphere %f %f %f %f %f %f %f %f %f %f %d\n", &s.rad, &s.p.x, &s.p.y, &s.p.z, &s.e.x, &s.e.y, &s.e.z, &s.c.x, &s.c.y, &s.c.z, &mat); switch (mat) { case 0: s.refl = Refl::DIFF; break; case 1: s.refl = Refl::SPEC; break; case 2: s.refl = Refl::REFR; break; default: fprintf(stderr, "Failed to read material type for sphere #%d: %d\n", i, mat); exit(-1); break; } if (c != 11) { fprintf(stderr, "Failed to read sphere #%d: %d\n", i, c); exit(-1); } spheres.push_back(s); } std::fclose(f); return spheres; }
int makeGeometry(Box& a_domain, RealVect& a_dx) { int eekflag = 0; //parse input file ParmParse pp; int verbosity = 0; RealVect origin = RealVect::Zero; Vector<int> n_cell(SpaceDim); pp.getarr("n_cell",n_cell,0,SpaceDim); CH_assert(n_cell.size() == SpaceDim); IntVect lo = IntVect::Zero; IntVect hi; for (int ivec = 0; ivec < SpaceDim; ivec++) { if (n_cell[ivec] <= 0) { pout() << " bogus number of cells input = " << n_cell[ivec]; return(-1); } hi[ivec] = n_cell[ivec] - 1; } a_domain.setSmall(lo); a_domain.setBig(hi); Vector<Real> prob_lo(SpaceDim, 1.0); Real prob_hi; pp.getarr("prob_lo",prob_lo,0,SpaceDim); pp.get("prob_hi",prob_hi); for (int idir = 0; idir < SpaceDim; idir++) { a_dx[idir] = (prob_hi-prob_lo[idir])/n_cell[idir]; origin[idir] = prob_lo[idir]; } int whichgeom; pp.get("which_geom",whichgeom); CH_XD::EBIndexSpace* ebisPtr = Chombo_EBIS::instance(); if (whichgeom == 0) { //allregular pout() << "all regular geometry" << endl; AllRegularService regserv; ebisPtr->define(a_domain, origin, a_dx[0], regserv); } else if (whichgeom == 1) { pout() << "ramp geometry" << endl; int upDir; int indepVar; Real startPt; Real slope; pp.get("up_dir",upDir); pp.get("indep_var",indepVar); pp.get("start_pt", startPt); pp.get("ramp_slope", slope); RealVect normal = RealVect::Zero; normal[upDir] = 1.0; normal[indepVar] = -slope; RealVect point = RealVect::Zero; point[upDir] = -slope*startPt; bool normalInside = true; PlaneIF ramp(normal,point,normalInside); GeometryShop workshop(ramp,verbosity,a_dx); //this generates the new EBIS ebisPtr->define(a_domain, origin, a_dx[0], workshop); } else if (whichgeom == 5) { pout() << "sphere geometry" << endl; vector<Real> sphere_center(SpaceDim); pp.getarr("sphere_center",sphere_center, 0, SpaceDim); RealVect sphereCenter; for (int idir = 0; idir < SpaceDim; idir++) { sphereCenter[idir] = sphere_center[idir]; } Real sphereRadius; pp.get("sphere_radius", sphereRadius); bool insideRegular = false; SphereIF implicit(sphereRadius,sphereCenter,insideRegular); GeometryShop workshop(implicit,verbosity,a_dx); //this generates the new EBIS ebisPtr->define(a_domain, origin, a_dx[0], workshop); } else if (whichgeom == 6) { pout() << "multisphere geometry" << endl; int numSpheres; pp.get("num_spheres", numSpheres); Vector<Real> radius(numSpheres); Vector<RealVect> center(numSpheres); for (int isphere = 0; isphere < numSpheres; isphere++) { char radiusString[80]; char centerString[80]; sprintf(radiusString, "sphere_radius_%d", isphere); sprintf(centerString, "sphere_center_%d", isphere); vector<Real> sphere_center(SpaceDim); Real sphereRadius; pp.get(radiusString, sphereRadius); pp.getarr(centerString,sphere_center, 0, SpaceDim); RealVect sphereCenter; for (int idir = 0; idir < SpaceDim; idir++) { sphereCenter[idir] = sphere_center[idir]; } center[isphere] = sphereCenter; radius[isphere] = sphereRadius; } bool inside = false; MultiSphereIF spheres(radius, center, inside); GeometryShop workshop(spheres,verbosity,a_dx); //this generates the new EBIS ebisPtr->define(a_domain, origin, a_dx[0], workshop); } else { //bogus which_geom pout() << " bogus which_geom input = " << whichgeom; eekflag = 33; } return eekflag; }