OpenGL Renderer

Ideas, enhancements, feature requests and development related discussion.

Re: OpenGL Renderer

Postby dcuny » Wed Jan 23, 2008 9:12 pm

I've took a quick look at the Blender code, and played a bit with the SVN version of Blender. The AO routine is very impressive - it's fast, and produces nice contact shadows, even in areas in low tessellation:
blender_ao.jpg
Approximate Ambient Occlusion in Blender. The only lighting is AO.
blender_ao.jpg (9.35 KiB) Viewed 10165 times

Sweet. 8)
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby sascha » Wed Jan 23, 2008 10:48 pm

Very nice. What's the subdiv level, and how long did it take to render?
sascha
Site Admin
 
Posts: 2792
Joined: Thu May 20, 2004 9:16 am
Location: Austria

Re: OpenGL Renderer

Postby dcuny » Thu Jan 24, 2008 12:33 am

It took about 14 seconds to render, with a subdivision level of 1 and oversampling of 8. A full size image of 800x600 took about 40 seconds.

I rendered a small video clip to see how it looked in motion, and the contact shadow looks quite good. With more complex geometry, people have been complaining that it takes longer. But the numbers that I've seen posted show it to be about 5 - 8 times faster than the equivalent raytraced ambient occlusion. And, of course, it's noise free.

I've really got to do some work on wxBasic, but I'm tempted to write a good triangle rasterizer and put together a nice little scanline renderer. It wouldn't be nearly as fast as OpenGL, but it would be easier to write code for. Add ambient occlusion and spherical harmonics, and it's good to go... :?
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby dcuny » Sat Jan 26, 2008 12:07 pm

The Blender SVN code is all online. Here's the occlusion.c file, where the occlusion is calculated. The routines for calculating the spherical harmonics look like the SH routines found elsewhere - nothing really magical going on there. There's not a lot of documentation in the code, but it looks fairly straightforward.

There's also sss.c, which handles subsurface scattering. Interestingly, the High-Quality Ambient Occlusion article talks about being able to use the same code to calculate multiple scattering as well. I'd be curious to find out if they could be linked together. I'm not sure how well this works for skin, though - the NVidia articles I've been looking at argue that you've got to use multiple values for scattering, or else you end up with something that looks more like wax. :?

SInce AO is computationally expensive, I'm wondering if a deferred rendering approach would work. That is, calculate the occlusion only for the visible pixels, as a separate pass. I'm not sure how you deal with transparency, though... :|

Pity you can't call Blender as an external renderer yet.
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby sascha » Mon Feb 04, 2008 10:28 pm

I kept thinking about ambient occlusion. Two thoughts:
A ray tracer that uses ray differentials to
  • perform antialiasing on the shader level and
  • uses adaptive tesselation (with caching of already subdivided faces as long as there is memory available)
would be cool. It could use then use Pixar's approach to AO (smoothing the irradiance values over several animation frames).

Of course this would be pretty slow, so here's the second thought:
When using the approach with the precomputed discs, the artifacts are not caused because there are too few disks, but because we take only one sample per disc. Two examples:
1) A detailed model over a solid ground plane (a single quad).
2) An image you've posted: a character with a few strands of hair on the face.
Both will show artifacts on the less detailed parts: the ground plane in the first example, and the face in the second example. This is because we've got quite a bunch of disks in the high-detail areas, so the effect of these discs is there. What we're lacking are discs in the low detail areas: In the first example, we've got a single AO value for the entire floor, and in the second example we've only got a few AO samples for the entire face - not enough to reflect the effect of the (thin) strands of hair.

One solution is to subdivide everything until we've got enough discs in the high-detail areas as well, but this multiplies the number of discs even in areas where the detail level is high enough. What "enough detail" actually means depends on many parameters, including viewing angle and screen resolution. So the solution is simple: Sample at the pixel level instead of the vertex/face level.
I think you've mentioned using a pixel shader for doing that, but it should also be possible with a RenderMan shader:

Imagine a scene with 10,000 faces: We have to compute n*(n-1)/2=~ 50 million AO values.
Now suppose we're computing the AO amount per pixel: For a 800x600 image these are 480,000 pixel times 10,000 faces = 4.8 billion AO values to compute (shudder). But: We won't need that many faces to achieve good results, maybe 1,000 is enough, so we stop at about 500 million AO values (which still is about ten times as much as above). But do we need a sample at every pixel? I guess not. So we could set the shading level (for the AO pass) to something like 10 - compute an AO value every ten pixels and interpolate them. We'd end up at 50 million AO samples again, but the result probably looks much better than before. Better yet, for previews at e.g. 320x200, AO would run about 10 times faster. And for even higher resolutions (1920x1080 for example), we could probably use an even lower shading rate, so the AO computation time wouldn't increase linearly with the pixel count.

