mmp / pbrt-v4

Source code to pbrt, the ray tracer described in the forthcoming 4th edition of the "Physically Based Rendering: From Theory to Implementation" book.
https://pbrt.org
Apache License 2.0
2.83k stars 440 forks source link

Periodic Radiance Values for Spectral Render #424

Open Youre opened 4 months ago

Youre commented 4 months ago

Hi, I am wondering if anyone could provide some insight into what might cause periodic radiances to appear in spectral renders.

I rendered several data cubes using the spectral film type and all pixels show a periodic radiance pattern. The pattern is more clear in some pixels compared to others, but the pattern is always present. The graphic below is a plot of the radiance values from a selected pixel. In this case, the sample was taken from a zero-day render with 63 spectral channels and the Sobol sampler -- but the pattern appears regardless of those parameters.

PeriodicRadiance

Overall magnitude is low because of the dark scene and the peaks are very clear for illustrative purposes. Again, I do not think this is really connected to the core problem since the pattern is present across the whole scene. For reference, RGB=[13, 13, 16] for this pixel, according to the respective 'R,' 'G,' and 'B' channels in the .exr.

My guess is that is has to do with RGB getting mapped into spectral space, which has ambiguity. For the very few materials that have spectral definition, their contribution would be much less than the RGB. So we would see artifacts of that mapping more clearly than with a purely spectrally defined scene. It is always four repetitions, regardless of the number of channels.

Also considered whether the wavelengths list and how I am extracting the data is not organized the same way.

Maybe I am missing something fundamental? Or maybe this is expected behavior when the scene isn't purely defined with spectral materials?

Any insight would be appreciated. Thanks!

Additional information: Spectral samples were extracted using Python, OpenEXR, and Imath.

# Python code to get wavelength channels
file = OpenEXR.InputFile(exr_path)    
channels = list(file.header()[ 'channels'].keys())
lambda_channels = channels[3:] # BGR are the first three channels, so we skip

# Extracting the values
float_Type = Imath.PixelType(Imath.PixelType.FLOAT)
for lambda_idx in range(len(lambda_channels)):
   channel_name = lambda_channels[lambda_idx]                        
   channel_str = file.channel(channel_name, float_Type)
   spectral_image[:,:,lambda_idx] = np.frombuffer(channel_str, dtype=np.float32). reshape(size[0],-1)