Thoughts on making Cycles into a spectral renderer

Just to be totally clear, what exactly are the ranges in the curve corresponding to? Can you give precise numbers?

The spectrum curve goes from 380nm to 730nm along the x axis and -1 (don’t use it) to 1 on the Y axis. What I tend to do is move the left point up above the middle then change the view range in the settings. It’s a pain but I haven’t figured out the UI code to solve it yet.

I’ve seen in most of the resources that the visible spectrum goes from 380nm to 780, why the choice to clamp it to 730nm?

Im not at the computer right now but I think it was just a practical choice for now considering how little contributions those longer wavelengths have on a scene. Once I add wavelength importance sampling, I’ll extend the range to the range of the newer 2012 CMFs which go from 360 to 830.

3 Likes

I’m catching up on this thread, and although this is pretty old at this point I’d still like to clarify. I’m sure what I’m about to say is what Troy meant, but I just want to make sure there’s no ambiguity for other readers who aren’t as familiar with the issues involved:

Even with the spectral sensitivity curves of a camera, you still cannot reconstruct the original spectra from the captured colors of an image. Going from spectrum to RGB (or XYZ, or whatever) is always a lossy operation, and cannot be inverted.

Trying to reconstruct a spectrum from an RGB color is like trying to reconstruct an RGB color from a black-and-white value: you simply don’t have the data anymore. Even with complete knowledge of the RGB->BW process that was used, you still can’t recover the original RGB colors.

However, what you can do with complete knowledge of the RGB->BW process is at least make sure that the RGB color you choose is one of the colors that would produce the same black-and-white value, given the same process. And, similarly, with the spectral sensitivity curves of an RGB camera, although you can’t get back the original spectrum, you can at least make sure that the spectrum you choose is one of the spectra that would produce the same RGB color with the same camera. And I believe that’s what Troy was getting at.

2 Likes

380 - 730 being the exact x-value inputs? Or is this what the range -1 to 1 is set to?

For ease of input I’d suggest moving that range to the mentioned 380 - 730 (right now a one-time-hassle to change the ranges but you can directly put in values from known spectra then, and eventually that ought to be the default range anyway) or at least to also 0 - 1, to make conversion a bit easier if you want to put in something specific

Currently - 1 maps to 380 etc. I hope to get the x coordinates to be in nm but I can’t find where in the code that is specified. The end goal is definitely to have things as clear as possible.

1 Like

I’ll have to think about interesting tests to perform but in the mean time, here’s a (roughly) ruby bracelet

I don’t think I necessarily did the right thing there: This is using a transmittance spectrum rather than an absorption spectrum. It still yields quite Ruby-like values though.

The extra subtract node there is simply so as to clamp the spectrum, hopefully meaning it gets limited to between 0 - 1. However, that notch in the spectrum essentially doesn’t do anything regardless, so I might as well leave it out. It’s at the wavelength of a ruby laser.

Also, I’m struggling to actually find a database of reflectance or absorption spectra.
The easiest to find are complex IOR spectra for metals. But as far as I can tell (correct me if I’m wrong - maybe there’s some OSL trickery?) I can’t use those at all yet. So if anybody has pointers to extensive libaries, preferably simultaneously in table and plot form, I’d love to hear it!
(For this material I basically used a ruler to roughly get the right values. That’s rather tedious)

1 Like

The code for the curve mapping widget is in a few different places:

  1. interface_templates.c Does the button layout and the some of the function callbacks
  2. interface_draw.c The stuff inside the box with the grid is drawn here.
  3. interface_handlers.c The event handling for the box. This shouldn’t need to be changed for this.

I’d imagine some more extensive changes to that widget will be necessary to make it work well for this situation, although using it is definitely the best way forward. I’m happy to help if you have any questions.

2 Likes

You can actually get a much closer representation of the spectra in the scene! Albeit subject to the camera metamerism. Think of it as a wobbly, slightly more erratic version of the spectral locus, where the deviations are a byproduct of the filter array and construction.

That’s the thing about proper spectral lookups is that they invert, within the limitations of the constructions of the filters, the camera’s first, second, and third plane, back to spectra in a combinatorial fashion. It avoids the worse issue of the forced mathematical fit of camera planes to XYZ!

I struggle to do nice lighting. Attempted a studio light setup but not really happy with it.
However, more importantly, this should closely approximate the spectrum of jade. And I think that worked quite well.

