TracePixel traceRay(RayPixel ray, Octree& tree){ vector<int> leaves; leaves.reserve(512); tree.trace(leaves,ray.r,false); float sum = 0; for (int k = 0; k < leaves.size(); k++) { sum += tree.nodes[leaves[k]].val; } return TracePixel(ray.x, ray.y, sum); }
bool RayTracer::RunRayTrace() { for(int y=0; y<FRAME_HEIGHT; y++) { for(int x=0; x<FRAME_WIDTH; x++) { Ray ray; computeRayDir(x, y, &ray); frame[y][x] = TracePixel(&ray, NULL, 0); } } if(!saveImage()) { #ifdef _WIN32 MessageBoxA( NULL, "Mesh Init Failure", "Error", MB_OK ); #endif cerr << "Mesh Init Failure" << endl; return false; } return true; }
RayTracer::Pixel RayTracer::TracePixel(Ray* ray, ModelClass* reflectedObject, int depth) { Pixel finalColor = {0.0f, 0.0f, 0.0f}; ModelClass* intersectObject = NULL; Vector3 normal, viewDirection, hitPoint; if(depth == MAX_RAY_BOUNCE) { //You hit the max amount of reflections finalColor.r = 0.0f; finalColor.g = 0.0f; finalColor.b = 0.0f; return finalColor; } intersectObject = mThreeDGraphics->computeIntersection(*ray, mCamera, reflectedObject, &hitPoint, &normal, &viewDirection); if(intersectObject == NULL) { //Didnt intersect anything finalColor.r = 0.0f; finalColor.g = 0.0f; finalColor.b = 0.0f; } else{ if(depth == 1) { int i = 0; } //Compute illum Ray shadowRay; bool inShadow = false; shadowRay.origin = hitPoint; shadowRay.direction = *mLight->getPosition() - hitPoint; inShadow = mThreeDGraphics->computeShadowIntersection(shadowRay, mCamera, intersectObject); if(!inShadow) { //Do lighting calc float diffuseCoefficient; Vector3 intersectObjectColor, lightDir, reflection; Vector4 specularColor, finalLightColor, outputColor; intersectObjectColor = intersectObject->getColor(); //Init the specular color specularColor = Vector4(); //Minimum brightness that the pixel must be set to outputColor = *(mLight->getAmbientLight()); //Invert the light direction lightDir = (*mLight->getDirection())*-1; //Calc the amount of light on this pixel diffuseCoefficient = normal.dot(lightDir); diffuseCoefficient = clamp(diffuseCoefficient); if(diffuseCoefficient > 0.0f) { //Find the final diffuse light color if the object isnt pointing away from the light source outputColor += (*mLight->getDiffuseColor() * diffuseCoefficient); outputColor.clamp(); //Calculate the reflection vector vased on the light intensity, normal vector and light direction reflection = normal*(2*diffuseCoefficient); reflection = reflection - lightDir; reflection.normalize(); //Determine the amount of specular light based on the reflection vector, viewing direction and specular power float specularCoefficient = reflection.dot(viewDirection); specularCoefficient = clamp(specularCoefficient); specularCoefficient = pow(specularCoefficient, mLight->getSpecularPower()); specularColor = *(mLight->getSpecularColor())*specularCoefficient; } //Find the final color by multing the lightColor with the texture color outputColor = outputColor*vec4(intersectObjectColor); //Add the specular component to the final color outputColor = outputColor + specularColor; Pixel reflectionColor = {0.0f, 0.0f, 0.0f}; if(depth < MAX_RAY_BOUNCE) { //Compute reflection Ray reflectionRay; float c1 = -1*normal.dot(ray->direction); reflectionRay.direction = ray->direction + ((normal*2)*c1); reflectionRay.origin = hitPoint; reflectionColor = TracePixel(&reflectionRay, intersectObject, depth+1); } outputColor = outputColor + Vector4(reflectionColor.r/mLight->getSpecularPower(), reflectionColor.g/mLight->getSpecularPower(), reflectionColor.b/mLight->getSpecularPower(), 1.0f); outputColor.clamp(); //Convert to pixel format finalColor.r = outputColor.x; finalColor.g = outputColor.y; finalColor.b = outputColor.z; } else{ //In shadow finalColor.r = 0.0f; finalColor.g = 0.0f; finalColor.b = 0.0f; } } return finalColor; }