/* 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; }
/* task that renders a single screen tile */ Vec3fa renderPixelStandard(float x, float y, const ISPCCamera& camera, RayStats& stats) { RTCIntersectContext context; rtcInitIntersectContext(&context); /* 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 */ rtcIntersect1(g_scene,&context,RTCRayHit_(ray)); RayStats_addRay(stats); /* 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; { rtcInterpolate0(rtcGetGeometry(g_scene,geomID),ray.primID,ray.u,ray.v,RTC_BUFFER_TYPE_VERTEX_ATTRIBUTE,0,&diffuse.x,3); } //return diffuse; diffuse = 0.5f*diffuse; } /* calculate smooth shading normal */ Vec3fa Ng = ray.Ng; if (ray.geomID == 2 || ray.geomID == 3) { 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); } //return dPdu; Ng = cross(dPdu,dPdv); } Ng = normalize(Ng); color = color + diffuse*0.5f; 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) { 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; }
/* 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; }
/* 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) { RTCIntersectContext context; rtcInitIntersectContext(&context); /* 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 */ 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 = 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; 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); } Ng = normalize(cross(dPdu,dPdv)); dPdu = dPdu + Ng*displacement_du(P,dPdu); dPdv = dPdv + Ng*displacement_dv(P,dPdv); Ng = normalize(cross(dPdu,dPdv)); } #endif /* initialize shadow ray */ Ray shadow(ray.org + ray.tfar*ray.dir, neg(lightDir), 0.001f, inf, 0.0f); /* 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,Ng)),0.0f,1.0f); } return color; }
/* renders a single screen tile */ void renderTileStandardStream(int taskIndex, int threadIndex, int* pixels, const unsigned int width, const unsigned int height, const float time, const ISPCCamera& camera, const int numTilesX, const int numTilesY) { const unsigned int tileY = taskIndex / numTilesX; const unsigned int tileX = taskIndex - tileY * numTilesX; const unsigned int x0 = tileX * TILE_SIZE_X; const unsigned int x1 = min(x0+TILE_SIZE_X,width); const unsigned int y0 = tileY * TILE_SIZE_Y; const unsigned int y1 = min(y0+TILE_SIZE_Y,height); RayStats& stats = g_stats[threadIndex]; RTCRay2 primary_stream[TILE_SIZE_X*TILE_SIZE_Y]; RTCRay2 shadow_stream[TILE_SIZE_X*TILE_SIZE_Y]; Vec3fa color_stream[TILE_SIZE_X*TILE_SIZE_Y]; float weight_stream[TILE_SIZE_X*TILE_SIZE_Y]; bool valid_stream[TILE_SIZE_X*TILE_SIZE_Y]; /* generate stream of primary rays */ int N = 0; int numActive = 0; for (unsigned int y=y0; y<y1; y++) for (unsigned int x=x0; x<x1; x++) { /* ISPC workaround for mask == 0 */ /* initialize variables */ numActive++; color_stream[N] = Vec3fa(0.0f); weight_stream[N] = 1.0f; bool mask = 1; { valid_stream[N] = mask; } /* initialize ray */ RTCRay2& primary = primary_stream[N]; primary.org = Vec3fa(camera.xfm.p); primary.dir = Vec3fa(normalize((float)x*camera.xfm.l.vx + (float)y*camera.xfm.l.vy + camera.xfm.l.vz)); mask = 1; { // invalidates inactive rays primary.tnear = mask ? 0.0f : (float)(pos_inf); primary.tfar = mask ? (float)(inf) : (float)(neg_inf); } primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.mask = 0xFFFF0000 + N*1 + 0; primary.time = 0.0f; primary.transparency = 0.0f; N++; RayStats_addRay(stats); } Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); while (numActive) { /* trace rays */ RTCIntersectContext primary_context; primary_context.flags = g_iflags_coherent; primary_context.userRayExt = &primary_stream; rtcIntersect1M(g_scene,&primary_context,(RTCRay*)&primary_stream,N,sizeof(RTCRay2)); /* terminate rays and update color */ N = -1; for (unsigned int y=y0; y<y1; y++) for (unsigned int x=x0; x<x1; x++) { N++; /* ISPC workaround for mask == 0 */ /* invalidate shadow rays by default */ RTCRay2& shadow = shadow_stream[N]; { shadow.tnear = (float)(pos_inf); shadow.tfar = (float)(neg_inf); } /* ignore invalid rays */ if (valid_stream[N] == false) continue; /* terminate rays that hit nothing */ if (primary_stream[N].geomID == RTC_INVALID_GEOMETRY_ID) { valid_stream[N] = false; continue; } /* update color */ RTCRay2& primary = primary_stream[N]; float opacity = 1.0f-primary.transparency; Vec3fa diffuse = colors[primary.primID]; Vec3fa La = diffuse*0.5f; color_stream[N] = color_stream[N] + weight_stream[N]*opacity*La; /* initialize shadow ray */ shadow.org = primary.org + primary.tfar*primary.dir; shadow.dir = neg(lightDir); bool mask = 1; { shadow.tnear = mask ? 0.001f : (float)(pos_inf); shadow.tfar = mask ? (float)(inf) : (float)(neg_inf); } shadow.geomID = RTC_INVALID_GEOMETRY_ID; shadow.primID = RTC_INVALID_GEOMETRY_ID; shadow.mask = 0xFFFF0000 + N*1 + 0; shadow.time = 0; shadow.transparency = 1.0f; shadow.firstHit = 0; shadow.lastHit = 0; RayStats_addShadowRay(stats); } N++; /* trace shadow rays */ RTCIntersectContext shadow_context; shadow_context.flags = g_iflags_coherent; shadow_context.userRayExt = &shadow_stream; rtcOccluded1M(g_scene,&shadow_context,(RTCRay*)&shadow_stream,N,sizeof(RTCRay2)); /* add light contribution and generate transmission ray */ N = -1; numActive = 0; for (unsigned int y=y0; y<y1; y++) for (unsigned int x=x0; x<x1; x++) { N++; /* ISPC workaround for mask == 0 */ /* invalidate rays by default */ RTCRay2& primary = primary_stream[N]; float primary_tfar = primary.tfar; { primary.tnear = (float)(pos_inf); primary.tfar = (float)(neg_inf); } /* ignore invalid rays */ if (valid_stream[N] == false) continue; numActive++; /* add light contrinution */ float opacity = 1.0f-primary.transparency; Vec3fa diffuse = colors[primary.primID]; RTCRay2& shadow = shadow_stream[N]; if (shadow.geomID) { Vec3fa Ll = diffuse*shadow.transparency*clamp(-dot(lightDir,normalize(primary.Ng)),0.0f,1.0f); color_stream[N] = color_stream[N] + weight_stream[N]*opacity*Ll; } /* initialize transmission ray */ weight_stream[N] *= primary.transparency; bool mask = 1; { primary.tnear = mask ? 1.001f*primary_tfar : (float)(pos_inf); primary.tfar = mask ? (float)(inf) : (float)(neg_inf); } primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.transparency = 0.0f; RayStats_addRay(stats); } N++; } /* framebuffer writeback */ N = 0; for (unsigned int y=y0; y<y1; y++) for (unsigned int x=x0; x<x1; x++) { /* ISPC workaround for mask == 0 */ /* write color to framebuffer */ unsigned int r = (unsigned int) (255.0f * clamp(color_stream[N].x,0.0f,1.0f)); unsigned int g = (unsigned int) (255.0f * clamp(color_stream[N].y,0.0f,1.0f)); unsigned int b = (unsigned int) (255.0f * clamp(color_stream[N].z,0.0f,1.0f)); pixels[y*width+x] = (b << 16) + (g << 8) + r; N++; } }
/* 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; }
/* renders a single screen tile */ void renderTileStandardStream(int taskIndex, int threadIndex, int* pixels, const unsigned int width, const unsigned int height, const float time, const ISPCCamera& camera, const int numTilesX, const int numTilesY) { const unsigned int tileY = taskIndex / numTilesX; const unsigned int tileX = taskIndex - tileY * numTilesX; const unsigned int x0 = tileX * TILE_SIZE_X; const unsigned int x1 = min(x0+TILE_SIZE_X,width); const unsigned int y0 = tileY * TILE_SIZE_Y; const unsigned int y1 = min(y0+TILE_SIZE_Y,height); RayStats& stats = g_stats[threadIndex]; RTCRay primary_stream[TILE_SIZE_X*TILE_SIZE_Y]; RTCRay shadow_stream[TILE_SIZE_X*TILE_SIZE_Y]; Vec3fa color_stream[TILE_SIZE_X*TILE_SIZE_Y]; bool valid_stream[TILE_SIZE_X*TILE_SIZE_Y]; /* generate stream of primary rays */ int N = 0; for (unsigned int y=y0; y<y1; y++) for (unsigned int x=x0; x<x1; x++) { /* ISPC workaround for mask == 0 */ /* initialize variables */ color_stream[N] = Vec3fa(0.0f); bool mask = 1; { valid_stream[N] = mask; } /* initialize ray */ RTCRay& primary = primary_stream[N]; primary.org = Vec3fa(camera.xfm.p); primary.dir = Vec3fa(normalize((float)x*camera.xfm.l.vx + (float)y*camera.xfm.l.vy + camera.xfm.l.vz)); mask = 1; { // invalidates inactive rays primary.tnear = mask ? 0.0f : (float)(pos_inf); primary.tfar = mask ? (float)(inf) : (float)(neg_inf); } primary.instID = RTC_INVALID_GEOMETRY_ID; primary.geomID = RTC_INVALID_GEOMETRY_ID; primary.primID = RTC_INVALID_GEOMETRY_ID; primary.mask = -1; primary.time = 0.0f; N++; RayStats_addRay(stats); } Vec3fa lightDir = normalize(Vec3fa(-1,-1,-1)); /* trace rays */ RTCIntersectContext primary_context; primary_context.flags = g_iflags_coherent; primary_context.userRayExt = primary_stream; rtcIntersect1M(g_scene,&primary_context,(RTCRay*)&primary_stream,N,sizeof(RTCRay)); /* terminate rays and update color */ N = -1; for (unsigned int y=y0; y<y1; y++) for (unsigned int x=x0; x<x1; x++) { N++; /* ISPC workaround for mask == 0 */ /* invalidate shadow rays by default */ RTCRay& shadow = shadow_stream[N]; { shadow.tnear = (float)(pos_inf); shadow.tfar = (float)(neg_inf); } /* ignore invalid rays */ if (valid_stream[N] == false) continue; /* terminate rays that hit nothing */ if (primary_stream[N].geomID == RTC_INVALID_GEOMETRY_ID) { valid_stream[N] = false; continue; } /* calculate shading normal in world space */ RTCRay& primary = primary_stream[N]; Vec3fa Ns = primary.Ng; if (primary.instID != RTC_INVALID_GEOMETRY_ID) Ns = xfmVector(normal_xfm[primary.instID],Ns); Ns = normalize(Ns); /* calculate diffuse color of geometries */ Vec3fa diffuse = Vec3fa(1,1,1); if (primary.instID != RTC_INVALID_GEOMETRY_ID) diffuse = colors[primary.instID][primary.geomID]; color_stream[N] = color_stream[N] + diffuse*0.5; /* initialize shadow ray */ shadow.org = primary.org + primary.tfar*primary.dir; shadow.dir = neg(lightDir); bool mask = 1; { shadow.tnear = mask ? 0.001f : (float)(pos_inf); shadow.tfar = mask ? (float)(inf) : (float)(neg_inf); } shadow.geomID = RTC_INVALID_GEOMETRY_ID; shadow.primID = RTC_INVALID_GEOMETRY_ID; shadow.mask = -1; shadow.time = 0; RayStats_addShadowRay(stats); } N++; /* trace shadow rays */ RTCIntersectContext shadow_context; shadow_context.flags = g_iflags_coherent; shadow_context.userRayExt = shadow_stream; rtcOccluded1M(g_scene,&shadow_context,(RTCRay*)&shadow_stream,N,sizeof(RTCRay)); /* add light contribution */ N = -1; for (unsigned int y=y0; y<y1; y++) for (unsigned int x=x0; x<x1; x++) { N++; /* ISPC workaround for mask == 0 */ /* ignore invalid rays */ if (valid_stream[N] == false) continue; /* calculate shading normal in world space */ RTCRay& primary = primary_stream[N]; Vec3fa Ns = primary.Ng; if (primary.instID != RTC_INVALID_GEOMETRY_ID) Ns = xfmVector(normal_xfm[primary.instID],Ns); Ns = normalize(Ns); /* calculate diffuse color of geometries */ Vec3fa diffuse = Vec3fa(1,1,1); if (primary.instID != RTC_INVALID_GEOMETRY_ID) diffuse = colors[primary.instID][primary.geomID]; /* add light contrinution */ RTCRay& shadow = shadow_stream[N]; if (shadow.geomID) { color_stream[N] = color_stream[N] + diffuse*clamp(-dot(lightDir,Ns),0.0f,1.0f); } } N++; /* framebuffer writeback */ N = 0; for (unsigned int y=y0; y<y1; y++) for (unsigned int x=x0; x<x1; x++) { /* ISPC workaround for mask == 0 */ /* write color to framebuffer */ unsigned int r = (unsigned int) (255.0f * clamp(color_stream[N].x,0.0f,1.0f)); unsigned int g = (unsigned int) (255.0f * clamp(color_stream[N].y,0.0f,1.0f)); unsigned int b = (unsigned int) (255.0f * clamp(color_stream[N].z,0.0f,1.0f)); pixels[y*width+x] = (b << 16) + (g << 8) + r; N++; } }