Tuesday, June 30, 2015

A new iOS photo app: Subjective

We have a new iOS photo app out that combines some features of our previous apps.   The basic idea we have been pursuing for a while is based on the subjective refraction test from optometry where a person uses their own judgment for which of a set of things is better.  A/B testing is a more randomized version of this basic idea.

We first have you pick a category of editing (e.g., is it an outdoor landscape or is it food or do you want to make a stencil version like the Obama HOPE poser?).   It shows the image being edited as a background:

 Pick one of the filter families-- like Stencil

Now three screens of choose best of 4:
 Now pick best of four 3 times
 And voila!

And here's the product.

You can of course go more conventionally and adjust contract and color temperature and saturation (one screen for each).  I like this for food.  Here's before:

and after.   Is it better?  I think so, but it's SUBJECTIVE!

Monday, June 29, 2015

Ray tracing: refraction

As my new ray tracer is spectral I am rewriting some of the basics from scratch including dielectric code.   I figured I could cut and paste some stuff out of ancient "ray tracing news" but ran into some problems with normal vectors.   So I am re-deriving this for my own benefit.
 Sketch created with limnu iphone app from limnu.com
All renderers have some convention about which way surface normals point and whether that depends on incoming rays.   I am a fan of surfaces being boundaries between materials, and a dielectric has a surface normal N pointing to the side with refractive index n.   One thing that means is that in the diagram N might be pointing "down" along the dotted line.

First what about reflection?   It is usually the classic formula:

S = D - 2*N*dot(D, N)

Does that formula still work if N points along the dotted line?   Happily, yes-- try substituting -N in there and you get a "-" on the N and the dot product and they cancel.   Also, D need not be a unit vector.  I rarely require that in my ray tracers so I can use instancing if I want.   N however does need to be a unit vector.

Now what about refraction?   It obeys Snell's law:

n sin(theta) = n' sin(theta')

We can use the same trick as in reflection where we use N and D as a 2D basis.   First let's make life easy on ourselves and assume D is a unit vector and N points "up" like in the picture, and make an orthogonal basis (let's change the sin() and cos() with c, c', s, s')

D = -cN + sQ

Here Q is to the right and perpendicular to N.   We don't know what is is yet, but it we know what it is by rearranging the terms above to be get

Q = (D +  cN) / s

We also know that

T = -c'N + s'*Q

We know c = -dot(D,N), and s = sqrt(1 - c^2)

Further we know that s' = (n/n') s

Right there is a place we can get into trouble-- n can be high (over 2 for diamond) so if the more dense medium is where D is (the top medium), we could have s > 1.   In that case we get all reflection and no refraction (total internal reflection).   Here's a nice image of that:
 The water acts as a perfect mirror due to total internal reflection (from wikipedia)
OK plug and chug the algebra:

T = -c'N + s'Q

T =  -c'N + s'(D +  cN) / s

We know s'/s = n'/n.

We also know c' = sqrt(1-s'^2) = sqrt(1 - (n/n')^2 (1-c^2) ).

T = (n'/n) D +(c(n'/n) - sqrt(1 - (n/n')^2 (1-c^2) ))

putting back in c = -dot(D, N) we get

T = (n'/n) D +(-dot(D, N)(n'/n) - sqrt(1 - (n/n')^2 (1-dot(D, N)^2) )) N

Ok!  That agrees with the ray tracing news formula.   Now what happens when N points down?  Only the last term is different:

T = (n'/n) D +(-dot(D, N)(n'/n) + sqrt(1 - (n/n')^2 (1-dot(D, N)^2) )) N

Well isn't that annoying?   That sign difference is just sgn(dot(D, N)).   I never know how to best code that sort of thing, but when in doubt, be very readable!

if (dot(D,N) > 0) temp_normal = -N    // now proceed with original formula

Friday, June 26, 2015

First real test of new spectral renderer

I just ran my first serious end to end test of my (still primitive) spectral renderer.   I turned to the trusy Macbeth color checker (data from BabelColor which Brian Cabral turned me onto).   I used Chris Wyman's approximations to the XYZ tristimulous curves and they were so much more pleasant than typing that junk it.  This is the chart with just a uniform background(lambda) = constant and no lights.  Looks like it all works fine.  This was a great test case (which is why everybody uses it for spectral work) and it shook out several bugs.

Wednesday, June 24, 2015

HDR and stb_image.h

I just got my renderer where I wanted so I will start outputting hdr.   The simple library I talked about in an earlier post has a minimal but sweet interface for dealing with Radiance .rgbe/.hdr files.   This appears to work fine (reading in a pgm into floats and then cranking them up X10).   Question: on OSX what do people use to view Radiance image files?    I downloaded ximage for OSX but it needs x windows and I am trying to avoid installing X for no good reason (maybe just one of these moments I experience with perfectly good things like X).  Edit: I knuckled under and put X on my mac.   Running ximage from xterm works great.  ximage stands up well for its age!  The stb_image* support for HDR seems to work perfectly!

Retroreflective caustic

Here's a nice retroreflective caustic on the roof of my car:

Placing my phone camera there immediately reveals the culprit:
This is an example of retroreflection.   The wikipedia on corner reflectors (this type of retroreflector) article is excellent.

Tuesday, June 23, 2015

A small image IO library: stb_image.h

I did my first test of one of the several libraries y'all suggested (thanks again!): stb_image

That is one of the "all in one file" kinds of libraries with all documentation in that header.   As a KISS kind of person that still thinks terminals are cool, I have to admit the simplicity of the thing almost brought tears to my eyes.   It's mainly by Sean Barrett and it is very nicely documented (in comments!).  I decided to try it first because Christopher Kulla said pbrt uses it and I like the taste shown in pbrt.

For input you use stb_image.h but output is the compatible stb_image_write.h.   The take the image and shove it into a 3 bytes per pixel array (for 24 bit images).   I haven't tested hdr (Ward's rgbe for this library) yet but so far I am very very pleased with this code.

Here's my test of just the io (in another program I verified their simple internal representation).  Included as an image so it doesn't mess up formatting and I am too lazy for HTML.   Sean Barrett, whomever you are, the beer is definitely on me if we ever cross paths!  (edit-- Sean is a real person and has a twitter @nothings).

Wednesday, June 17, 2015

What image library/format should I use?

I am doing a new batch renderer and need to do image I/O including HDR (with viewer if possible).  Last time I did this it was all image magic and Greg Ward's rgbe code.   What are the cool kids using these days?

Tuesday, June 9, 2015

Some amazing new skin work.

One step closer to leaving the uncanny valley!   From researchers at USC and ICL.  Watch the video here.