float Radiosity::Iterate() {
  if (formfactors == NULL) 
    ComputeFormFactors();
  assert (formfactors != NULL);

  // ==========================================
  // ASSIGNMENT:  IMPLEMENT RADIOSITY ALGORITHM
  // ==========================================
  
  int new_max_patch = 0;
  float max_light = 0;
  float sum_light = 0;
  glm::vec3 undistributed_light = undistributed[max_undistributed_patch];
  undistributed[max_undistributed_patch] = glm::vec3(0, 0, 0);
  for (int i = 0; i < num_faces; i++)
  {
	  //std::cout << glm::length(undistributed_light) << "\n";
		float FF = getFormFactor(max_undistributed_patch, i);
		Material* m = this->getMesh()->getFace(i)->getMaterial();
		//splitlight is the value that is added to the undistributed light and absorbed.
		glm::vec3 splitlight = FF * undistributed_light;

		undistributed[i] += splitlight * m->getEmittedColor();
		absorbed[i] += splitlight * glm::vec3(1-m->getDiffuseColor().x,1-m->getDiffuseColor().y,1-m->getDiffuseColor().z);
		radiance[i] += splitlight * m->getDiffuseColor();
		sum_light += glm::length(undistributed[i]);
		//Find the new largest undistributed light patch
		if (glm::length(undistributed[i]) > max_light)
		{
			new_max_patch = i;
		}
  }
  max_undistributed_patch = new_max_patch;
  return sum_light;
  // return the total light yet undistributed
  // (so we can decide when the solution has sufficiently converged)
  
  return 0;




}
Example #2
0
Vec3f Radiosity::whichVisualization(enum RENDER_MODE mode, Face *f, int i) {
    assert (mesh->getFace(i) == f);
    assert (i >= 0 && i < num_faces);
    if (mode == RENDER_LIGHTS) {
        return f->getMaterial()->getEmittedColor();
    } else if (mode == RENDER_UNDISTRIBUTED) { 
        return getUndistributed(i);
    } else if (mode == RENDER_ABSORBED) {
        return getAbsorbed(i);
    } else if (mode == RENDER_RADIANCE) {
        return getRadiance(i);
    } else if (mode == RENDER_FORM_FACTORS) {
        if (formfactors == NULL) ComputeFormFactors();
        double scale = 0.2 * total_area/getArea(i);
        double factor = scale * getFormFactor(max_undistributed_patch,i);
        return Vec3f(factor,factor,factor);
    } else {
        assert(0);
    }
    exit(0);
}
Example #3
0
// different visualization modes
glm::vec3 Radiosity::setupHelperForColor(Face *f, int i, int j) {
  assert (mesh->getFace(i) == f);
  assert (j >= 0 && j < 4);
  if (args->render_mode == RENDER_MATERIALS) {
    return f->getMaterial()->getDiffuseColor();
  } else if (args->render_mode == RENDER_RADIANCE && args->interpolate == true) {
    std::vector<Face*> faces;
    CollectFacesWithVertex((*f)[j],f,faces);
    float total = 0;
    glm::vec3 color = glm::vec3(0,0,0);
    glm::vec3 normal = f->computeNormal();
    for (unsigned int i = 0; i < faces.size(); i++) {
      glm::vec3 normal2 = faces[i]->computeNormal();
      float area = faces[i]->getArea();
      if (glm::dot(normal,normal2) < 0.5) continue;
      assert (area > 0);
      total += area;
      color += float(area) * getRadiance(faces[i]->getRadiosityPatchIndex());
    }
    assert (total > 0);
    color /= total;
    return color;
  } else if (args->render_mode == RENDER_LIGHTS) {
    return f->getMaterial()->getEmittedColor();
  } else if (args->render_mode == RENDER_UNDISTRIBUTED) { 
    return getUndistributed(i);
  } else if (args->render_mode == RENDER_ABSORBED) {
    return getAbsorbed(i);
  } else if (args->render_mode == RENDER_RADIANCE) {
    return getRadiance(i);
  } else if (args->render_mode == RENDER_FORM_FACTORS) {
    if (formfactors == NULL) ComputeFormFactors();
    float scale = 0.2 * total_area/getArea(i);
    float factor = scale * getFormFactor(max_undistributed_patch,i);
    return glm::vec3(factor,factor,factor);
  } else {
    assert(0);
  }
  exit(0);
}
Example #4
0
float Radiosity::Iterate() {
  if (formfactors == NULL) 
    ComputeFormFactors();
  assert (formfactors != NULL);




  // ==========================================
  // ASSIGNMENT:  IMPLEMENT RADIOSITY ALGORITHM
  // ==========================================

  //Compute the radiosity matrix. I feel like I shouldn't have to do this 
  //every time. Maybe this is what the form factors matrix was meant for

  //save the radiances
  std::vector<glm::vec3> radiations, absorbeds;
  for (int i=0; i<num_faces; i++){
    
    Face* face=mesh->getFace(i);
    glm::vec3 ro_i=face->getMaterial()->getDiffuseColor();
    glm::vec3 ones(1,1,1);
    glm::vec3 abso_i=ones-ro_i;

    glm::vec3 radiance=face->getMaterial()->getEmittedColor();
    glm::vec3 absorbed_i(0,0,0);//=getAbsorbed(i);
    for (int j=0; j<num_faces; j++){
      //new_row.push_back(-ro_i*getFormFactor(i,j))
      //might need to reverse that j,i
      radiance+=ro_i*getFormFactor(j,i)*getRadiance(j); 
      absorbed_i+=abso_i*getFormFactor(j,i)*getRadiance(j);

    } 
    //the undistributed light is the stuff we got on this iteration
    setUndistributed(i, radiance-getRadiance(i));  
    //std::cout<<glm::length(radiance)<<' ';
    
    radiations.push_back(radiance);
    absorbeds.push_back(absorbed_i);
  }

  //std::cout<<std::endl;
  //set the computed radiances
  for(int i=0; i<num_faces; i++){
    setRadiance(i, radiations[i]);
    setAbsorbed(i, absorbeds[i]);
  }
  //now we must calculate the undistributed light
  float total_undistributed = 0;
  glm::vec3 ambient;
  for (int i=0; i<num_faces;i++){
    total_undistributed+=glm::length(getUndistributed(i));
    ambient+=getUndistributed(i);
  }
  
  //uncomment this for the ambient lighting term. This implementation, while simple
  //breaks my visualization for undistributed
  #if 1
  ambient/=float(num_faces);
  for (int i=0; i<num_faces; i++){
    setRadiance(i, getRadiance(i)+ambient);
  }
  #endif

  // return the total light yet undistributed
  // (so we can decide when the solution has sufficiently converged)
  std::cout<<total_undistributed<<std::endl;
  return total_undistributed;




}
float Radiosity::Iterate() {
  if (formfactors == NULL) 
    ComputeFormFactors();
  assert (formfactors != NULL);




  // ==========================================
  // ASSIGNMENT:  IMPLEMENT RADIOSITY ALGORITHM
  // ==========================================

    //printf("\n\n");
    
    //take the thing with the most undistributed radiosity
    findMaxUndistributed();
    
    float totalUnd = 0;
    
    for(int j = 0; j<num_faces; j++)
    {
        if (j == max_undistributed_patch)
        {
            continue;
        }
        //use max_undistributed_patch for the thing giving away radience
        
        //the j panel absorbs some of the light and reflects the rest
        
        /*printf("MaxUndist: (%f %f %f)\tJDiffuseColor: (%f %f %f)\tAbsorbed: (%f %f %f)\tRadiance: (%f %f %f)\tUndistributed: (%f %f %f)\t\n\n", getUndistributed(max_undistributed_patch).x, getUndistributed(max_undistributed_patch).y, getUndistributed(max_undistributed_patch).z,
               mesh->getFace(j)->getMaterial()->getDiffuseColor().x, mesh->getFace(j)->getMaterial()->getDiffuseColor().y, mesh->getFace(j)->getMaterial()->getDiffuseColor().z,
               getAbsorbed(j).x, getAbsorbed(j).y, getAbsorbed(j).z,
               getRadiance(j).x, getRadiance(j).y, getRadiance(j).x,
               getUndistributed(j).x, getUndistributed(j).y, getUndistributed(j).z);//*/
        
        
        //give it to everyone else based on form factor
        setRadiance(j, getUndistributed(max_undistributed_patch)*(getFormFactor(max_undistributed_patch, j)/
                       totalFormFactori[max_undistributed_patch])*mesh->getFace(j)->getMaterial()->getDiffuseColor() +//- getAbsorbed(j) + *******INSTEAD OF GET ABSORBED THIS SHOULD BE PANEL COLOR)
                        getRadiance(j));//*/
        
        setAbsorbed(j,  (getUndistributed(max_undistributed_patch)*(1.0f-mesh->getFace(j)->getMaterial()->getDiffuseColor()))*
                    (getFormFactor(max_undistributed_patch, j)/totalFormFactori[max_undistributed_patch]) +
                    (getAbsorbed(j)));//*/
        
        setUndistributed(j, getUndistributed(max_undistributed_patch)*(getFormFactor(max_undistributed_patch, j)/
                            totalFormFactori[max_undistributed_patch])*mesh->getFace(j)->getMaterial()->getDiffuseColor() +
                         getUndistributed(j));//*/
        
        totalUnd += glm::length(getUndistributed(j));
        
        /*printf("MaxUndist: (%f %f %f)\tJDiffuseColor: (%f %f %f)\tAbsorbed: (%f %f %f)\tRadiance: (%f %f %f)\tUndistributed: (%f %f %f)\t\n", getUndistributed(max_undistributed_patch).x, getUndistributed(max_undistributed_patch).y, getUndistributed(max_undistributed_patch).z,
               mesh->getFace(j)->getMaterial()->getDiffuseColor().x, mesh->getFace(j)->getMaterial()->getDiffuseColor().y, mesh->getFace(j)->getMaterial()->getDiffuseColor().z,
               getAbsorbed(j).x, getAbsorbed(j).y, getAbsorbed(j).z,
               getRadiance(j).x, getRadiance(j).y, getRadiance(j).x,
               getUndistributed(j).x, getUndistributed(j).y, getUndistributed(j).z);
        
        printf("***************************************************************************************\n");//*/
        
        
        
    }
    //setRadiance(max_undistributed_patch, glm::vec3(0,0,0));
    setUndistributed(max_undistributed_patch, glm::vec3(0, 0, 0));
    
    
    
  //==============================================
  // return the total light yet undistributed
  //==============================================
    
  // (so we can decide when the solution has sufficiently converged)

    //printf("TotalUndistributed: %f", totalUnd);
    
  return totalUnd;




}
void Radiosity::ComputeFormFactors() {
  assert (formfactors == NULL);
  assert (num_faces > 0);
  formfactors = new float[num_faces*num_faces];


  // =====================================
  // ASSIGNMENT:  COMPUTE THE FORM FACTORS
  // =====================================

  //num_patches * num_patches = total number of subdivided areas for FF
  int num_patches = 9;

  //THIRD ATTEMPT
  for (int i = 0; i < num_faces; i++)
  {
	  float FFsum = 0;

	  for (int j = 0; j < num_faces; j++)
	  {
		  //std::cout << i << "\n";
		  //If it is the same face, FF = 0
		  if (i != j)
		  {
			  Face* iface = this->getMesh()->getFace(i);
			  Face* jface = this->getMesh()->getFace(j);
			  //Variables needed for subdivision of patches
			  //A is the starting corner of the patch, xvec is the length of one side of the patch
			  /*glm::vec3 iA, ixvec, iyvec;// , jA, jxvec, jyvec;
			  iA = (*iface)[0]->get();
			  ixvec = (*iface)[1]->get() - iA;
			  ixvec /= num_patches;
			  iyvec = (*iface)[3]->get() - iA;
			  iyvec /= num_patches;*/

			  //Normals of respective surfaces
			  glm::vec3 inormal = (*iface).computeNormal();
			  glm::vec3 jnormal = (*jface).computeNormal();

			  glm::vec3 ipoint = (*iface).computeCentroid();
			  glm::vec3 jpoint = (*jface).computeCentroid();
			  
			  //Ray from j to i
			  glm::vec3 ray = ipoint - jpoint;

			  float FFanswer = 0;

			  //Check for occlusion
			  Ray r(jpoint, ray);
			  Hit vhit = Hit();
			  raytracer->CastRay(r, vhit, false);
			  if (args->num_shadow_samples > 0 && vhit.getT() < glm::length(ray) * .95f)
			  {
				  //Occlusion
				  FFanswer = 0;
			  }
			  else
			  {
				  //Calculate Cos() for i and j, reversing the ray for i for angle calculation
				  float icos = glm::dot(inormal, -ray) / (glm::length(inormal) * glm::length(ray));
				  float jcos = glm::dot(jnormal, ray) / (glm::length(jnormal) * glm::length(ray));
				  //std::cout << glm::length(jnormal) << "\n";
				  //Calculate divisor for FF equation
				  float divisor = 3.14159 * glm::length(ray) * glm::length(ray);
				  FFanswer = (icos*jcos) / divisor;
				  FFanswer /= (*iface).getArea();
			  }
			  
			  FFsum += FFanswer;

			setFormFactor(i, j, FFanswer);
			  
			  
		  }
		  else
		  {
			  setFormFactor(i, j, 0);
			  //std::cout << "Face[" << i << "]: " << "0" << "\n";
		  }
		  
	  }
	  //std::cout << "Face[" << i << "] FFsum: " << FFsum << "\n";
	  float sumfix;
	  if (FFsum != 0)
	  {
		  sumfix = 1 / FFsum;
		  float Newsum = 0;
		  for (int j = 0; j < num_faces; j++)
		  {
			  float ff = getFormFactor(i, j);
			  ff *= sumfix;
			  //std::cout << ff << "\n";
			  setFormFactor(i, j, ff);
			  Newsum += ff;
		  }
		  //std::cout << "Face[" << i << "] Newsum: " << Newsum << "\n";
	  }
  }
}