Esempio n. 1
0
const ColorRGB Scene3D::traceRay(const Ray& ray, int depth) const
{

	float closest_t_value = NO_INTERSECT;
	const SceneObject* closest_object = findClosest(ray, closest_t_value);

	if (closest_object == 0)
		return ColorRGB(0,0,0);

	ColorRGB retColor(0,0,0);


	for (int i = 0; i < lights.size(); i++)
	{
		Vector3D normL = ((*lights[i]).get_position()-ray.getPointAt(closest_t_value)).normalize();
		Vector3D normN = (*closest_object).surface_normal(ray.getPointAt(closest_t_value));

		retColor += (*lights[i]).get_color()*(*closest_object).get_color()*std::max((normL*normN),float(0));
		
		if (depth < 6 && (*closest_object).get_reflectivity() > 0)
		{
				Ray reflected_ray = ray.reflect(ray.getPointAt(closest_t_value), (*closest_object).surface_normal(ray.getPointAt(closest_t_value)));
				ColorRGB reflection_color = traceRay(reflected_ray, depth+1);
				retColor+= (*closest_object).get_reflectivity()*reflection_color;
		}
		
	}	


	return retColor;
}
Esempio n. 2
0
Spectrum IntegratorHelpers::radianceDirect(const Scene* scene, const Ray& ray,
    const RaySurfIntersection& hit, const IntegratorHelpers::SpectralStrategy& ss)
{
    //Memory for output spectrum
    //TODO: Remove all dynamic memory allocations from rendering inner loop
    //...for now this is still in here for east of implementation
    float* buf = new float[ss.numSpectralSamples];
    for(int i = 0; i < ss.numSpectralSamples; i++){
        buf[i] = 0.0f;
    }

    //Return spectrum
    Spectrum retColor(buf, ss.nmMin, ss.nmMax, ss.nmStep, ss.numSpectralSamples);

    //Create relavent params
    const Vector omega_o(-ray.getDir());
    const Vector vecN(hit.n.x, hit.n.y, hit.n.z);
    const AccelStructure* geom = scene->getSceneGeom(); //Scene acceleration structure
    const bool isEmitter = hit.shp->isEmitter();
    const Point hitLocWS(hit.locWS);

    //Determine the maximum number of light samples we will make
    //and allocate this memory OUTSIDE of the light loop
    int NLightSampsMax = -1;
    for(size_t i = 0; i < scene->getNumLights(); i++){
        NLightSampsMax = std::max<int>(
            NLightSampsMax,
            scene->getLight(i)->getRecNumVisibilitySamples());
    }
    Point* samps = new Point[NLightSampsMax];

    //Process each light individually
    for(size_t i = 0; i < scene->getNumLights(); i++){
        Light* l = scene->getLight(i);

        //Skip sampling the light itself if the geometry is an emitter
        if(isEmitter && hit.shp->getEmitter() == l){
            continue;
        }

        //Sample the light source potentially many times
        const int N = l->getRecNumVisibilitySamples();
        l->getSamples(samps, N);


        //Loop over all light samples
        const float invNumSamps = 1.0f / float(N);
        for(int j = 0; j < N; j++){

            //Check if we can see the light
            VisibilityTester visTest(hitLocWS, samps[j], l->getGeom(),
                geom, DFLT_RAY_MOVE_EPSILON);
            //visTest.r is a ray to the light from hitLocWS

            //Get the incident radiance from the light at the hit location
            Spectrum L = l->sampleIncidentRadiance(hitLocWS, vecN, samps[j]);
            //TODO: "continue" here if the spectrum is black...is this any faster?


            //If we saw the light, add its contribution
            bool sawLight = visTest.visible(NULL);
            if(sawLight){
                //Vector to light
                const Vector omega_i(visTest.r.getDir());

                //Geomety term (solid angle)
                const Vector Nvec = hit.n;
                const float G = GeomUtils::absDotProd(omega_i, Nvec);
                //Technically, the above G is not correct! TODO
                //const Vector v = (samps[j] - hitLocWS);
                //const float r = v.magnitude();
                //const float G = GeomUtils::absDotProd(omega_i, Nvec) / (r*r);

                //Transform vectors into local BRDF frame
                /*
                Vector w_i_brdfCS = BRDFCoordHelpers::worldCSToBrdfCS(omega_i,
                   Nvec, hit.tangent, Nvec.cross(hit.tangent));
                Vector w_o_brdfCS = BRDFCoordHelpers::worldCSToBrdfCS(omega_o,
                   Nvec, hit.tangent, Nvec.cross(hit.tangent));
                */

                //Evaluate BRDF term at each wavelength
                float nm = ss.nmMin;
                BRDF* brdf = hit.shp->getBRDF();
                for(int i = 0; i < ss.numSpectralSamples; i++){
                    buf[i] = brdf->f(omega_i, omega_o, nm);
                    //buf[i] = brdf->f(w_i_brdfCS, w_o_brdfCS, nm);
                    nm += ss.nmStep;
                }

                //Create a "spectrum" of BRDF values
                Spectrum brdfSpec(buf, ss.nmMin, ss.nmMax, ss.nmStep,
                    ss.numSpectralSamples);

                //Light term
                retColor = retColor + (L * G * invNumSamps * brdfSpec);
            }
        }
    }

    //All done!
    delete[] samps; samps = NULL;
    delete[] buf; buf = NULL;
    return retColor;
}