Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing Time Sampling/Motion Blur for SPPM #441

Merged
merged 2 commits into from
Oct 27, 2024
Merged

Conversation

paulgrassler
Copy link
Contributor

@paulgrassler paulgrassler commented Sep 21, 2024

Small changes allow SPPM to converge to the correct image for animated scenes. Before. Rays and photons were individually sampling a separate timestamp leading to many inconsistencies, see #440. This approach can not work without significant changes (e.g. implementing a time kernel). Using a single timestamp per iteration and using it for all rays and photons of that iteration instead provides a straightforward solution to this problem with minimal additions. Because of the numerous iterations/samples of SPPM, it reliably converges to the correct result without any sampling artifacts. I am fairly certain that this is also how they did it in the original paper.

Image with Path Tracer Integrator:

cornell-box_path_gt

Image with existing SPPM implementation (RMSE: 0.001364; PSNR: 57.31529; SSIM: 0.99679):

cornell-box-sppm

Image with fixed SPPM implementation (RMSE: 0.00074; PSNR: 62.55448; SSIM: 0.99938):

cornell-box_sppm_fix

For reference: I found this issue while working on a seminar paper about Photon Mapping at the Institute of Computer Graphics and Knowledge Visualisation, Graz University of Technology.

My contact information:

My supervisor:

Scene used in the example images:

#Integrator "path"
Integrator "sppm"
    "float radius" [ 0.005 ]
Transform [ 1 -0 -0 -0 -0 1 -0 -0 -0 -0 -1 -0 -0 -1 6.8 1  ]
Sampler "paddedsobol"
    "integer pixelsamples" [ 2048 ]
Film "rgb"
    "string filename" [ "cornell-box.png" ]
    "integer yresolution" [ 1024 ]
    "integer xresolution" [ 1024 ]
Camera "perspective"
    "float fov" [ 19.5 ]
TransformTimes 0 1


WorldBegin

MakeNamedMaterial "LeftWall"
    "string type" [ "diffuse" ]
    "rgb reflectance" [ 0.75 0.25 0.25 ]
MakeNamedMaterial "RightWall"
    "string type" [ "diffuse" ]
    "rgb reflectance" [ 0.25 0.25 0.75 ]
MakeNamedMaterial "Floor"
    "string type" [ "diffuse" ]
    "rgb reflectance" [ 0.725 0.71 0.68 ]
MakeNamedMaterial "Ceiling"
    "string type" [ "diffuse" ]
    "rgb reflectance" [ 0.725 0.71 0.68 ]
MakeNamedMaterial "BackWall"
    "string type" [ "diffuse" ]
    "rgb reflectance" [ 0.725 0.71 0.68 ]
MakeNamedMaterial "ShortBox"
    "string type" [ "diffuse" ]
    "rgb reflectance" [ 0.25 0.75 0.25 ]
MakeNamedMaterial "TallBox"
    "string type" [ "diffuse" ]
    "rgb reflectance" [ 0.25 0.75 0.25 ]
MakeNamedMaterial "Light"
    "string type" [ "diffuse" ]
    "rgb reflectance" [ 0 0 0 ]
NamedMaterial "Floor"
Shape "trianglemesh"
    "point2 uv" [ 0 0 1 0 1 1 0 1 
        ]
    "normal N" [ 4.37114e-8 1 1.91069e-15 4.37114e-8 1 1.91069e-15 4.37114e-8 1 1.91069e-15 
                 4.37114e-8 1 1.91069e-15 ]
    "point3 P" [ -1 1.74846e-7 -1 -1 1.74846e-7 1 1 -1.74846e-7 1 1 -1.74846e-7 -1 ]
    "integer indices" [ 0 1 2 0 2 3 ]
NamedMaterial "Ceiling"
Shape "trianglemesh"
    "point2 uv" [ 0 0 1 0 1 1 0 1 
        ]
    "normal N" [ -8.74228e-8 -1 -4.37114e-8 -8.74228e-8 -1 -4.37114e-8 -8.74228e-8 
                 -1 -4.37114e-8 -8.74228e-8 -1 -4.37114e-8 ]
    "point3 P" [ 1 2 1 -1 2 1 -1 2 -1 1 2 -1 ]
    "integer indices" [ 0 1 2 0 2 3 ]
NamedMaterial "BackWall"
Shape "trianglemesh"
    "point2 uv" [ 0 0 1 0 1 1 0 1 
        ]
    "normal N" [ 8.74228e-8 -4.37114e-8 -1 8.74228e-8 -4.37114e-8 -1 8.74228e-8 -4.37114e-8 
                 -1 8.74228e-8 -4.37114e-8 -1 ]
    "point3 P" [ -1 0 -1 -1 2 -1 1 2 -1 1 0 -1 ]
    "integer indices" [ 0 1 2 0 2 3 ]
NamedMaterial "RightWall"
Shape "trianglemesh"
    "point2 uv" [ 0 0 1 0 1 1 0 1 
        ]
    "normal N" [ 1 -4.37114e-8 1.31134e-7 1 -4.37114e-8 1.31134e-7 1 -4.37114e-8 
                 1.31134e-7 1 -4.37114e-8 1.31134e-7 ]
    "point3 P" [ 1 0 -1 1 2 -1 1 2 1 1 0 1 ]
    "integer indices" [ 0 1 2 0 2 3 ]
NamedMaterial "LeftWall"

AttributeBegin
	Translate 0 1.9 0
	AreaLightSource "diffuse" "rgb L" [ 40 40 40 ] 
	NamedMaterial "Light" 
	Shape "sphere" "float radius" [ 0.1 ] 
AttributeEnd
Shape "trianglemesh"
    "point2 uv" [ 0 0 1 0 1 1 0 1 
        ]
    "normal N" [ -1 -4.37114e-8 -4.37114e-8 -1 -4.37114e-8 -4.37114e-8 -1 -4.37114e-8 
                 -4.37114e-8 -1 -4.37114e-8 -4.37114e-8 ]
    "point3 P" [ -1 0 1 -1 2 1 -1 2 -1 -1 0 -1 ]
    "integer indices" [ 0 1 2 0 2 3 ]


AttributeBegin
    NamedMaterial "ShortBox"
    Translate 0 0.2 0
    ActiveTransform EndTime
    Translate 0 0.2 0
    Shape "sphere"
        "float radius" [ 0.2 ]
AttributeEnd

Copy link
Owner

@mmp mmp left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One small comment. It's wonderful what a straightforward fix this is; thanks for submitting it!

@@ -2867,6 +2867,8 @@ void SPPMIntegrator::Render() {
Options->disableWavelengthJitter ? Float(0.5) : RadicalInverse(1, iter);
const SampledWavelengths passLambda = film.SampleWavelengths(uLambda);

Float timeSample = samplerPrototype.Get1D();
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this isn't quite right: you'll end up taking a sample from successive dimensions of the sampler, which doesn't necessarily give you well-distributed samples (and for some like Halton, will wrap around and start repeating values after the prime number table is used up.)

Note above that RadicalInverse() is used to generate a good set of samples for wavelength sampling. I think it would work well to instead do timeSample = RadicalInverse(2, iter) and just use the next Halton dimension for times. That way you get samples that are not correlated with the wavelength samples.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see. That makes sense, thank you for pointing that out!

@paulgrassler
Copy link
Contributor Author

It should be fixed now!

@mmp mmp merged commit 1ae72cf into mmp:master Oct 27, 2024
@mmp
Copy link
Owner

mmp commented Oct 27, 2024

Looks great-thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants