BSDF evaluate (const Diff_Geom& diff_geom_, float *lod) const { Color kd(m_kd); if (hasTexture()){ *lod = mTexture->computeMipmapLevel(diff_geom_.dTdx(), diff_geom_.dTdy()); kd = getTextureColor(diff_geom_.u(), diff_geom_.v(),*lod); } return BSDF::init_pure_refl (diff_geom_.normal(), kd, m_kr); }
/** * Triangle Intersection */ float Triangle::getIntersection(Vector3 eyeOrig, Vector3 delOrig, float startInterval, float endInterval, PixelInfo* intersection) { //transform e and d: Vector3 eye=((*inverseTransMat)*getV4(eyeOrig, 1)).xyz(); Vector3 del=((*inverseTransMat)*getV4(delOrig, 0)).xyz(); float alpha, beta, gamma; float t=triangleIntersection(eye, del, startInterval, endInterval, &alpha, &beta, &gamma, vertices[0].position, vertices[1].position, vertices[2].position); if(!t) return 0; if(intersection) { intersection->ambient=(alpha*(vertices[0].material->ambient)) + (beta*(vertices[1].material->ambient)) + (gamma*(vertices[2].material->ambient)); intersection->diffuse=(alpha*(vertices[0].material->diffuse)) + (beta*(vertices[1].material->diffuse)) + (gamma*(vertices[2].material->diffuse)); intersection->specular=(alpha*(vertices[0].material->specular)) + (beta*(vertices[1].material->specular)) + (gamma*(vertices[2].material->specular)); intersection->refractive_index=(alpha*(vertices[0].material->refractive_index)) + (beta*(vertices[1].material->refractive_index)) + (gamma*(vertices[2].material->refractive_index)); intersection->intersectionPoint=eyeOrig+(t*delOrig); intersection->normal=normalize((*normalMat)*(alpha*vertices[0].normal + beta*vertices[1].normal + gamma*vertices[2].normal)); // calculate texture color: Vector2 tex_coord=(alpha*vertices[0].tex_coord) + (beta*vertices[1].tex_coord) + (gamma*vertices[2].tex_coord); intersection->tex_coord=tex_coord; intersection->tex_color=alpha*getTextureColor(tex_coord, vertices[0].material)+ beta*getTextureColor(tex_coord, vertices[1].material)+ gamma*getTextureColor(tex_coord, vertices[2].material);//*/ } return t; }
/** * Intersection with sphere * If intersects twice only return the smaller t */ float Sphere::getIntersection(Vector3 eOrig, Vector3 dOrig, float startInterval, float endInterval, PixelInfo* intersection) { //transform e and d: Vector3 e=((*inverseTransMat)*getV4(eOrig, 1)).xyz(); Vector3 d=((*inverseTransMat)*getV4(dOrig, 0)).xyz(); real_t dDot = dot(d, d); Vector3 eMinusC = e-((*inverseTransMat)*getV4(position, 1)).xyz(); float radical= pow(dot(d, eMinusC), 2) - (dDot*(dot(eMinusC,eMinusC)-pow(radius,2))); if(radical<0)//if no intersection return 0; radical=sqrt(radical); float a=(dot((d*-1),eMinusC)-radical)/dDot; float b=(dot((d*-1),eMinusC)+radical)/dDot; //check out of bounds intersections: if((a<startInterval || a>endInterval) && (b<startInterval || b>endInterval)) return 0; if(a<startInterval || a>endInterval) return b; if(b<startInterval || b>endInterval) return a; float t = a;//return min of a,b if(b<a) t=b; if(intersection) { intersection->ambient=material->ambient; intersection->diffuse=material->diffuse; intersection->specular=material->specular; intersection->refractive_index=material->refractive_index; intersection->intersectionPoint=eOrig + (t*dOrig); intersection->normal=normalize((*normalMat)*(intersection->intersectionPoint-position)); // this math from cse.msu.edu/~cse872/tutorial4.html float tx = atan2(intersection->normal.x, intersection->normal.z) / (2. * PI) + 0.5; float ty = asin(intersection->normal.y) / PI + .5; intersection->tex_coord=Vector2(tx, ty); intersection->tex_color=getTextureColor(intersection->tex_coord, material); } return t; }
Color lambertian(Ray normal, const Scene* s, Sphere* sphere, Plane* plane) { Color result; result.r = 0; result.g = 0; result.b = 0; bool blocked; for(int i = 0; i < s->lights.size(); i++) { blocked = false; Light current_light = s->lights.at(i); Ray lightRay; lightRay.p0 = current_light.origin; lightRay.dir = sub(normal.p0, current_light.origin); lightRay.dir = normalize(lightRay.dir); // check that point of interest is not shadowed by other objects float distFromLight = dist(normal.p0, current_light.origin); float distClosestObject = fInfinity; // distance between light and closest object along ray to normal initial point for(int k = 0; k < s->planes.size(); k++) { Plane current_plane = s->planes.at(k); if(!areEqual(¤t_plane, plane)) { distClosestObject = plane_intersect(¤t_plane, &lightRay); // check if current object would block the light if(distClosestObject < distFromLight) { blocked = true; break; } } } for(int k = 0; k < s->spheres.size(); k++) { Sphere current_sphere = s->spheres.at(k); if(!areEqual(¤t_sphere, sphere)) { distClosestObject = sphere_intersect(¤t_sphere, &lightRay); // check if current object would block the light if(distClosestObject < distFromLight) { blocked = true; break; } } } // check that the light source isn't behind the object Vec3 lv = lightRay.dir; Vec3 nv = normalize(normal.dir); if(dot(lv, nv) > 0.0) blocked = true; if(!blocked) { // add this light's contribution to the pixel color float coef = abs(dot(lv, nv)); if(sphere != NULL) { result.r += (sphere->material.color.r * current_light.color.r) * coef; result.g += (sphere->material.color.g * current_light.color.g) * coef; result.b += (sphere->material.color.b * current_light.color.b) * coef; } else if(plane != NULL) { if(plane->hastexture) { Color textureColor = getTextureColor(getTexel(normal,plane),plane); result.r += textureColor.r * current_light.color.r * coef; result.g += textureColor.g * current_light.color.g * coef; result.b += textureColor.b * current_light.color.b * coef; } else { result.r += (plane->material.color.r * current_light.color.r) * coef; result.g += (plane->material.color.g * current_light.color.g) * coef; result.b += (plane->material.color.b * current_light.color.b) * coef; } } } } return result; }
Vector3 PencilShader::shade(const Ray& ray, const HitInfo& hit, const Scene& scene) const { int m = 0; int totalRays = 0; float step = (float)RAD_H/SAMPLES; std::vector<Vector3> normals; std::vector<HitInfo> hits; for(float r = step; r <= RAD_H; r+=step){ float theta_step = (2.0*M_PI)/(pow(2, r+2)); for(float theta = 0; theta <= 2.0*M_PI; theta += theta_step){ totalRays++; float x = r*cos(theta); float y = r*sin(theta); Ray stencilRay; Vector3 dir = Vector3(ray.d); dir.x += x; dir.y += y; stencilRay.o = ray.o; stencilRay.d = dir; HitInfo h; if(scene.trace(h, stencilRay)){ if(h.objId != hit.objId){ m++; } else{ normals.push_back(Vector3(h.N)); hits.push_back(h); } } else m++; } } //Hit other geometry, outline edge if(m > 0){ return Vector3(0.0f); } float gradient = 0.0; //Check for creases or silhouettes for(int i = 0; i <= normals.size(); i++){ gradient += (dot(normals[i], hit.N))/normals.size(); if(gradient < 0.01) return Vector3(0.0f); } Vector3 L = Vector3(0.0f, 0.0f, 0.0f); const Lights *lightlist = scene.lights(); Ray shadow; shadow.o = hit.P - ray.o; Lights::const_iterator lightIter; for (lightIter = lightlist->begin(); lightIter != lightlist->end(); lightIter++) { PointLight* pLight = *lightIter; Vector3 l = pLight->position() - hit.P; // the inverse-squared falloff float falloff = l.length2(); // normalize the light direction l /= sqrt(falloff); // get the diffuse component shadow.d = l; float nDotL = dot(hit.N, l); //Map into color location L += getTextureColor(nDotL, hit); } return L; }
Rgb cylindre::getColor(vector3 currPoint) { if (texture != NULL) return getTextureColor(currPoint); else return material->getColor(); }