Skip to main content
GameDev.net gamedev.net
🔒 Locked

Translucent subsurface scattering approximation

Started by Elixir Nov 8, 2004 at 3:33 PM 12 replies 5.7k views
Original Post
Elixir
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?
Nik02
Nik02
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...

Niko Suni
Elixir
Elixir
Awesome. Thanks =D
lancekt
lancekt

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. :)
Orin Tresnjak | Graphics ProgrammerBethesda Game StudiosStandard Disclaimer: My posts represent my opinions and not those of Bethesda/Zenimax, etc.
Nik02
Nik02
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).
Niko Suni
cignox1
cignox1
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]
Nik02
Nik02
I'll be happy to post pictures from my program, if I find the code - my archive is in my attic, in one of very numerous cardboard boxes...
Niko Suni
Sneftel
Sneftel
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.
Nik02
Nik02
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...
Niko Suni
Nik02
Nik02
By the way, the last AP was me. Wasn't logged in for some reason [smile]

-Nik
Niko Suni
chrisATI
chrisATI
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

EvilDecl81
EvilDecl81
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.


EvilDecl81

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.