Color PhotonMapping::doShading(Ray& ray) { Vec3f hitPoint=ray.origin+ray.distance*ray.direction; Vec3f normal=ray.hitObject->getNormal(hitPoint); Material& material=ray.hitObject->getMaterial(); if(material.reflectiveRate>0.0f){ Ray reflectRay; reflectRay.origin=hitPoint; reflectRay.direction=ray.direction-2.0f*dot(normal,ray.direction)*normal; reflectRay.hitObject=ray.hitObject; reflectRay.distance=INFINITY; topGroup->intersection(reflectRay); if(reflectRay.hitObject == ray.hitObject){ //hit nonthing return Color(0.0f,0.0f,0.0f); } return doShading(reflectRay); } Color color(0.0f,0.0f,0.0f); boost::ptr_vector<Light>::iterator light; boost::ptr_vector<Light>& lights=scene.getLights(); for (light=lights.begin();light < lights.end(); light++){ Vec3f lightVector=light->getLightVector(hitPoint); float distance=abs(lightVector); lightVector/=distance; //constant linear quadratic float attenuation= 1.0f / (light->attenuation(0)+light->attenuation(1)*distance +light->attenuation(2)*distance*distance); //float attenuation=1.0f; Color ambient=light->ambient*material.ambient*attenuation; color+=ambient; float normalLight=dot(normal,lightVector); if (normalLight<=0.0f) continue; Ray shadowRay; shadowRay.origin=hitPoint; shadowRay.direction=lightVector; shadowRay.distance=distance; shadowRay.hitObject=ray.hitObject; topGroup->intersection(shadowRay); if(shadowRay.distance < distance) //in shadow continue; Color diffuse=light->diffuse*(material.diffuse)*(normalLight*attenuation); if(material.exponent!=0.0f){ Vec3f halfVector=lightVector-ray.direction; //halfVector.normalize(); //change to new math library halfVector/=abs(halfVector); float half=std::max(0.0f, dot(normal,halfVector)); float powerFactor=std::pow(half, material.exponent); Color specular=light->specular*material.specular*powerFactor*attenuation; color+=specular; } color+=diffuse; } return color; }
void Rasterization( GzRender * render, GzCoord * vertex, GzCoord * normXY) { float temp1=0.0,temp2=0.0,temp3=0.0,temp4=0.0,m=0.0,midPoint=0.0; triEdge tEdges[3]; int flag =0; int defVertex[3]={0,1,2}; float xDiffE0,yDiffE0,zDiffE0,xDiffE1,yDiffE1,zDiffE1,xDiffE2,yDiffE2,zDiffE2; float A,B,C,D; float a0,b0,c0,a1,b1,c1,a2,b2,c2; float lowerX=99999999.0,lowerY=99999999.0,upperX=0.0,upperY=0.0; float v0,v1,v2,v; GzIntensity r,g,b,a; GzDepth z; //First sort the vertices by Y if Y is same sort it according to X sortTriangle(vertex,&defVertex[0]); //Assign edge in CCW if(vertex[0][1]== vertex[1][1]) { tEdges[0].x1= vertex[1][0]; tEdges[0].x2= vertex[0][0]; tEdges[0].y1= vertex[1][1]; tEdges[0].y2= vertex[0][1]; tEdges[0].z1= vertex[1][2]; tEdges[0].z2= vertex[0][2]; tEdges[1].x1= vertex[0][0]; tEdges[1].x2= vertex[2][0]; tEdges[1].y1= vertex[0][1]; tEdges[1].y2= vertex[2][1]; tEdges[1].z1= vertex[0][2]; tEdges[1].z2= vertex[2][2]; tEdges[2].x1= vertex[2][0]; tEdges[2].x2= vertex[1][0]; tEdges[2].y1= vertex[2][1]; tEdges[2].y2= vertex[1][1]; tEdges[2].z1= vertex[2][2]; tEdges[2].z2= vertex[1][2]; tEdges[0].tl= defVertex[1]; tEdges[0].hd= defVertex[0]; tEdges[1].tl= defVertex[0]; tEdges[1].hd= defVertex[2]; tEdges[2].tl= defVertex[2]; tEdges[2].hd= defVertex[1]; } if(vertex[1][1]== vertex[2][1]) { tEdges[0].x1= vertex[0][0]; tEdges[0].x2= vertex[1][0]; tEdges[0].y1= vertex[0][1]; tEdges[0].y2= vertex[1][1]; tEdges[0].z1= vertex[0][2]; tEdges[0].z2= vertex[1][2]; tEdges[1].x1= vertex[1][0]; tEdges[1].x2= vertex[2][0]; tEdges[1].y1= vertex[1][1]; tEdges[1].y2= vertex[2][1]; tEdges[1].z1= vertex[1][2]; tEdges[1].z2= vertex[2][2]; tEdges[2].x1= vertex[2][0]; tEdges[2].x2= vertex[0][0]; tEdges[2].y1= vertex[2][1]; tEdges[2].y2= vertex[0][1]; tEdges[2].z1= vertex[2][2]; tEdges[2].z2= vertex[0][2]; tEdges[0].tl= defVertex[0]; tEdges[0].hd= defVertex[1]; tEdges[1].tl= defVertex[1]; tEdges[1].hd= defVertex[2]; tEdges[2].tl= defVertex[2]; tEdges[2].hd= defVertex[0]; } else { float slope=0.0; slope= ( vertex[2][1] - vertex[0][1] ) / ( vertex[2][0] - vertex[0][0] ); midPoint=vertex[0][0]+( ( vertex[1][1] - vertex[0][1] ) / slope ) ; if( vertex[1][0]< midPoint ) { tEdges[0].x1= vertex[0][0]; tEdges[0].x2= vertex[1][0]; tEdges[0].y1= vertex[0][1]; tEdges[0].y2= vertex[1][1]; tEdges[0].z1= vertex[0][2]; tEdges[0].z2= vertex[1][2]; tEdges[1].x1= vertex[1][0]; tEdges[1].x2= vertex[2][0]; tEdges[1].y1= vertex[1][1]; tEdges[1].y2= vertex[2][1]; tEdges[1].z1= vertex[1][2]; tEdges[1].z2= vertex[2][2]; tEdges[2].x1= vertex[2][0]; tEdges[2].x2= vertex[0][0]; tEdges[2].y1= vertex[2][1]; tEdges[2].y2= vertex[0][1]; tEdges[2].z1= vertex[2][2]; tEdges[2].z2= vertex[0][2]; tEdges[0].tl= defVertex[0]; tEdges[0].hd= defVertex[1]; tEdges[1].tl= defVertex[1]; tEdges[1].hd= defVertex[2]; tEdges[2].tl= defVertex[2]; tEdges[2].hd= defVertex[0]; } else if( vertex[1][0]>midPoint ) { tEdges[0].x1= vertex[0][0]; tEdges[0].x2= vertex[2][0]; tEdges[0].y1= vertex[0][1]; tEdges[0].y2= vertex[2][1]; tEdges[0].z1= vertex[0][2]; tEdges[0].z2= vertex[2][2]; tEdges[1].x1= vertex[2][0]; tEdges[1].x2= vertex[1][0]; tEdges[1].y1= vertex[2][1]; tEdges[1].y2= vertex[1][1]; tEdges[1].z1= vertex[2][2]; tEdges[1].z2= vertex[1][2]; tEdges[2].x1= vertex[1][0]; tEdges[2].x2= vertex[0][0]; tEdges[2].y1= vertex[1][1]; tEdges[2].y2= vertex[0][1]; tEdges[2].z1= vertex[1][2]; tEdges[2].z2= vertex[0][2]; tEdges[0].tl= defVertex[0]; tEdges[0].hd= defVertex[2]; tEdges[1].tl= defVertex[2]; tEdges[1].hd= defVertex[1]; tEdges[2].tl= defVertex[1]; tEdges[2].hd= defVertex[0]; } } xDiffE0=tEdges[0].x2 - tEdges[0].x1; xDiffE1= tEdges[1].x2 - tEdges[1].x1; xDiffE2=tEdges[2].x2 - tEdges[2].x1; yDiffE0= tEdges[0].y2 - tEdges[0].y1; yDiffE1=tEdges[1].y2 - tEdges[1].y1; yDiffE2=tEdges[2].y2 - tEdges[2].y1; zDiffE0= tEdges[0].z2 - tEdges[0].z1; zDiffE1= tEdges[1].z2 - tEdges[1].z1; zDiffE2=tEdges[2].z2-tEdges[1].z1; //Find ABC value for the line equation a0 = yDiffE0; a1 = yDiffE1; a2 =yDiffE2; b0 = -xDiffE0; b1 = -xDiffE1; b2 = -xDiffE2; c0 = xDiffE0 * tEdges[0].y1 - yDiffE0 * tEdges[0].x1 ; c1 = xDiffE1 * tEdges[1].y1 - yDiffE1 * tEdges[1].x1 ; c2 = xDiffE2* tEdges[2].y1 - yDiffE2 * tEdges[2].x1 ; //Find Ax+By+Cz+d=0 float temp=0.0; A = yDiffE0 * zDiffE1 - zDiffE0 * yDiffE1; B = - xDiffE0 * zDiffE1 + zDiffE0 * xDiffE1 ; C = xDiffE0 * yDiffE1 - yDiffE0 * xDiffE1; temp=A* vertex[0][0] + B* vertex[0][1] + C* vertex[0][2]; D=-temp; //Find the bounding box for the triangle //construct bounding box createBoundingBox(vertex,&lowerX,&lowerY,&upperX,&upperY); if(render->interp_mode== GZ_NORMALS) { getPlaneCoeff(tEdges,normXY); } else if(render->interp_mode== GZ_COLOR) { GzColor c[3]; memset(c,0,sizeof(GzColor)*3); for( int p =0; p <3; p++ ) doShading(render,c[p],normXY[p]); getPlaneCoeff(tEdges,c); } //Check for each pixel within the bounding box whether it lies in the triangle for(int i=lowerY;i<= upperY; i++ ) { for(int j=lowerX;j<= upperX; j++ ) { GzIntensity r, g, b, a; GzDepth z; v =-(A*j+B*i+D)/C; v0 = a0 * j + b0 * i + c0; v1 = a1 * j + b1 * i + c1; v2 = a2 * j + b2 * i + c2; if(v<0||v0<0||v1<0||v2<0) continue; GzGetDisplay( render->display, j, i, &r, &g, &b, &a, &z ); //Check with prev Z vaule GzColor q; for(int k=0;k<3;k++) q[k] = -( pCof[k].planeA * j + pCof[k].planeB * i + pCof[k].planeD ) / pCof[k].planeC; if(render->interp_mode == GZ_FLAT) { for(int k=0;k<3;k++) q[k] = render->flatcolor[k]; if( v < z || z==0) GzPutDisplay(render->display,j,i,ctoi(q[0]),ctoi(q[1]),ctoi(q[2]),a,(GzDepth )v); } if(render->interp_mode == GZ_COLOR) { if( v < z || z==0) GzPutDisplay(render->display,j,i,ctoi(q[0]),ctoi(q[1]),ctoi(q[2]),a,(GzDepth )v); } else if(render->interp_mode == GZ_NORMALS) { GzColor c; memset(c,0,sizeof(GzColor)); getNormal(q); doShading(render,c,q); if( v < z || z==0) GzPutDisplay(render->display,j,i,ctoi(c[0]),ctoi(c[1]),ctoi(c[2]),a,(GzDepth )v); } } } }