Thoughts?
sascha
Site Admin
 
Posts: 2792
Joined: Thu May 20, 2004 9:16 am
Location: Austria

Re: OpenGL Renderer

Postby dcuny » Mon Feb 04, 2008 11:01 pm

sascha wrote:I kept thinking about ambient occlusion.

So do I. I've reached the following conclusions:
  • Slow rendering is bad for animation.
  • There's nothing the matter with being "good enough".
  • If that's not good enough, use a different renderer

Of course this would be pretty slow

See the above list. ;)

...hair...

Hold on there, cowboy! Rendering hair is a special subdomain all its own.

One solution is to subdivide everything until we've got enough discs in the high-detail areas as well, but this multiplies the number of discs even in areas where the detail level is high enough.

It also multiplies estimated AO errors, see the "High Quality Ambient Occlusion" paper for details.

So the solution is simple: Sample at the pixel level instead of the vertex/face level.

That problem is discussed in the paper; you still get rendering artifacts.

Imagine a scene with 10,000 faces: We have to compute n*(n-1)/2=~ 50 million AO values.

The real problem is that people think they need to re-render the entire frame out each time. Even the "big boys" end up doing a lot of cheats (like rendering in layers) with no one the wiser.

I'll note that while BlueSky had the niftiest-keen GI renderer in the business, when it came time to render Ice Age they ended up using the same cheats that other studios do.

For big scenes, I think Composited Layers + Ambient Occlusion + Spherical Harmonics will end up giving the best bang for the buck. If you can't afford per-pixel AO, fall back to per-vertex AO. If you can't afford that, use hemisphere lighting.

Plus, we're already so close to being able to do this on commodity hardware, it's not even funny. :?
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby sascha » Tue Feb 05, 2008 11:09 am

...hair... Hold on there, cowboy! Rendering hair is a special subdomain all its own.

I was referring to this image:
Image
The hair is just another solid object (btw, I found the "clay" hair in Flushed Away sufficient). Clearly there are too few AO samples on the forehead, so we see artifacts.
I'd like to give the per-pixel approach a try with a RenderMan shader, so when I've got time I'll update my AO RIB export and the shaders.
Plus, we're already so close to being able to do this on commodity hardware, it's not even funny.

Yes, these days you have to be careful that your rendered movie (which of course took days if not months to render) isn't outperformed by some in-game sequence that's been rendered in realtime. :?
sascha
Site Admin
 
Posts: 2792
Joined: Thu May 20, 2004 9:16 am
Location: Austria

Re: OpenGL Renderer

Postby dcuny » Tue Feb 05, 2008 11:47 am

sascha wrote:I was referring to this image...

Ah. :oops:

Yes, "fake" hair generally works better for animated characters anyway.

Clearly there are too few AO samples on the forehead, so we see artifacts.

I've been intending to put those models into Blender to see how they render. I think the model would look great under per-pixel shading.

I'd like to give the per-pixel approach a try with a RenderMan shader, so when I've got time I'll update my AO RIB export and the shaders.

I've been playing around with the idea of writing a 3D triangle renderer, but deferring the actual shading until the final pass, after all the visibility has been determined. That get rid of a lot of unneeded calculations. To get around the size of the screen, dividing the screen into buckets might be an option.

Another possibility would be to use raytracing to make the visibility determination. That way, you're guaranteed to have visibility, and you have access to the raytracer for other cool effects like true reflections and accurate shadows. The problem with that approach is that you'd have to keep all your geometry in memory. Then again, if you're trying to do something so mammoth, you probably should be using RenderMan in the first place. :?
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby sascha » Tue Feb 05, 2008 1:43 pm

I've read some reasoning about why RenderMan usually shades before hiding. I can't remember all of them, but the most obvious are transparency and the fact that a displacement shader might make otherwise hidden areas visible (and vice versa). Not to mention motion- and focal blur...

GLSL should work too, the static data containing the occlusion discs could be passed to the shader as a texture. There's no such thing as a shading rate in GLSL, but alternatively the AO pass could be rendered at a lower resolution than the actual image.

With a separate AO pass, it could even make sense to use RenderMan for general shading and GLSL for high-quality AO only (and then using some compositor to merge the images).
sascha
Site Admin
 
Posts: 2792
Joined: Thu May 20, 2004 9:16 am
Location: Austria

Re: OpenGL Renderer

Postby dcuny » Tue Feb 05, 2008 6:16 pm

sascha wrote:I've read some reasoning about why RenderMan usually shades before hiding.

I think it's also cheaper in the long run, because calculations can take advantage of simple dx/dy changes over the micropolygon, which turn out to be expensive to calculate on the fly.

GLSL should work too, the static data containing the occlusion discs could be passed to the shader as a texture. There's no such thing as a shading rate in GLSL, but alternatively the AO pass could be rendered at a lower resolution than the actual image.

