void PhotonMapper::forwardPassRay(Ray ray, int x, int y, float weight, int depth){ Intersection is; if (weight > 0 && depth < maxForwardPassDepth && mScene->intersect(ray, is)){ Hitpoint* hp = new Hitpoint(); hp->pixelX = x; hp->pixelY = y; hp->is = is; hp->radius = startRadius; Color reflectedC, refractedC, emittedC; Material* m = is.mMaterial; float reflectivity = m->getReflectivity(is); float transparency = m->getTransparency(is); float diffuse = (1.0f - reflectivity - transparency)*weight; hp->pixelWeight = (1.0f - reflectivity - transparency) * weight; if (reflectivity > 0.0f) { Ray reflectedRay = is.getReflectedRay(); forwardPassRay(reflectedRay, x, y, reflectivity * weight, depth+1); } if (transparency > 0.0f) { Ray refractedRay = is.getRefractedRay(); forwardPassRay(refractedRay, x, y, transparency * weight, depth+1); } if (diffuse){ for (int i = 0; i < mScene->getNumberOfLights(); ++i){ PointLight* l = mScene->getLight(i); if (!mScene->intersect(is.getShadowRay(l))){ Vector3D lightVec = l->getWorldPosition() - is.mPosition; float d2 = lightVec.length2(); lightVec.normalize(); Color radiance = l->getRadiance(); Color brdf = is.mMaterial->evalBRDF(is, lightVec); float angle = max(lightVec * is.mNormal, 0.0f); hp->directIllumination += radiance * brdf * angle / d2; } } vec.push_back(hp); } } }
void PhotonMapper::photonTracingPass(){ for (int i = 0; i < mScene->getNumberOfLights(); ++i){ PointLight* l = mScene->getLight(i); for (int i = 0; i < numberPhotons; ++i){ Vector3D dir(uniform() * 2 - 1, uniform() * 2 - 1, uniform() * 2 - 1); while(dir.length2() > 1.0f){ dir = Vector3D(uniform() * 2 - 1, uniform() * 2 - 1, uniform() * 2 - 1); } dir.normalize(); Ray ray; ray.orig = l->getWorldPosition(); ray.dir = dir; Color startFlux = l->getRadiance() * 4.0f * M_PI; trace(ray, 0, startFlux); } } }