Thoughts on making Cycles into a spectral renderer

Finally, a new build is available on GraphicAll. This one took a bit longer than I expected. Changes:

  • Added an ability to switch between RGB and spectral rendering modes. This is done by compiling RGB and spectral rendering kernels separately, meaning there should be no overhead when using RGB mode. As for now, CUDA supports only spectral mode. You can switch between using a checkbox (which is off by default, I haven’t figure out how to make it checked).
    image
  • Updated RGB upsampling LUT to reduce color differences between RGB and spectral renders. It’ll be replaced with a better upsampling technique in the future. Comparison (thanks to @kram1032 for the test scene):
    before
    after
  • Fixed render passes bug that made them colorless, though there’s now much more color than should be :sweat_smile:. I suspect the reason is the incorrect RGB upsampling, which will be replaced anyway.
  • Fixed “Import spectrum from CSV” plugin incorrectly importing values outside of the default spectrum range.
  • Removed the usage of Intel’s SVML library. If you had any compiler errors due to some _mm256_* functions, they should be gone now.
  • Updated Blender.
9 Likes

Awesome improvement, thanks @pembem22. That’s going to make comparing RGB and spectral a lot easier.

Oh great! Lots of neat stuff in here!

Could we get Filmic back perhaps? I know it’s not the final look but it’s still better than nothing

Sure, I’ll look into it.

1 Like

Retried the screws real quick. These are all from the spectral branch

Old (already posted above):

New:

Diff;

As expected, there’s a lot more red. Though, as the other test has shown, not yet enough

Compare that to the RGB version:

where you can very clearly see that, for instance, the sky is much more yellowish/orangeish rather than greenish/greyish.

Interestingly there’s also more fireflies again? Not sure why that might be

Really looking forward to the improved spectral upsampling!

1 Like

I have compiled a new macOS build including @pembem22’s latest changes.

5 Likes

Don’t have much time right now but I tried an Iron Complex IOR and it’s weirdly purple?
Like, I like it, but that’s not what iron ought to look like I’m pretty sure. I wonder where the problem lies.

Also I’m not sure the fixed render passes were entirely an improvement: I now get Dif/Glossy Direct and Indirect to look roughly right. But both Glossy and Diffuse Col just render black for spectrally defined materials (i.e. those that use spectral curves rather than spectrally upsampled RGB - previously they gave some reasonable output)

Seems to be the way it’s reflecting that floor? For sanity check try a gray floor perhaps?

1 Like

tried that and you can tell best that it’s super purple at the highlight which is by the sun so nowhere near the floor. It’s super purple

the best would be to “plot” out the reflection result to a emission shader,on a plane or some measurement model, that displays the wavelength range you can read/compare.

IE,if the plot is the same as the calculated reflection,from the refractive index site.

I mean it’s clear at a glance that it isn’t because iron isn’t this purple :slight_smile:
I might have made a mistake in the n k values though. I’ll have to double check

1 Like

I have downloaded your testfile and added the math for R0 calculation,to compare the results from the refractive list values.
Left is gold with nk from your preset,the right is Iron from the list.Backround light is 0,emission at 1.the emission output is around 50% higher as expected.(around .5 for Iron is renderpreview around .75).with exposure at -1 its closer (.55).Not sure if its gamma correction(is no option to deactivate the display gamma),or the math nodes(the math is correct,could be internal wrong),or something else.The color appearence seems right though.


and with sky tex and glossy shader.

Try the Raw view transform

Have no raw option,latest spectral build.

Yeah I hope @pembem22 will add the missing options back in. They were removed because they were deemed “wrong” but I think that was without considering just how long it’d take to get a fully satisfactory version of spectral filmic.

For now what you gotta do is to render stuff out as multilayer exr and then import it into regular blender where you use the compositor to get whichever scene transform you want.

The colors in that exr will be the ones before color management. If you check values in blender’s render output viewer, the left-most values are linear and they tend to be much darker than the labelled CM (Color Management) to the right

Anyway as far as I can tell you did the exact same inputs as me, just with slightly less precision (shouldn’t really matter)

I get a very clear purple tinge. So right now I’m not sure where the mistake lies. Since you get a perfectly plausible grey value, perhaps something still is wrong with my Complex IOR math here

Left my R0 equation,right your equation with same nk input as mine.Seems that something is wrong with your equation.

Yeah working on it. I think I already see what it is. Looks like a major brainfart on my part

EDIT: fixed as of Thoughts on making Cycles into a spectral renderer

image

ok that looks more like it.

EDIT: Ok I had some things wrong there still (totally forgot to plug in the normal)

And then I accidentally had some nodes exactly covering each other (seems like the only way to spot this is to wiggle around each and every node and find that, oops, there’s something below) and now I get this for R:

image

And the test scene looks like this:

Rusty Iron:

I think something still is wrong though. It looks like it goes white in the center and dark at the fringes, as if the cos and sin inputs were inverted perhaps… But as far as I can tell, they aren’t.

EDIT: Ok at this point I don’t see what, if anything, would be wrong. What I got is this:

Which is just the code from this page you previously showed me

float3 FresnelDieletricConductor(float3 Eta, float3 Etak, float CosTheta)
{  
   float CosTheta2 = CosTheta * CosTheta;
   float SinTheta2 = 1 - CosTheta2;
   float3 Eta2 = Eta * Eta;
   float3 Etak2 = Etak * Etak;

   float3 t0 = Eta2 - Etak2 - SinTheta2;
   float3 a2plusb2 = sqrt(t0 * t0 + 4 * Eta2 * Etak2);
   float3 t1 = a2plusb2 + CosTheta2;
   float3 a = sqrt(0.5f * (a2plusb2 + t0));
   float3 t2 = 2 * a * CosTheta;
   float3 Rs = (t1 - t2) / (t1 + t2);

   float3 t3 = CosTheta2 * a2plusb2 + SinTheta2 * SinTheta2;
   float3 t4 = t2 * SinTheta2;   
   float3 Rp = Rs * (t3 - t4) / (t3 + t4);

   return 0.5 * (Rp + Rs);
}

Expressed as nodes.

As far as I can tell the result that looks like what I’d expect is stored in Rs. Rp makes the center much brighter, leading to R being quite bright in the center.

Here’s the Blend file if you want to try it out:

If am not wrong then the a part has to multiplyed by 0.5 before sqrt.and t2 is 2 * a * costheta

Whether you go

2 * sqrt( 0.5 * x )

or

2 * sqrt(0.5) * sqrt(x)

or

(2 / sqrt(2)) * sqrt(x)

or

sqrt(2) * sqrt(x)

does not matter, except that that last line saves one multiplication in exchange for one precomputable square root :wink: