路径追踪MIS实现结果过亮问题排查求助
路径追踪器MIS实现亮度异常排查求助
我正在实现路径追踪器,采用**多重重要性采样(MIS)**结合光源分布与BRDF分布计算直接光照,已完成递归形式的MIS实现代码,同时拥有可生成真值图像的暴力实现代码。但对比两者渲染结果时,发现MIS结果明显更亮,附不同光源大小的渲染对比图,恳请帮忙排查问题给出提示。
MIS实现代码
vec3 TraceMISRecur(const Ray& WorldRay, int MaxDepth, std::vector<Object*>& World, Object* Lights) { if (MaxDepth == 0) return vec3::Zero(); // direct integral, use light dis and brdf dis to approx HitRecord Record; bool Flag = HitClosest(WorldRay, Record, World); if (!Flag) return vec3::Zero(); vec3 L_direct = vec3::Zero(), L_indirect = vec3::Zero(); vec3 LightSample; float PdfOnLight; vec3 LightColor; vec3 LightNormal; SampleLights(LightSample, PdfOnLight, LightColor, LightNormal, Lights); vec3 SurfacePosition = Record.HitPoint; vec3 Dir = LightSample - SurfacePosition; float Distance = Dir.norm(); Dir.stableNormalize(); bool HitOtherObject = HitAny(Ray(SurfacePosition, Dir), World); HitOtherObject |= LightNormal.dot(-Dir.stableNormalized()) < 0; HitOtherObject |= Dir.dot(Record.Normal) < 0; if (!HitOtherObject) { float GFactor = GeometryFactor(SurfacePosition, LightSample, LightNormal); float LightpdfOnHemisphere = PdfOnLight / GFactor; vec3 BRDF = Record.Mat->BRDF(-WorldRay.B, Dir, Record); float MatPdf = Record.Mat->PDF(-WorldRay.B, Dir, Record); vec3 Le = LightColor; float MISWeight = BalanceHuristic(LightpdfOnHemisphere, MatPdf); L_direct += MISWeight * BRDF.cwiseProduct(Le) * Dir.dot(Record.Normal) / LightpdfOnHemisphere; } vec3 Wi = Record.Mat->Sample(-WorldRay.B, Record); float MatPdf = Record.Mat->PDF(-WorldRay.B, Wi, Record); vec3 BRDF = Record.Mat->BRDF(-WorldRay.B, Wi, Record); HitRecord LightRecord; bool HitLight = Lights->IntersectClosest(Ray(Record.HitPoint, Wi), LightRecord); if (HitLight) { float GFactor = GeometryFactor(SurfacePosition, LightRecord.HitPoint, LightRecord.Normal); int LightIndex = LightRecord.PrimitiveIndex; float LightArea = Lights->Primitives[LightIndex]->GetArea(); float LightpdfOnHemisphere = 1. / Lights->Primitives.size() / LightArea / GFactor; vec3 Le = LightRecord.Mat->BRDF(); float MISWeight = BalanceHuristic(MatPdf, LightpdfOnHemisphere); L_direct += MISWeight * BRDF.cwiseProduct(Le) * Wi.dot(Record.Normal) / MatPdf; } // indirect L_indirect = BRDF.cwiseProduct(TraceMISRecur(Ray(Record.HitPoint, Wi), MaxDepth - 1, World, Lights)) * Wi.dot(Record.Normal) / MatPdf; return L_direct + L_indirect; }
暴力实现代码
vec3 Trace(Ray &WorldRay, int MaxDepth, std::vector<Object*> &World) { vec3 Background = vec3::Zero(); vec3 Throughput = vec3::Ones(); vec3 OutputRadiance = vec3::Zero(); HitRecord Record; for (int i = 0; i < MaxDepth; i++) { HitRecord Record; bool Flag = HitClosest(WorldRay, Record, World); if (!Flag) { // currently, the env light not included in MIS OutputRadiance += Throughput.cwiseProduct(Background); return OutputRadiance; } int MaterialType = Record.Mat->MaterialType(); bool IsBackFace = Record.IsBackFace; vec3 Wi = Record.Mat->Sample(WorldRay.B, Record); float pdf = Record.Mat->PDF(WorldRay.B, Wi, Record); vec3 BRDF = Record.Mat->BRDF(WorldRay.B, Wi, Record); if (MaterialType == EMISSION) { if (IsBackFace) return vec3::Zero(); OutputRadiance += Throughput.cwiseProduct(BRDF); return OutputRadiance; } Throughput = Throughput.cwiseProduct(BRDF) * Wi.dot(Record.Normal) / pdf; WorldRay = Ray(Record.HitPoint, Wi); } return vec3::Zero(); }
渲染对比结果
- 小光源MIS结果:

- 小光源暴力实现结果:

- 大光源MIS结果:

- 大光源暴力实现结果:

内容的提问来源于stack exchange,提问作者yys_c
相关产品推荐
相关产品推荐

