Skip to content

DiskLight / RectLight with spread < 1: intersect() reports a different pdf than sample() #330

Open

Description

@gonsolo

Two related problems in lib/rendering/pbr/light/DiskLight.cc and RectLight.cc (same in the ISPC versions), version 2026.29.1.

1. DiskLight: bounding box instead of the disk

Reproduce. Glossy floor (roughness 0.3) under a disk light, max_depth 1:

spread light samples only BSDF samples only both
1.0 0.04509 0.04510 0.04509
0.95 0.04114 0.04116 0.04139
0.8 0.02979 0.02980 0.02997

Cause. DiskLight::sample() uses mInvArea (1 / (pi R^2)) when the whole disk lies inside the spread region (lightIsInsideSpread), and the overlap rectangle otherwise. DiskLight::intersect() always calls getOverlapBounds, which in the first case returns the 2R x 2R bounding box, so the hit pdf is 1 / (4 R^2). The MIS weights of light and BSDF samples then do not sum to one.

Fix (untested). Use the same case distinction in intersect() as in sample().

2. Reverse and two-sided lights: signed distance

Reproduce. The same floor under a light with sidedness reverse and spread 0.8:

light light samples only BSDF samples only both
DiskLight 0.02980 0 0.02942
RectLight 0.03794 0 0.03725

Cause. intersect() computes float spreadLength = localP.z * mTanSpreadTheta; with the signed localP.z, which is negative on the reverse side. getOverlapBounds then finds no overlap and returns false without writing width and height; the return value is not checked and the pdf is computed from them. sample() uses the sign-corrected plane distance and is fine.

Fix (untested). Use abs(localP.z), and check the return value of getOverlapBounds.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions