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; }
public static RgbSpectrum UniformSampleLights(ref Vector wo, IAccellerationStructure intersector, SceneGeometryInfo scene, IList<ILight> lights, IntersectionInfo isect, SurfaceBsdf bsdf, FastRandom rnd) { var Ld = new RgbSpectrum(); for (int index = 0; index < lights.Count; index++) { var lightsource = lights[index]; Ld += EstimateDirect(ref wo, intersector, scene, lightsource, isect, bsdf, rnd); } return Ld; }
private RgbSpectrum Shade(MediumInfo currentMedium, float weight, RayInfo vray, IntersectionInfo isect, int depth) { var txtn = isect.GeometryInfo.GeoNormal; var p = isect.GeometryInfo.HitPoint; Vector v1, v2; Vector.CoordinateSystem(ref txtn, out v1, out v2); var Radiance = BaseColor * Vector.AbsDot(ref txtn, ref vray.Dir); for (int i = 0; i < shadowRayCount; i++) { var dir = MC.CosineSampleHemisphere(rnd.Value.NextFloat(), rnd.Value.NextFloat()); dir = new Vector(v1.x * dir.x + v2.x * dir.y + txtn.x * dir.z, v1.y * dir.x + v2.y * dir.y + txtn.y * dir.z, v1.z * dir.x + v2.z * dir.y + txtn.z * dir.z); stats.intersections++; if (!manager.Intersect(new RayInfo(p, dir, 1e-4f, maxOcclussionRayLength))) { Radiance += AddedRadiance * (1.0f / shadowRayCount); } } return Radiance; }
public static RgbSpectrum UniformSampleLight(ref Vector wo, IAccellerationStructure intersector, SceneGeometryInfo scene, IList<ILight> lights, IntersectionInfo isect, SurfaceBsdf bsdf, FastRandom rnd) { int nLights = lights.Count; int lightNum = rnd.Next(0, nLights - 1); var light = lights[lightNum]; return (float)nLights * EstimateDirect(ref wo, intersector, scene, light, isect, bsdf, rnd); }
public bool Intersect(RayInfo ray, out IntersectionInfo intersection) { return accel.Intersect(ray, out intersection); }