Jump to content

Glass


Mario Marengo

Recommended Posts

Absorption...

Glass_Part2.zip

28593[/snapback]

Hi Mario,

So I suppose real-world gels have an extremely high rate of absorbtion and result in pure filters, right? Perhaps it'd be wise to have a toggle in the shader to skip the (expensive) exp() calls with very high exponents and do a straight mult in the case of pure Filters ?

And could I put another topic on the queue for future discussion? "Spectral models and what they really mean to us." This is an area I'm interested in finding out more about too:)

Link to comment
Share on other sites

So I suppose real-world gels have an extremely high rate of absorbtion and result in pure filters, right? Perhaps it'd be wise to have a toggle in the shader to skip the (expensive) exp() calls with very high exponents and do a straight mult in the case of pure Filters ?

Hey Jason,

Yes, if you want a colored gel (with reflections I'm guessing), then the way the shader is built now, you'd turn off absorption, and color-correct the reflected and refracted rays by tinting them to whatever color you want... which is ugly.

Truth is, I just realized now that I'm (unintentionally) totally ignoring "Glass Color" when absorption is off, which is silly. It should be used as a global tint when absorption is off, thereby giving you a colored gel... I was thinking about absorption and totally missed that. I'll update the bundle when I get a chance.

And could I put another topic on the queue for future discussion? "Spectral models and what they really mean to us."  This is an area I'm interested in finding out more about too:)

I was actually thinking of trying a spectral model for dispersion -- a small set of six samples maybe, just for fun. It's guaranteed to be slower than the RGB model, but maybe have it as an option just for giggles.

Link to comment
Share on other sites

Hey Mario, I had a bit of a rough time dialing in glass_part2 on this model; something I'm doing wrong?

The normals are backwards (if you zoom in you'll notice they're all pointing into the glass. You want them pointing away from the glass). Here's what I get when I just render what you sent:

post-148-1150321774_thumb.jpg

And here it is (polys-as-subd) after a reverse SOP:

post-148-1150321786_thumb.jpg

Link to comment
Share on other sites

The normals are backwards (if you zoom in you'll notice they're all pointing into the glass. You want them pointing away from the glass). Here's what I get when I just render what you sent:

post-148-1150321774_thumb.jpg

And here it is (polys-as-subd) after a reverse SOP:

post-148-1150321786_thumb.jpg

28616[/snapback]

Wow; what a noob mistake; I really thought I checked 'em. :unsure:

I suppose I confused myself with too long a normal display. Sorry for wasting your time.

Link to comment
Share on other sites

Wow; what a noob mistake; I really thought I checked 'em.  :unsure:

I suppose I confused myself with too long a normal display. Sorry for wasting your time.

Heh, that makes three of us then: I do it all the time. Though now I think I trust the fresnel function enough to instantly suspect the normals if something looks waaaay off like that :)

@sum][one: Remember the shader doesn't support illumination yet. But yes, an environment map, if it is part of the scene (i.e: traceable) should get picked up. Though I haven't bothered exposing a lot of options for the reflectlight/refractlight calls yet... this will be there, I promise! :)

Link to comment
Share on other sites

  • 2 weeks later...
Hmmm... time to ask the "big people" about this, as it is hard to construct a meaningful test for secondary rays in the shader(s).

28554[/snapback]

Hi Mario,

Just wondering if you've spoken with SESI about this topic since then? I'm kinda curious as to whats causing this.

Link to comment
Share on other sites

Hi Mario,

Just wondering if you've spoken with SESI about this topic since then? I'm kinda curious as to whats causing this.

28750[/snapback]

Hey Jason,

Yes I did, but very briefly because we'd met to talk about something completely different. After some speculation, it was suggested that I try setting the variance to zero, as this is one of the heuristics used to determine the number of samples taken over the MP. I tried this briefly at the time, but it didn't seem to make much of a difference.

I'll bug them again with a concrete example they can analyze, but I know they're going crazy over there at the moment, so I'll wait a bit.

P.S: I'll try to get my act together and post the next glass installment -- I've had it sitting here for over a week now, but haven't gotten around to cleaning it up and writing all the explanations yet. I'm hoping to be able to get to that soon.

Cheers!

Link to comment
Share on other sites

Dispersion

Dispersion is the separation of transmitted light into individual color (wavelength) components -- a rainbow. This is due to the difference in each wave's speed, which is related to its wavelength. The amount by which light refracts (bends) when crossing a transmissive interface (glass, water, etc) is related to the speed of the wavelength as well as the optical properties of the material, and so we can think of the material as having a different index of refraction (IOR) per wavelength -- "bending" by different amounts. Typically, we assign a single IOR to a transmissive material and leave it at that, when a more realistic approach would be to assign a continuous IOR curve to the whole visible range of the spectrum, giving each wavelength a different IOR.

