SP2View::SP2View(SoECSP2 *sp2, QWidget *parent): QGroupBox(parent), ui(new Ui::SP2View) { ui->setupUi(this); m_sp2=sp2; busy(m_sp2->Owner()->IsBusy()); connect(m_sp2->Owner(),SIGNAL(busy(bool)),this, SLOT(busy(bool))); for(int i=0; i<sp2->Owner()->Number(sp2);i++){ SObject *so=sp2->Owner()->at(i); if(so->Is(SOT_SPAxis))ui->AxTree->addTopLevelItem(new SObjectTreeWidgetItem(so,NULL,false)); } refr(); }
Color trace(Ray& ray, int i){ if(!i) return Color(0,0,0); Obj* o; Vector x; Vector n; if(firstIntersect(ray, x, n, &o)<0) return La; Color c=directLight(ray.dir,x,n,o->mat); if(!o->mat.reflective&&!o->mat.refractive){ double px=(x.x/4+0.5)*phms; double py=(x.y/4+0.5)*phms; double u=px-(int)px; double v=py-(int)py; Color f=ph2((int)px, (int)py)*(1-u)*(1-v)+ ph2((int)px+1, (int)py)*(u)*(1-v)+ ph2((int)px, (int)py+1)*(1-u)*(v)+ ph2((int)px+1, (int)py+1)*(u)*(v); c=c+f*(5000./phLim); } if(o->mat.reflective) { Vector refd=reflectDir(ray.dir,n)+x; Ray ref(x,refd); if(o->mat.refractive){ bool valid=true; Vector refrd=refractDir(ray.dir,n,o->mat.n.r,valid); if(valid){ c=c+fresnel(ray.dir,n,o->mat,false)*trace(ref,i-1); } else { c=c+trace(ref,i-1); } } else { c=c+fresnel(ray.dir,n,o->mat,false)*trace(ref,i-1); } } if(o->mat.refractive){ bool valid=true; Vector refrd=refractDir(ray.dir,n,o->mat.n.r,valid)+x; if(valid){ Ray refr(x,refrd); c=c+fresnel(ray.dir,n,o->mat,true)*trace(refr,i-1); } } return c; }
void shoot(const Color& pow, Ray& ray, int i){ if(i>8) return; Obj* o; Vector x; Vector n; if(firstIntersect(ray, x, n, &o)<0) return; if(i&&!o->mat.reflective&&!o->mat.refractive){ if(n*ray.dir<0){ addPhoton(x, pow*(n*ray.dir*-1)); } return; } if(o->mat.reflective) { Vector refd=reflectDir(ray.dir,n)+x;; Ray ref(x,refd); if(o->mat.refractive){ bool valid=true; Vector refrd=refractDir(ray.dir,n,o->mat.n.r,valid); if(valid){ shoot(pow*fresnel(ray.dir,n,o->mat,false), ref, i+1); } else { shoot(pow, ref, i+1); } } else { shoot(pow*fresnel(ray.dir,n,o->mat,false), ref, i+1); } } if(o->mat.refractive){ bool valid=true; Vector refrd=refractDir(ray.dir,n,o->mat.n.r,valid)+x; if(valid){ Ray refr(x,refrd); shoot(pow*fresnel(ray.dir,n,o->mat,true), refr, i+1); } } }
void DisplayClass::traceRay(glm::vec3* color, int depth, glm::vec3 P, glm::vec3 V, float currentRI, float oldRI, glm::vec3 lcol) { if (depth > 5) { color->x = rayAmbientCol->x; color->y = rayAmbientCol->y; color->z = rayAmbientCol->z; return; } Node* n = getIntersectionObject(P, V); if (n == NULL) { color->x = rayAmbientCol->x; color->y = rayAmbientCol->y; color->z = rayAmbientCol->z; return; } //find intersection glm::vec3 intersection = P + (((float) *n->t) * V); //get material float* mt; switch(*n->mtl) { case 1: mt = mtl1; break; case 2: mt = mtl2; break; case 3: mt = mtl3; break; case 4: mt = mtlf; break; } glm::vec3 N = glm::normalize(*n->normal); //compute normal at intersection point //if (N.x < 0.0001f && N.x > -0.0001f && N.y < 0.0001f && N.y > -0.0001f && N.z < 1.0001f && N.z > 0.9999f) { // std::cout << "Noisy!" << std::endl; //} glm::vec3 Rd = glm::normalize(glm::reflect(V, N)); //compute reflected ray direction float RI = mt[6]; glm::vec3 Rfn = N; //if reflective, make recursive call glm::vec3 spec(0.0f, 0.0f, 0.0f); if (mt[4] > 0.0f) { glm::vec3* reflectedColor = new glm::vec3(); traceRay(reflectedColor, depth + 1, intersection + 0.001f * Rd, Rd, currentRI, oldRI, glm::vec3(lcol.x * mt[0], lcol.y * mt[1], lcol.z * mt[2])); spec = *reflectedColor; delete reflectedColor; } glm::vec3 refr(0.0f, 0.0f, 0.0f); glm::vec3 Rf; glm::vec3 tcol; float insFl = -1.0f; if (mt[5] > 0.0f) { insFl = glm::dot(N, V); tcol = glm::vec3(lcol.x * mt[0], lcol.y * mt[1], lcol.z * mt[2]); if (insFl > -0.0001f) { Rfn = -1.0f * N; //tcol = lcol; //RI = 1.0f; } if (currentRI == 1.0f) { oldRI = RI; } float eta = currentRI/oldRI; Rf = glm::normalize(glm::refract(V, Rfn, eta)); glm::vec3* refractedColor = new glm::vec3(); traceRay(refractedColor, depth + 1, intersection + 0.001f * Rf, Rf, oldRI, currentRI, glm::vec3(lcol.x * mt[0], lcol.y * mt[1], lcol.z * mt[2])); refr = *refractedColor; delete refractedColor; } //ambient color color->x = rayAmbientCol->x * mt[0]; color->y = rayAmbientCol->y * mt[1]; color->z = rayAmbientCol->z * mt[2]; //*color = *color * 0.2f; *color = glm::clamp(*color, 0.0f, 1.0f); if (mt[5] > 0.0f) { *color = *color + refr; *color = ((1.0f - mt[4]) * glm::clamp(*color, 0.0f, 1.0f)) + (mt[4] * glm::clamp(spec, 0.0f, 1.0f)); /*float cosT = glm::dot(Rf, V); //2.0f * glm::dot(-1.0f * Rfn, V); float rcoef = glm::clamp(pow(1.0f - cosT, 5), 0.0f, 1.0f); *color = glm::clamp(((1.0f - rcoef) * *color) + (rcoef * tcol), 0.0f, 1.0f);*/ return; } //light ray glm::vec3 L; glm::vec3 R; glm::vec3 finalCol; glm::vec3 ambientCol = *color; glm::vec3 totalCol(0.0f, 0.0f, 0.0f); for (int lc = 0; lc < 3; lc++) { L = glm::normalize(*rayLightPos->at(lc) - intersection); R = glm::reflect(-1.0f * L, N); //cast ray for shadow glm::vec3 blockob; Node* blocker = getIntersectionObject(*rayLightPos->at(lc), -1.0f * L); if (blocker != NULL) { blockob = *rayLightPos->at(lc) - (((float) *blocker->t) * L); } float di = glm::length(blockob - intersection); //if not shadowed, add more color if (blocker == NULL || (di < 0.0001f && di > -0.0001f)) { //diffuse color glm::vec3 diffuseColor = glm::clamp(glm::vec3(mt[0] * rayLightCol->at(lc)->x, mt[1] * rayLightCol->at(lc)->y, mt[2] * rayLightCol->at(lc)->z), 0.0f, 1.0f); //specular term float specTerm = glm::clamp(pow(glm::dot(V, R), mt[3]), 0.0f, 1.0f); //diffuse term float diffuseTerm = glm::clamp(glm::dot(N, L), 0.0f, 1.0f); //final color weighted calculation //blinn-phong finalCol = ambientCol + (glm::clamp(diffuseTerm * diffuseColor, 0.0f, 1.0f) * 0.6f) + (glm::clamp(spec + specTerm * *rayLightCol->at(lc), 0.0f, 1.0f) * 0.2f); totalCol = totalCol + finalCol; *color = totalCol; } } //reflectivity-weighted *color = ((1.0f - mt[4]) * glm::clamp(*color, 0.0f, 1.0f)) + (mt[4] * glm::clamp(spec, 0.0f, 1.0f)); }
void SP2View::on_sety_clicked() { SoSPAxis *ax=SelectedAxis(); if(ax!=NULL)m_sp2->SetYAxis(ax); refr(); }