glm::vec3 BidirectionalIntegrator::TraceRay(Ray r, unsigned int depth)
{
    Intersection isx = intersection_engine->GetIntersection(r);
    if(isx.t < 0)
        return glm::vec3(0);
    else if(isx.object_hit->material->is_light_source)
    {
        return isx.object_hit->material->base_color * isx.texture_color;
    }

    glm::vec3 resultColor(0);

    for(Geometry* light : scene->lights)
    {
        std::vector<PathNode> eyePath = generateEyePath(r);
        std::vector<PathNode> lightPath = generateLightPath(light);

        if(!eyePath.empty() && !lightPath.empty())
        {
            PathNode* node = &lightPath[0];
            float lightPdf = light->RayPDF(node->isx,Ray(node->isx.point,node->dirIn_world));
            glm::vec3 Le(0);
            if(lightPdf != 0)
                Le = light->material->base_color * light->material->intensity / lightPdf;

            glm::vec3 directWt(1.0f);
            for(int i=1;i<=eyePath.size();i++)
            {
                node = &eyePath[i-1];

                Ray ray(light->transform.position(), - node->dirIn_world);
                resultColor += directWt * EstimateDirectLight(node->isx, ray, light) / WeightPath(i,0);
                directWt *= node->F * glm::abs(glm::dot(node->dirOut_world,node->isx.normal)) / node->pdf;

                for(int j=1;j<=lightPath.size();j++)
                {
                    resultColor += Le * EvaluatePath(eyePath,i,lightPath,j) / WeightPath(i,j);
                }
            }
        }
        else
        {
            continue;
        }

    }
    return resultColor;
}
Пример #2
0
Spectrum VolumePatIntegrator::UniformSampleLight(const Scene *scene,
        const Renderer *renderer, MemoryArena &arena, const Point &p,
        const Normal &n, const Vector &wo, float rayEpsilon, float time, RNG &rng) const {
    // Randomly choose a single light to sample, _light_
    int nLights = int(scene->lights.size());
    if (nLights == 0) return Spectrum(0.);
    int lightNum;
    lightNum = Floor2Int(rng.RandomFloat() * nLights);
    lightNum = min(lightNum, nLights-1);
    Light *light = scene->lights[lightNum];

    // Initialize light sample for single light sampling
    LightSample lightSample(rng);

    return (float) nLights * EstimateDirectLight(scene, renderer, arena,
            light, p, n, wo, rayEpsilon, time, rng, lightSample);
}