コード例 #1
0
/**
 * Computes the radiance returned by tracing the ray r.
 */
void PhotonMapper::trace(const Ray& ray, int depth, const Color& flux)
{
	Intersection is;
	Color lIndirect = Color(0.0f, 0.0f, 0.0f);

	if (mScene->intersect(ray, is)){

		if (depth != 0){
			Hitpoint hp;
			hitpointBVH.intersect(is, flux);

			float type = uniform();

			float reflectivity = is.mMaterial->getReflectivity(is);
			float transparency = is.mMaterial->getTransparency(is);

			if (type <= reflectivity){
				trace(is.getReflectedRay(), depth + 1, flux);
				return;
			}
			else if (type - reflectivity <= transparency){
				trace(is.getRefractedRay(), depth + 1, flux);
				return;
			}
		}

		if (depth < maxDepth || uniform() > p_abs){
			float theta = acos(sqrt(1 - uniform()));
			float phi = 2 * M_PI * uniform();
			float x = sin(theta) * cos(phi);
			float y = sin(theta) * sin(phi);
			float z = cos(theta);

			Vector3D nvec(1.0f, 0.0f, 0.0f);
			Vector3D mvec(0.0f, 1.0f, 0.0f);

			Vector3D W = is.mNormal;
			W.normalize();
			Vector3D U = nvec % W;
			if (U.length() < 0.01f)
				U = mvec % W;
			Vector3D V = W % U;

			Vector3D dir = x * U + y * V + z * W;

			Ray ray2;
			ray2.orig = is.mPosition;
			ray2.dir = dir;
			Color addFlux = M_PI * is.mMaterial->evalBRDF(is, ray.dir) * flux * (is.mNormal * dir);
			
			if (depth >= maxDepth)
				addFlux *= abs_factor;

			trace(ray2, depth + 1, addFlux);
		}
	}
}
コード例 #2
0
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);
		}
	}
}