Thoughts on making Cycles into a spectral renderer

Spectrum curves will be in the next build! Again, big thanks to @pembem22 for helping getting this to work.

Although this isn’t so practical right now (the curves interface isn’t very well suited to generating spectra) it opens the possibilities for a lot of things to happen now. This can be plugged in anywhere you’d use a colour normally, so in absorption/scatter/emission and in regular material colours.

Keep in mind the Curves window shows -1 to 1 on the Y axis for now, so make sure you move the left point up above the midpoint then change the range of the view (or just use the top half of the curves window).

3 Likes

Before RGB sliders and computers, there were only options to mix pigments and dyes or use physical or chemical processes like abrasion or etching to get a color. At the time, ‘color’ always implied ‘the full spectrum’. Basically, RGB still is a full spectrum, but only if you multiply with the spectral power-distribution-function of each LED or the spectral sensitivity of the RGB elements on your camera sensor. But you all know that.

Thus, selecting spectral colors in your artist-workflow should be similar to selecting and mixing pigments from a pallet, right? Other spectrum selection- or modification nodes could simulate the physical- and chemical processes, right? A digital artist thus obtains the tools from the traditional artists. By extension: using a texture then also implies that the artist needs to select the primaries that were used in that ‘painting’; three in case of an RGB texture. So I guess that a texture input node should have three inputs; one for each primary. These inputs could default to a (selectable) camera gamut or some convention for non-color data.

Having these options available, a future artist would think about the days past when he had only three pigments: red, green, and blue.

(I love your work, guys)

2 Likes

I really appreciate the first principles mindset you have here and I see this as a great explanation of how doing things right can simplify a workflow considerably.

Just in the same way that raytracers are popular because they give you a lot of realism for ‘free’ (rather than fiddling with cube maps and irradiance caches), thinking of colour in the human sense simplifies the process to something intuitive. The fact that RGB makes sense to us is just because we have worked with it for so long. There’s nothing truly fundamental about RGB, it is just convenient that they can cover a lot of the colours that we can see when mixed.

I don’t see RGB based workflows disappearing any time soon, but opening other doors will change how we work in the long run, I’m pretty confident about that.

1 Like

This is great. I assume the lower and upper X ends of the curve correspond to those of visible spectra ? Another question, why accept negative absorption values ?
So I know we’re really not thinking of UX yet, but as this is the only way I can contribute, I was thinking of such an interface :
cycles_spectra
For convenience.

3 Likes

Pretty closely, yes.

You could call it a bug. I can’t think of a time where negative values would be meaningful and I think they might be clipped anyway, but it was just how the node turned out since I don’t know how the UI code works.

This is pretty close to what I had in mind for this node, yes. There are plans for other spectral input nodes in the future too, so this isn’t the only option.

2 Likes

Thanks for your reply ! I guess negative absorption could mean emission, but that probably wouldn’t work since this is a color node and not a bsdf.

If I may ask another couple of complete layman questions : are there absorption curves known for different materials that users could choose as presets to populate the absorption curves widget (kind of like an IOR list)? I don’t think the typical shading artist knows that kind of thing by heart ?

And : are there any plans to be able to change camera response curves to something out of range such as infrared, to get certain effects cheaply ? (thinking of night vision, or xray see-through, etc). I imagine this may have little payback since these effects can be faked pretty easily, but that was already the rationale for RGB vs spectral a few years back hence my question.

1 Like

I’m not sure about this yet, I feel like some presets might be practical like a ‘metals’ node, but I also feel like people will naturally create and distribute these as necessary. Finding good data is also a challenge.

2 Likes

It is something I’ve thought about. There’s not really much technically limiting us from doing this, it’s just a matter of the development work involved in implementing it. It would be nice to have.

2 Likes

Nice progress guys!
Random question, are the AI denoisers (OIDN, OptiX) trained for luminance noise only and have to be updated for spectral/color noise? Or will this not make a significant difference?

I suspect it will make little difference in the performance of the denoisers. With 8 wavelength samples per ray, there’s virtually no colour noise at all introduced by the spectral sampling process. By the time you get to a reasonable level of luminance noise I would expect the colour noise to also be well resolved.