A curve that represents different magnitudes for each wavelength in the electromagnetic spectrum is called a "Spectral Power Distribution" (SPD), and is analogous to assigning different values for the red, green, and blue channels in our more familiar RGB color model. In other words, an SPD is a spectral color.

Wavelengths are usually given in either micrometers (

post-148-1151808990_thumb.jpg

post-148-1151809010_thumb.jpg

post-148-1151809027_thumb.jpg

post-148-1151809059_thumb.jpg

post-148-1151809069_thumb.jpg

post-148-1151809123_thumb.jpg

post-148-1151809135_thumb.jpg

post-148-1151809177_thumb.jpg

post-148-1151809189_thumb.jpg

Glass_Part3.zip

post-148-1151826135_thumb.jpg

  • Like 3
Link to comment
Share on other sites

thank you again Mario for your great work! I think this is something that everyone here not very familiar with shader writing needs to start playing around and understand how deep it can go.

really thank you very much!

cheers,

happy SY :)

Link to comment
Share on other sites

I think this is something that everyone here not very familiar with shader writing need to start playing around...

28942[/snapback]

I wouldn't call this a starter approach, it is rather the example of professional work - not to play with, but to follow.

Sorry SYmek - I didn't mean to contradict you. :)

Link to comment
Share on other sites

I wouldn't call this a starter approach, it is rather the example of professional work - not to play with, but to follow.

Sorry SYmek - I didn't mean to contradict you.  :)

28944[/snapback]

this is definitely not a starter approach! I think you know what I meant ;)

Link to comment
Share on other sites

Thanks guys. Glad you like it.

One thing I forgot to mention:

The list of measured glasses in the "Optics" menu has been sorted in order of ascending dispersion (descending "Abbe number") -- i.e: the last member of the list disperses more than the first member.

In general, optical glasses are grouped into the following categories (in ascending dispersion order):

1. Crown

2. Dense Crown

3. Light Flint

4. Flint

5. Dense Flint (and lead-containing glasses)

Overall though, the progression is pretty smooth, so you won't notice a great deal of difference between close neighbours in that list -- it's really more of a "confidence factor" to have a reference of what "real" glasses look like.

The tables for the pre-computed weights are not much more than a re-formatted version of the Schott catalog: just copy-pasted into a C++ array and re-formatted into a VEX spline in a very quick and dirty way.

Here is the C++ code that generates these tables, in case someone wants to play with them:

glass_dev.zip

In Linux, you would compile like this:

g++ -I. -o mktables mktables.C

and then redirect its output to some file when you run it (or without redirection you want to dump to the shell):

mktables > my_glass_header.h

Like I said, quick'n dirty.

Cheers!

Link to comment
Share on other sites

Together with your SubSurface thread, these are some of the most informative documents one could ask for! :)

Thank you very much for putting all this great work into it!

EDIT: I suppose now there is this nice spectral model work, it should perhaps not be too difficult to simulate iridescence?

example

ANOTHEREDIT: Here is a page which shows the dispersion effect in a photon pass : diamond rendering

Link to comment
Share on other sites

Hey Jason,

Thank you very much for putting all this great work into it!

My pleasure.

EDIT: I suppose now there is this nice spectral model work, it should perhaps not be too difficult to simulate iridescence?

example

Yeah, it should be pretty straight forward.

The good thing about this "thin film interference" type of iridescence is that it happens at the surface, which means you can sometimes get away with a great deal of hackery.

The simplest approach is to use some function of position or direction (like noise(P) or dot(N,V) or both) to index into a rainbow ramp -- very, very hacky but obviously cheap to compute. I think the ThinFilm VOP uses something like this.

Another lookup method, but perhaps a little more convincing (yet still cheap to compute) is the one from the nVidia SDK (scroll down to "Thinfilm").

A more convincing method from this paper, approximates spectral colors using phong lobes on the secondary reflection (still keeping everything in RGB). I've used this one before and it's not bad.

Finally, you could try the "real thing". Iridescence is precisely the topic of that paper I mentioned earlier. They are the ones who also propose the hybrid spectral model, but I'm sure it could be tested with the model in the glass shader.

I think this kind of thing would only make sense as a VOP though, since it's a "coating" on the underlying material...

Any takers?

ANOTHEREDIT: Here is a page which shows the dispersion effect in a photon pass : diamond rendering

In time, I'm hoping to get to the photon shader for this glass... haven't written many photon shaders (none for Mantra, actually), so this would be a good excuse to get into it and learn a few things. :)

Link to comment
Share on other sites

  • 2 weeks later...

I went and found myself a little play time... JOY! :)

This was pretty rushed though, so I wouldn't be surprised if this update has a few bugs (some parts I haven't even tested), but since time is at a premium these days, I thought I'd throw it out there anyway.

One small change to the previous version:

*/ The mean eta for secondary transmissions in the case of non-user-defined glasses was getting picked up from the parameters instead of the tables. This is now fixed.

Some New Stuff:

