You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

路径追踪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小光源渲染结果
  • 小光源暴力实现结果:暴力实现小光源渲染结果
  • 大光源MIS结果:MIS大光源渲染结果
  • 大光源暴力实现结果:暴力实现大光源渲染结果

内容的提问来源于stack exchange,提问作者yys_c

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 05:10:58