Sign in to follow this  
Elixir

Translucent subsurface scattering approximation

Recommended Posts

Elixir    122
Does anyone know of a way to calculate translucent subsurface scattering in real time? For a good example of what I'm trying to simulate: I was thinking if I rendered each "frosted" part offscreen as a portal, then did a quick blur, it would look 1/2 decent. Has anyone tried this sort of thing before?

Share this post


Link to post
Share on other sites
Nik02    4348
I implemented a similar system a while ago, here is the pseudocode:


  1. Render scene as normal.
  2. Copy rendered image to a smaller texture, preferably on hw with stretch filtering.
  3. Render the effect areas into stencil buffer, effectively creating a mask for the effect.
  4. Set the stencil pass mode to non-zero.
  5. Using a pixel shader to sample the aforementioned texture with more blurring (gaussian, perhaps, and noise for "frost"), render the result to the framebuffer - which is now masked by the stencil buffer - using a full-screen quad.
  6. Repeat...

Share this post


Link to post
Share on other sites
lancekt    348

One of my profs at UM has done stuff with subsurface scattering:

http://www.cs.umd.edu/projects/gvil/projects/translucency.shtml

...Not that I particularly understand how it works. :)

Share this post


Link to post
Share on other sites
Nik02    4348
For this particular effect, the method I described is more suitable than any vertex-based approach (correct me if I'm wrong). The blurring, especially if combined with little noise, is a very good approximation of light refraction scattering in fundamentally flat geometry (such as frosted glass or mirrors).

Share this post


Link to post
Share on other sites
cignox1    735
Could you post a pic of your scene, when you've done it? I'm curious to see how it appears...

[Edited by - cignox1 on November 10, 2004 2:43:54 AM]

Share this post


Link to post
Share on other sites
Sneftel    1788
You've posted a fairly difficult example of subsurface scattering. Most approximations are performed in tangent-space, and are thus independent of the viewer; in more technical terms, they have a constant BRDF. This works well for surfaces with a fairly high scattering coefficient. The panels here, though, seem to have a low scattering coefficient. Thus, conventional real-time subsurface scattering techniques will be unacceptable as-is.



I suggest a combination method. The panels themselves should be lit with a realtime-determined ambience. To do this, do a low-res, untextured render of the scene from the POV of the center of the panel, facing you, with maximum FOV, into a pbuffer. downsample this to a single pixel by generating mipmaps, and use that one-pixel mipmap later, as an additive blend over the entire panel. (You'll only need to calculate this value once every few frames.) Now, here's the tricky part. Do an initial render of the scene into a texture the size of your screen, with everything on your side of the plane of the panel clipped off. (This will require a custom-built projection equation; glFrustum will not be sufficient.) Render that texture to the framebuffer. Now render a blurred version of it _only_ into the areas the panel occupies, remembering to blend that source with the ambient color you calculated earlier. (A stencil will be useful here.) Now render everything on your side of the panel directly to the framebuffer, completing the scene.



Essentially what we're doing here is rendering our scene in three parts: everything on the other side of the panel, the panel, everything on our side of the panel. The panel itself is illuminated by everything on the other side via the blur, as well as by the averaging of the light on your side. We use the custom-clipped frustra to ensure that stuff on your side of the panel doesn't get blurred onto the panel itself.

Share this post


Link to post
Share on other sites
Nik02    4348
Quote:
Original post by Sneftel
...nice concept...


While this is more physically accurate than the method I recommended above, I think it is an overkill for this situation. As I see it, the blurring already gathers the ambience factor (mostly). Furthermore, my approach works with arbitrary amount of flat panels in one pass of the system as in, for example, the OP picture. However, I'm going to test your concept soon [smile]

Kind regards,
-Nik

EDIT: Ah, but my method does not take into account the light coming from the viewer's side of the panels! However, for simulations sake, it should suffice that the ambient mean is the same across the environment...

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Does the OP image really show subsurface scattering?
It looks just like blurred refractions to me. Say you have a perfectly smooth glass pane - this has no subsurface scattering. Now if its fogged.. then the objects on the other side of the glass appear to be blurred. But this is due to the surface "dew" rather than scattering inside the glass. This is like "diffuse refractions". If the surface of the glass itself is not smooth but has small bumps.. then you'd have a similar effect too.
I feel blurring the image of the objects on the other side of the panel tries to simulate this effect. The blur factor should be dependent on the distance of the pixel from the translucent material. The farther the object, the blurrier it appears.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster   
Guest Anonymous Poster
Since a real glass panel is not entirely transparent, a small amount of light is destined to reflect back even if the panel was entirely smooth.

If the panel is frosted, both the back and front light tend to be blurred, because of the refraction (and reflection) distortion caused by the small bumps that you correctly mention - however, the reflection should still be approximated using a technique that fits the quality requirements.

And yes, on high-quality implementations, the distance from blur candidate pixels to the refractor surface should be taken into account. The effect can easily be achieved with multiple render targets and (optionally) PS3.0 hardware.

Share this post


Link to post
Share on other sites
chrisATI    266
Quote:
Original post by Elixir
Does anyone know of a way to calculate translucent subsurface scattering in real time? For a good example of what I'm trying to simulate:



I was thinking if I rendered each "frosted" part offscreen as a portal, then did a quick blur, it would look 1/2 decent. Has anyone tried this sort of thing before?


At the Advanced Renderman SIGGRAPH'03 course, Pixar talked about transparency tricks they used to render the jellyfish in Finding Nemo. This same trick (they called it "transblurancy") would give the type of effect you're looking for (things get more blury the further they are behind the frosted glass). You can find the course notes here:

http://www.renderman.org/RMR/Books/index.html#Sig

You want the notes from 2003, specifically you want the Advanced Renderman course notes and the section of the notes that are most relevant are "Translucency Tricks" by Wayne Wooten. It's presented in the context of Renderman shaders but the techinque maps directly to realtime shader code. The blur kernel is a growable poisson disc, you can find shader code for performing this kind of blur in a presentation I gave at GDCE, the slides are here:

http://www.ati.com/developer/gdce/Oat-ScenePostprocessing.pps

Good luck! --Chris

Share this post


Link to post
Share on other sites
EvilDecl81    360
Quote:
Original post by Elixir
Does anyone know of a way to calculate translucent subsurface scattering in real time? For a good example of what I'm trying to simulate:



I was thinking if I rendered each "frosted" part offscreen as a portal, then did a quick blur, it would look 1/2 decent. Has anyone tried this sort of thing before?


You could try to do subsurface scattering is to use PRT - its basically free sinceu the response functions respond to light from all directions, rather then just the visible hemisphere. The only difficulty with this is that it works well only for low frequancy lighting enviroments where the light is assume to be from an infinitly far away. However, if you had a finite number of lights and your door was on a fixed path you could build a set of response functions and interpolate through them as the door opened.

The DXSDK has an example of the infinite direction subsurface scattering.

This might be overkill for such a simple object however, perhaps render the object in texture space normally (as if it was solid), smooth it (much like ATI does for their Ruby Demo), and then alpha blend it on.


Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this