Yes, AO could be done as a separate pass. Doing it in software instead frees people from being locked into particular hardware, which is one of my (perhaps misplaced) concerns.

Something else I want to look into is the possibility of creating a stripped down version of Blender's renderer. That is, all I really need to do is render triangles, shade them, and apply AO. If I can rip these from Blender and create a stand alone command line version, it would prevent having to re-invent the wheel.
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby dcuny » Tue Feb 05, 2008 8:30 pm

I did a couple of renders in Blender for the sake of comparison. The only lighting in the scene is from ambient occlusion. I've included the ground plane to show the contact shadow. I've set the AO energy to 2.0 to make it more comparable to my rendering:

Here, the mesh is smoothed, but no SDS modifier is applied. The top of the boots are much too dark, and there seems to be a similar sort of error with the bootstraps. This is a problem with the plane - setting the falloff parameter helps, but doesn't completely fix the problem (I did not set the falloff in this image):
blender_aao_no_sds.png


Here's a closeup of the face, to show the rendering artifacts. I did the closeup shots later, so a few of the parameters are different. You can see the shadow from the hair is much better than the vertex-based AO, but using "real" geometry also causes exposes the low resolution of the mesh:
blender_aao_no_sds_cu.png
blender_aao_no_sds_cu.png (48.1 KiB) Viewed 10048 times


This render applies an SDS modifier (2 levels of refinement) to the mesh. The artifacts on the prior render are gone, but the rendering is still too dark:
blender_aao_sds.PNG


Here's a closeup of the face, with a single level of SDS refinement. There are some places that seem to bright (at the neck, at the edges of the hair), but the artifacts from the low-resolution mesh are gone:
blender_aao_sds_cu.PNG
blender_aao_sds_cu.PNG (43.87 KiB) Viewed 10045 times


This applies an "ad hoc" correction value to get rid of excessive darkening. I chose 0.5:
blender_aao_sds_corrected.PNG


Considering how fast and alias-free this is, I'm very impressed with AO in Blender. 8)
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby dcuny » Wed Feb 06, 2008 7:30 pm

The main reason I've been putting off writing a purely software renderer is the triangle rasterization - that code's always huge pain. I've written a "classical" scanline rasterizer before, and always had trouble with accuracy and cracks. The basic idea isn't difficult, but there's a bunch of exceptions and edge cases to deal with.

I ran across this tutorial on rasterizing using the half space method. I'd seen it before, but never really paid that much attention to it. It's slower than scanline rasterization, but it's pretty intuitive, which helps a lot. The main thing I've got to work out is how to interpolate barycentric coordinates. Time to start Googling... :?

Adapting the ambient occlusion to per-pixel process should be pretty straight forward. One difference is the disk will be an approximation of each triangle, not of the vertex. A lot of time in my code was spent determining which triangles shared which vertices, so it'll be nice to be able to no longer have to do that. :)
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby dcuny » Wed Feb 06, 2008 10:16 pm

I just ran across this thread which has a triangle rasterizer written in Java. So now I've got even more options. :)
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby dcuny » Tue Feb 26, 2008 1:29 am

I did a bit more digging around about the command line options in Blender. Not only can you launch it from the command line, but you can have it run a Python script. That means that you could create a data file from JPatch, and then call Blender to render it.

Of course, someone would have to write a Python script to read the import file. It's also not clear how "Python aware" the new features (SSS, AO) are.

Still, this is far preferable to writing a complete renderer from scratch. Plus (unlike a number of other options), Blender not encumbered by licensing issues and so forth. So I think it's well worth exploring as an export option for JPatch.
dcuny
 
Posts: 2902
Joined: Fri May 21, 2004 6:07 am

Re: OpenGL Renderer

Postby sascha » Tue Feb 26, 2008 9:00 am

Plus (unlike a number of other options), Blender not encumbered by licensing issues and so forth. So I think it's well worth exploring as an export option for JPatch.

I'd certainly prefere a FLOSS renderer over a proprietary one, even when it's free as in free beer. If Blenders renderer has all the features we need and can be called from an external application, it would be a cool thing. Blender also seems to have good compositing options, including OpenEXR support, so that would be interesting too.
I don't see the licensing issues in 3Delight though. The website states that a single license is free, even for commercial purposes. I'm not sure if this would be applicable for a distributed render farm - on the other hand it would still require just one license per render-farmer - I'll have to check the fine print or ask DNA about it. I could imagine that they'd agree, after all I don't plan to render anything commercial.
sascha
Site Admin
 
Posts: 2792
Joined: Thu May 20, 2004 9:16 am
Location: Austria

PreviousNext

Return to Development

Who is online

Users browsing this forum: No registered users and 2 guests

cron