Esempio n. 1
0
	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;
	}
Esempio n. 2
0
// XXX importance sampling is only done into the positive hemisphere
// ==> poor support for translucent materials
Light_SampleRes AmbientLight_sample(const Light* super,
                                    const DifferentialGeometry& dg,
                                    const Vec2f& s)
{
    AmbientLight* self = (AmbientLight*)super;
    Light_SampleRes res;

    const Vec3fa localDir = cosineSampleHemisphere(s);
    res.dir = frame(dg.Ns) * localDir;
    res.pdf = cosineSampleHemispherePDF(localDir);
    res.dist = inf;
    res.weight = self->radiance * rcp(res.pdf);

    return res;
}
Esempio n. 3
0
rgbColor substrate::sampleF(const float& u0, const float& u1, const vec3& wo, vec3& wi, float& pd) const{
    if(u0 < 0.5f){
        const float u = 2.f * u0;
        cosineSampleHemisphere(wi, u, u1);
    }else{
        const float u = 2.f * (u0 - 0.5f);
        distrib->sampleF(u, u1, wo, wi, pd);

        if(wo.y * wi.y < 0){
            return rgbColor(0.f);
        }
    }

    pd = pdf(wo, wi);
    return f(wo, wi);
}
Esempio n. 4
0
Light_SampleRes PointLight_sample(const Light* super,
                                  const DifferentialGeometry& dg,
                                  const Vec2f& s)
{
  const PointLight* self = (PointLight*)super;
  Light_SampleRes res;

  // extant light vector from the hit point
  const Vec3fa dir = self->position - dg.P;
  const float dist2 = dot(dir, dir);
  const float invdist = rsqrt(dist2);

  // normalized light vector
  res.dir = dir * invdist;
  res.dist = dist2 * invdist;

  res.pdf = inf; // per default we always take this res

  // convert from power to radiance by attenuating by distance^2
  res.weight = self->power * sqr(invdist);
  const float sinTheta = self->radius * invdist;

  if ((self->radius > 0.f) & (sinTheta > 0.005f)) {
    // res surface of sphere as seen by hit point -> cone of directions
    // for very small cones treat as point light, because float precision is not good enough
    if (sinTheta < 1.f) {
      const float cosTheta = sqrt(1.f - sinTheta * sinTheta);
      const Vec3fa localDir = uniformSampleCone(cosTheta, s);
      res.dir = frame(res.dir) * localDir;
      res.pdf = uniformSampleConePDF(cosTheta);
      const float c = localDir.z;
      res.dist = c*res.dist - sqrt(sqr(self->radius) - (1.f - c*c) * dist2);
      // TODO scale radiance by actual distance
    } else { // inside sphere
      const Vec3fa localDir = cosineSampleHemisphere(s);
      res.dir = frame(dg.Ns) * localDir;
      res.pdf = cosineSampleHemispherePDF(localDir);
      // TODO:
      res.weight = self->power * rcp(sqr(self->radius));
      res.dist = self->radius;
    }
  }

  return res;
}
Esempio n. 5
0
/*! Cosine weighted hemisphere sampling. Up direction is provided as argument. */
inline direction_sample cosineSampleHemisphere(real u, real v, const real3& N) {
    direction_sample s = cosineSampleHemisphere(u, v);
    return direction_sample(frameZ(N) * real3(s.value()), s.density());
}
Esempio n. 6
0
/* renders a single pixel casting with ambient occlusion */
Vec3fa ambientOcclusionShading(int x, int y, RTCRay& ray)
{
  RTCRay rays[AMBIENT_OCCLUSION_SAMPLES];

  Vec3fa Ng = normalize(ray.Ng);
  if (dot(ray.dir,Ng) > 0.0f) Ng = neg(Ng);

  Vec3fa col = Vec3fa(min(1.0f,0.3f+0.8f*abs(dot(Ng,normalize(ray.dir)))));

  /* calculate hit point */
  float intensity = 0;
  Vec3fa hitPos = ray.org + ray.tfar * ray.dir;

  RandomSampler sampler;
  RandomSampler_init(sampler,x,y,0);

  /* enable only valid rays */
  for (int i=0; i<AMBIENT_OCCLUSION_SAMPLES; i++)
  {
    /* sample random direction */
    Vec2f s = RandomSampler_get2D(sampler);
    Sample3f dir;
    dir.v = cosineSampleHemisphere(s);
    dir.pdf = cosineSampleHemispherePDF(dir.v);
    dir.v = frame(Ng) * dir.v;

    /* initialize shadow ray */
    RTCRay& shadow = rays[i];
    shadow.org = hitPos;
    shadow.dir = dir.v;
    bool mask = 1; { // invalidate inactive rays
      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;    // FIXME: invalidate inactive rays
  }

  RTCIntersectContext context;
  context.flags = RAYN_FLAGS;

  /* trace occlusion rays */
#if USE_INTERFACE == 0
  rtcOccluded1M(g_scene,&context,rays,AMBIENT_OCCLUSION_SAMPLES,sizeof(RTCRay));
#elif USE_INTERFACE == 1
  for (size_t i=0; i<AMBIENT_OCCLUSION_SAMPLES; i++)
    rtcOccluded(g_scene,rays[i]);
#else
  for (size_t i=0; i<AMBIENT_OCCLUSION_SAMPLES; i++)
    rtcOccluded1M(g_scene,&context,&rays[i],1,sizeof(RTCRay));
#endif

  /* accumulate illumination */
  for (int i=0; i<AMBIENT_OCCLUSION_SAMPLES; i++) {
    if (rays[i].geomID == RTC_INVALID_GEOMETRY_ID)
      intensity += 1.0f;
  }

  /* shade pixel */
  return col * (intensity/AMBIENT_OCCLUSION_SAMPLES);
}
Esempio n. 7
0
  void DebugRenderer::RenderJob::renderTile(size_t threadIndex, size_t threadCount, size_t taskIndex, size_t taskCount, TaskScheduler::Event* event)
  {
    size_t numRays = 0;
    if (taskIndex == taskCount-1) t0 = getSeconds();

    /*! tile pick loop */
    while (true)
    {
      /*! pick a new tile */
      size_t tile = tileID++;
      if (tile >= numTilesX*numTilesY) break;

      /*! compute tile location */
      Random rand(int(tile)*1024);
      size_t x0 = (tile%numTilesX)*TILE_SIZE;
      size_t y0 = (tile/numTilesX)*TILE_SIZE;

      Vec2i start((int)x0,(int)y0);
      Vec2i end (min(int(framebuffer->getWidth()),int(start.x+TILE_SIZE))-1,min(int(framebuffer->getHeight()),int(start.y+TILE_SIZE))-1);

      /*! loop over all pixels of the tile */
      for (size_t dy=0; dy<TILE_SIZE; dy++)
      {
        size_t iy = y0+dy; float fy = iy*rcpHeight;
        if (iy >= framebuffer->getHeight()) continue;
        if (!swapchain->activeLine(iy)) continue;
        iy = swapchain->raster2buffer(iy);

        for (size_t dx=0; dx<TILE_SIZE; dx++)
        {
          /*! ignore tile pixels outside framebuffer */
          size_t ix = x0+dx; float fx = ix*rcpWidth;
          if (ix >= framebuffer->getWidth()) continue;

	  for (size_t i=0; i<renderer->spp; i++)
	  {
	    /*! create primary ray */
	    Ray ray; camera->ray(Vec2f(fx,fy), /*Vec2f(rand.getFloat(),rand.getFloat())*/ Vec2f(0.5f,0.5f), ray);
	    
	    for (size_t depth=0; depth<renderer->maxDepth; depth++)
	    {
	      /*! shoot current ray */
              //scene->intersector->intersect(ray);
              rtcIntersect(scene->scene,(RTCRay&)ray);
              numRays++;
	      if (!ray) break;
	      
	      /*! compute new ray through diffuse bounce */
	      if (depth+1<renderer->maxDepth) 
		{
		  Vector3f Nf = normalize(ray.Ng);
		  if (dot(-ray.dir,Nf) < 0) Nf = -Nf;
		  new (&ray) Ray(ray.org+0.999f*ray.tfar*ray.dir,cosineSampleHemisphere(rand.getFloat(),rand.getFloat(),Nf),4.0f*float(ulp)/**hit.error*/);
		}
	      
	    }  

#if 1
	    /*! update framebuffer */
	    if (!ray) framebuffer->set(ix,iy,one);
	    //else      framebuffer->get(ix,iy) = Vec4f(abs(hit.Ns.x),abs(hit.Ns.y),abs(hit.Ns.z),1.0f);
            /*else      {
              hit.Ng = normalize(hit.Ng);
              framebuffer->set(ix,iy,Color(abs(hit.Ng.x),abs(hit.Ng.y),abs(hit.Ng.z)));
              }*/
	    //else      framebuffer->set(ix,iy,Color(clamp(dot(ray.dir,normalize(ray.Ng))),0,0));
	    //else      framebuffer->set(ix,iy,Color(hit.u,hit.v,1.0f-hit.u-hit.v));
	    //else      framebuffer->get(ix,iy) = Vec4f(hit.st.x,hit.st.y,1.0f-hit.st.x-hit.st.y,1.0f);
	    //else      framebuffer->get(ix,iy) = Vec4f(hit.st.x,0,0,1.0f);
	    //else      framebuffer->get(ix,iy) = Vec4f(abs(dot(ray.dir,normalize(hit.dPds))),0,0,1.0f);
	    else framebuffer->set(ix,iy,Color(((3434553*((unsigned)(ray.id0+ray.id1+3243)))%255)/255.0f,
                                              ((7342453*((unsigned)(ray.id0+ray.id1+8237)))%255)/255.0f,
                                              ((9234454*((unsigned)(ray.id0+ray.id1+2343)))%255)/255.0f));
#endif
	  }
        }
      }
      framebuffer->finishTile();
    }

    /*! we access the atomic ray counter only once per tile */
    atomicNumRays += numRays;
  }
Esempio n. 8
0
  void DebugRenderer::renderThread()
  {
    size_t numRays = 0;

    /*! tile pick loop */
    while (true)
    {
      /*! pick a new tile */
      size_t tile = tileID++;
      if (tile >= numTilesX*numTilesY) break;

      /*! compute tile location */
      Random rand(int(tile)*1024);
      size_t x0 = (tile%numTilesX)*TILE_SIZE;
      size_t y0 = (tile/numTilesX)*TILE_SIZE;

      Vec2i start((int)x0,(int)y0);
      Vec2i end (min(int(framebuffer->getWidth()),int(start.x+TILE_SIZE))-1,min(int(framebuffer->getHeight()),int(start.y+TILE_SIZE))-1);

      /*! loop over all pixels of the tile */
      for (size_t dy=0; dy<TILE_SIZE; dy++)
      {
        for (size_t dx=0; dx<TILE_SIZE; dx++)
        {
          /*! ignore tile pixels outside framebuffer */
          size_t ix = x0+dx, iy = y0+dy;
          if (ix >= framebuffer->getWidth() || iy >= framebuffer->getHeight()) continue;

	  for (int s=0; s<spp; s++)
	  {	
	    /*! create primary ray */
	    DifferentialGeometry hit;
	    Ray ray; camera->ray(Vec2f(ix*rcpWidth,iy*rcpHeight), Vec2f(rand.getFloat(),rand.getFloat()), ray);
	    
	    for (ssize_t depth=0; depth<maxDepth; depth++)
	    {
	      /*! shoot current ray */
	      new (&hit) DifferentialGeometry;
	      scene->intersector->intersect(ray,hit);
	      scene->postIntersect(ray,hit);
	      numRays++;
	      if (!hit) break;
	      
	      /*! compute new ray through diffuse bounce */
	      Vec3f Nf = hit.Ng;
	      if (dot(-ray.dir,Nf) < 0) Nf = -Nf;
	      if (depth+1<maxDepth) {
		ray = Ray(ray.org+0.999f*hit.t*ray.dir,cosineSampleHemisphere(rand.getFloat(),rand.getFloat(),Nf),4.0f*float(ulp)*hit.error);
	      }
	    }
	      
	    /*! update framebuffer */
	    if (!hit) framebuffer->get(ix,iy) = zero;
	    //else      framebuffer->get(ix,iy) = Vec4f(-dot(ray.dir,hit.Ns),0,0,1.0f);
	    else      framebuffer->get(ix,iy) = Vec4f(hit.u,hit.v,1.0f-hit.u-hit.v,1.0f);
	    //else      framebuffer->get(ix,iy) = Vec4f(hit.st.x,hit.st.y,1.0f-hit.st.x-hit.st.y,1.0f);
	    //else      framebuffer->get(ix,iy) = Vec4f(hit.st.x,0,0,1.0f);
	    //else      framebuffer->get(ix,iy) = Vec4f(abs(dot(ray.dir,normalize(hit.dPds))),0,0,1.0f);
	    //framebuffer->get(ix,iy) = Vec4f(ix*rcpWidth,iy*rcpHeight,0.0f,0.0f);
	  }
        }
      }
      framebuffer->finishTile();
    }

    /*! we access the atomic ray counter only once per tile */
    atomicNumRays += numRays;
  }