My plan is also to optimise wavelength sampling to importance-sample high luminosity wavelengths, which will favour quickly resolving luminosity noise at the expense of colour noise. The reason for this is that colour information can be denoised much more heavily with favourable results in comparison to luminance noise, as can be seen here. Reference, then 8px luminance blur on left and 8px colour blur on right. Blurring isn’t exactly the same operation as denoising, but it’s similar enough that I suspect it will still hold true.

2 Likes

This makes sense, yes.

I’d call it a feature. Much like RGB values can become negative in a node-based setup, negative spectral values suite the same purpose (e.g: trickery, NPR, …). Also, a node setup might include a set of negative spectral constants to feed some physical model. The possibilities are endless, so please do not limit (but possibly warn instead).

Yeah there’s not going to be any restriction of creating spectra which contain negative values, but I would expect that if that spectrum was passed into a diffuse colour for example, that the negative values would be clipped at that point. Certainly having a spectrum centered around 0 (some positive and some negative values) which could be added to another spectrum is a useful thing that should be possible.

What is the physical meaning of a negative absorption value ? how would a bsdf handle it ?

It wouldn’t mean anything in the physical sense. It could be defined to behave a certain way, but I can’t see that as a productive aspect of the engine.

Isn’t it what fluorescence does? A wavelength shift can be represented as positive absorbance of a certain wavelength balanced by negative absorbance in another wavelength. But maybe I am wrong and you are discussing something else… I’m new here :slight_smile:

1 Like

Hi! That’s certainly one way it could be defined, but there are a lot of complications in building fluorescence into Cycles, so it would almost certainly require it’s own node of some sort. That node might take in a spectrum representing what percentage of each wavelength to affect, and a float representing how much to shift by. In that sense, you’d still be using ‘positive’ spectra to define the fluorescence behaviour.

1 Like

Spectral blending certainly is a thing that would be great to have. And that, I think, would essentially cover the mixing of pigments.
How advanced we’d want to make this remains to be seen. Apparently Brecht doesn’t like the current functionality of arbitrary spectrum manipulation like we’d manipulate colors. However, we could have a variety of BSDFs with certain color models. - Perhaps the appropriate way to implement this, so as to avoid an explosion in shader nodes identical to each other aside of what underlying way they produce their spectra, would be a dropdown menu, much as in such BSDFs as Principled (for SSS), SSS, Glass, Glossy, and Hair. That should be easy enough.
And then, getting pigment mixing would be as simple as selecting two pigment-emulating shaders and mixing them with a mix shader.

Maybe it would be possible to build the current Curve Spectrum input into a shader instead? To me only the UI side is aparent and I’m not sure about the technicalities, but as far as I can tell that’s just a fancy new expanded slider, much like the various parameters that BSDFs can already offer.

As for textures: Really, you’d want multilayered textures with arbitrarily many channels, each of which potentially corresponds to its own spectral properties. RGB is based on hypothetical idealized light sources. And in some sense that’s already how textures are currently handled in this build, I think. You are picking (well currently it’s locked) a (currently very crude) color model, upsampling RGB to three lights which correspond to sRGB sources, normalized such that if they all glow with intensity 1, they produce sRGB 1 1 1 at the surface, and if each of them individually glows with intensity 1, it maximizes one of those three channels while keeping the other two minimized.

And you’d certainly not normally want, say, ACES gamut textures. Because that covers the entire gamut, one of its primaries doesn’t even lie inside the space of real colors corresponding to real spectra, and even if that wasn’t the case, they are pure wavelengths, sampling from a single value each, giving really weird behavior.

1 Like

Nope, that works differently. Emission adds light. Absorption, in a sense, multiplies it instead. Negative spectral absorption would simply make light of the corresponding wavelength, that passes through such a material continuously brighter. It would not add some constant color on top.
Meanwhile, negative Emission would mean it subtracts light instead, effectively “emitting shadows”

At the very least, by default, all spectral data ought to automatically be limited to positive values and probably to values between 0-1 specifically. (Going bigger than 1 does make physical sense for emission spectra but not for reflectance spectra)
Going negative could have artistic value, but I suspect it’d be really rare, and the interface should make it deliberately difficult to achieve that on accident.

1 Like