The material looks like this:

I didn’t bother exactly copying the short wavelengths which are a noisy mess of fluctuations. But otherwise this should be pretty close, according to this:
http://www.gemlab.co.uk/Through%20my%20Spectroscope.html

@smilebags one thing I’d like to see more for debugging than anything, is something like a Spectral-to-RGB viewer node. Like, literally all it does is taking a spectral input and showing a color swatch that corresponds to the closest sRGB value of that spectrum. I could then use that color to compare:

  • the non-specific spectrum version of the same material in the spectral branch
  • the same render in master

I’m not sure how hard it would be to make something like this, but just because of this it would be nice to have. Once it ends up in master, I’d imagine it’s no longer necessary.

3 Likes

That material looks really nice. It’d be interesting to see how it looks under different illumination spectra.

Definitely it’d be nice to be able to quickly compare the two but I’ll first focus on improving the spectral tools themselves such as the wavelength range in the spectrum curves

That’s another thing where this would come in handy :slight_smile:
If I had the ability to use the old and new blackbody stuff side by side, I could very easily use this to compare the RGB-light analogue as @pembem22 has done before.

Would it maybe be possible for now to have, two different blackbody nodes or a checkbox on the current node or something like that to switch between them? I’d imagine you’re basically tinkering with code right now that’s gonna help you understand how that might be possible. It’s probably gonna take changes in a similar spot to how you can redefine the default ranges of the spectral curve.

That being said, what’s really gonna be interesting is color change gems. There are a bunch of those around. If I use a spectrum reminiscent of one of them (I’ll have to find one first), so long as flourescence isn’t required for the effect, it’ll theoretically mean that I can get very noticeable color changes simply by varying the light source’s spectrum.

Wow, that looks great. I’m planning to bring back the old blackbody node and rename the current one, that’s required for backward compatibility. By “Spectral-to-RGB viewer node” do you mean node that takes spectrum as input and outputs RGB values? I guess this can be done.
Also, I think the ability to use image texture as a 1D LUT would be quite useful, I’d like to add that node at some point.

I think this would be the first node of it’s type, but it would definitely be useful.

It seems to fit as a specific case of a more generic ‘material preview node’ which I personally think would be really powerful, although potentially quite hard to implement. Being able to preview a texture within some UV range or preview a BSDF on a sphere for example, at various points in a node tree would make the process of material creation much more visual. I’ve had this idea for a while but I’m not sure how feasible it is.

If it also outputs it that would be really useful too but actually I mainly want a color swatch with the corresponding value, that I can read out. Like, gimme the accurate R, G, and B values for that color. Because I also want to use it in different versions of Blender. As far as the material is concerned it wouldn’t necessarily need an output at all! - Think viewer node.

Ideally it’d have a color swatch and then, below it, the three channels’ contributions in a form that can easily be copied and pasted between Blender versions.
A more advanced version of it could also provide a gradient of self-reflections (much like my absorption plots above) so as to make distinguishable metamers. But for now I’d really only need an immediate color so I can compare with Blenders outside the Spectral branch.

It’s really just meant as a debugging/testing tool, not necessarily as anything with a real application.

I see what you mean. Making some kind of viewer node is definitely much harder than just outputting converted value inside shader tree. That requires deeper Blender integration with Cycles and I don’t remember something similar existing already.

Maybe you can workaround this by using emission node and taking raw RGB values from rendered image.

1 Like

This is the sort of thing I’ve been thinking about. Seems really helpful but I’m not sure how much work it’d be

6 Likes

I don’t need it to be a full render. As such I don’t think it’d have to be Cycles-integrated? The way I’m imagining it, it should be possible to do it without any reference to Cycles at all.
The simple version is a single spectral-to-RGB conversion. No lighting consideration: It works as if the spectrum already is that light source. The gradient version, before that, preprocesses the spectrum by multiplying it by itself.
It’s just a onetime ingegration if I’m not mistaken? And it won’t have to be sampling based either, I don’t think. 1D integrals, like this would be, are better-approximated with other methods, as far as I know.
The one caveat, which is, however, separate from Cycles as well, should be color management.

This version is far more advanced than what I’d need for now, and a bigger project on its own. Also great and I’d love it. But just for previewing a single color, it’s overkill