*/ Added basic local illumination: ambient, diffuse, and specular.

*/ Most of the time, you shouldn't need to use any of these except maybe specular (but you're probably better off creating a light source to actually reflect). Diffuse and, *gulp*, ambient, would only be needed if the glass is supposed to be dusty, or greasy, or in some other state that makes it reflect diffusely. Otherwise, forget they're there (I turned them off by default).

*/ A note about the diffuse model: it is not quite Lambert.

Glass is a reflective surface (even when dusty), so this diffuse model is Lambert weighted by Fresnel (as per Ashikhmin). This basically ensures that at grazing angles, where you are getting mostly mirror/specular reflections due to Fresnel, the diffuse contribution diminishes proportionally -- a property of glossy surfaces that Lambert doesn't account for.

Photon Phun!

I got to play with purty, colorful faux-tonnes!!

I'm including a first stab at the glass photon shader. Even though the ui has most of the stuff from the surface shader, much of it is not active yet. Specifically: tinting, color correction, and absorption is missing at the moment (so changing those sliders will have no effect). IOW: it currently assumes white light and colorless glass.

An interesting little photonic problem right off the bat...

I haven't checked this yet, but it would seem that in the photon context, there's no way to access the current evaluation depth -- i.e: there doesn't seem to be an equivalent to getraylevel() or getglobalraylevel() (both of these seem to always return 0). The shader (both photon and surface) needs this information so as to only apply dispersion on first transmission (all subsequent transmissions are monochromatic).

Right now I'm getting around this by making Cl negative after first transmission -- this acts as a flag that gets tested per instance. Of course, this only works if there are no negative lights in the scene, but I think that's a pretty safe assumption. Anyway... this may not be an actual problem and likely I just haven't found the proper function yet (as mentioned, this was rushed), but it means that the photon light (the one that adds photon illumination by reading a photon map, like the v_gilight SHOP), can't use Cl as-is. Instead, it needs to use abs(Cl). The test hipfile includes a little light that does this (called "CausticLight") written in VOPs.

On the positive side, the photon shader, unlike its surface counterpart, doesn't need to worry its pretty little head about no stinkin' spectral colors when dispersing... aaaaahhhhh.

That's because in the photon shader we're pushing waves *into* the scene; not trying to reconstruct what's there by tracing. So we can slice'n'dice the spectrum any way we like. YAY!

This first try at photon dispersion simply chooses a wavelength at random (with equal probability at the moment) for each photon, tints Cl accordingly, and shoots it into the scene. The process of choosing a wavelength starts with a uniformly distributed random number in [0,1] -- using nrandom() -- which then gets mapped to a wavelength in the visible range (400nm-700nm). This random wavelength finally gets used to calculate the interior eta (i.e: IOR for that wavelength). The actual mapping to eta depends on the glass model being used (user-defined with spread, precomputed spread, or measured sellmeier coefficients) that's why that bit looks a little more complicated, but it's otherwise straight forward. Finally, the computed eta gets fed to Fresnel to get all the weights and directions (for transmission and reflection), and the wavelength gets mapped to HSV for tinting Cl.

But how to play Russian Roulette?!... choices, choices...

I started by using the fresnel weights (kr, kt) directly, as the probabilities for reflection and transmission. I believe this is as it should be; but there is a small problem: depending on a bunch of factors, it is possible that the two fresnel weights won't add up to 1 (this is not a flaw in the implementation). Given that I forcefully slam the diffuse probability to 0 (anyone think there should be a diffuse probability for glass?), this means that a combined reflect+transmit probability < 1 will end up storing photons in the glass itself...

Maybe that's not a bad thing... maybe it's exactly what we want... I just haven't had a chance to think about it yet (or to experiment at all), so for now, I decided to always normalize the combined reflect+transmit weights, essentially ensuring that no photons stay on the glass -- they'll all get reflected or transmitted.

Again, this is mostly because I'm not sure what to do with them on the glass at this point (which is hardly a good reason). I would love to hear what people here think would be the "correct" way to handle this.

OK. I thought I'd test the photons with the classical beam-splitter setup -- a single plane of insanely dispersive glass that splits an ultra thin slit of light. The custom "SlitLight" shader is written in VOPs and simply casts light orthographically inside a rectangular volume. It works as expected on its own, but for some reason, when spewing photons, it refuses to fill vertically (I think it's because I'm overriding L to make it ortho). End result is that I ended up instancing a bunch of these lights along a line to produce the photon slit (oh boy... I can hear the comments on my choice of names already :P).

The photon map is *not* included in the bundle, so you have to create it first, before you do a test render. Just run the "GenPhotons" ROP. It'll probably take a while... it's shooting 100 million photons. Then you can do a micropolygon render with "Mantra_MP", and you should get an image similar to this one (this one has 200 million):

post-148-1153112007_thumb.jpg

Here be the bundle:

Glass_Part4.zip

Cheers!

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...