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; }
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); }
// 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); }
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"; } } }