public static RgbSpectrum EstimateDirect(ref Vector wo, IAccellerationStructure intersector, SceneGeometryInfo scene, ILight light, IntersectionInfo isect, SurfaceBsdf bsdf, FastRandom rnd) { RgbSpectrum Ld = new RgbSpectrum(); Vector wi; float lightPdf, bsdfPdf; RayInfo shadowRay; RgbSpectrum Li = light.Sample(ref isect.GeometryInfo.HitPoint, ref isect.GeometryInfo.GeoNormal, rnd.NextFloat(), rnd.NextFloat(), rnd.NextFloat(), out shadowRay, out lightPdf); if (lightPdf > 0f && !Li.IsBlack()) { wi = -shadowRay.Dir; RgbSpectrum f ; bsdf.f(ref wo, ref wi, ref isect.GeometryInfo.GeoNormal, ref Ld, out f); if (!f.IsBlack() && !intersector.Intersect(shadowRay)) { // Add light's contribution to reflected radiance //Li *= visibility.Transmittance(scene, renderer, NULL, rng, arena); if (light.IsDelta) Ld += f * Li * (Vector.AbsDot(ref wi, ref isect.GeometryInfo.GeoNormal) / lightPdf); else { bsdfPdf = bsdf.Pdf(ref wo, ref wi, BxDFTypes.BSDF_ALL_TYPES); float weight = MC.PowerHeuristic(1, lightPdf, 1, bsdfPdf); Ld += f * Li * (Vector.AbsDot(ref wi, ref isect.GeometryInfo.GeoNormal) * weight / lightPdf); } } } if (!light.IsDelta) { //float bsdfPdf; bool spb; BsdfSampleData result; bsdf.Sample_f(ref wo, ref isect.GeometryInfo.GeoNormal, ref isect.GeometryInfo.ShadingNormal, ref Ld, rnd.NextFloat(), rnd.NextFloat(), rnd.NextFloat(), ref isect.TextureData, out result); bsdfPdf = result.Pdf; if (!result.F.IsBlack() && result.Pdf > 0f) { if (lightPdf > 0f) { float weight = MC.PowerHeuristic(1, bsdfPdf, 1, lightPdf); IntersectionInfo lightIsect; RgbSpectrum li = new RgbSpectrum(); var ray = new RayInfo(isect.GeometryInfo.HitPoint, result.Wi, 1e-4f, 1e+4f); if (intersector.Intersect(ray, out lightIsect)) { if (light is TriangleLight && lightIsect.PrimitiveId.Equals(((TriangleLight)light).Owner.Id)) li = light.Le(-result.Wi); } else li = light.Le(ray.Dir); if (!li.IsBlack()) { //Li *= scene->Transmittance(ray); Ld += result.F * li * Vector.AbsDot(ref result.Wi, ref isect.GeometryInfo.GeoNormal) * weight / bsdfPdf; } } } } /* if (!light->IsDeltaLight()) { BxDFType flags = BxDFType(BSDF_ALL & ~BSDF_SPECULAR); Spectrum f = bsdf->Sample_f(wo, &wi, bs1, bs2, bcs, &bsdfPdf, flags); if (!f.Black() && bsdfPdf > 0.) { lightPdf = light->Pdf(p, n, wi); if (lightPdf > 0.) { // Add light contribution from BSDF sampling float weight = PowerHeuristic(1, bsdfPdf, 1, lightPdf); Intersection lightIsect; Spectrum Li(0.f); RayDifferential ray(p, wi); if (scene->Intersect(ray, &lightIsect)) { if (lightIsect.primitive->GetAreaLight() == light) Li = lightIsect.Le(-wi); } else Li = light->Le(ray); if (!Li.Black()) { Li *= scene->Transmittance(ray); Ld += f * Li * AbsDot(wi, n) * weight / bsdfPdf; } } } } */ return Ld; }