Skip to main content

Fast subsurface scattering

Fig.1 - Fast Subsurface scattering of Stanford Bunny

Based on the implementation of three.js. It provides a cheap, fast, and convincing approach to do ray-tracing in translucent surfaces. It refers the sharing in GDC 2011 [1], and the approach is used by Frostbite 2 and Unity engines [1][2][3]. Traditionally, when a ray intersects with surfaces, it needs to calculate the bouncing result after intersections. Materials can be divided into three types roughly. Opaque, lights can't go through its geometry and the ray will be bounced back. Transparency, the ray passes and allow it through the surface totally, it probably would loose a little energy after leaving. Translucency, the ray after entering the surface will be bounced internally like below Fig. 2.

Fig.2 - BSSRDF [1]

In the case of translucency, we have several subsurface scattering approaches to solve our problem. When a light is traveling inside the shape, that needs to consider the diffuse value influence according the varying thickness of objects. As the Fig. 3 below, when a light leaving a surface, it generates diffusion and has attenuation based on the thickness of the shapes.

Fig.3 - Translucent lighting [1]

Thus, we need to have a way to determine the thickness inside surfaces. The most direct way is calculating  ambient occlusion to get its local thickness into a thickness map. The thickness map as below Fig.4 can be easy to generate from DCC tools.

Fig.4 - Local thickness map of Stanford Bunny

Then, we can start to implement our approximate subsurface scattering approach.

The tricky part of the exit light is its direction is opposite to the incident light.  Therefore,  we get the light attenuation with  dot(geometryViewDir, -scatteringHalf) as its attenuation. Besides, We have several parameters that can be discussed detailed.

thicknessAmbient
- Ambient light value
- Visible from all angles even at the back side of surfaces

thicknessPower
- Power value of direct translucency
- View independent

thicknessDistortion
- Subsurface distortion
- Shift the surface normal
- View dependent

thicknessMap
- Pre-computed local thickness map
- Attenuates the back diffuse color with the local thickness map
- Can be utilized for both of direct and indirect lights

Because the local thickness map is precomputed, it doesn't work for animated/morph objects and concave objects. The alternative way is via real-time ambient occlusion map and inverting its normal or doing real-time thickness map.


Reference:
[1] GDC 2011 – Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look, https://colinbarrebrisebois.com/2011/03/07/gdc-2011-approximating-translucency-for-a-fast-cheap-and-convincing-subsurface-scattering-look/
[2] Fast Subsurface Scattering in Unity Part 1, https://www.alanzucconi.com/2017/08/30/fast-subsurface-scattering-1/
[3] Fast Subsurface Scattering in Unity Part 2, https://www.alanzucconi.com/2017/08/30/fast-subsurface-scattering-2/

Comments

Popular posts from this blog

tex2D vs. tex2Dproj

texCoord(  texX, texY, texZ , texW ) means texture coordinate after transforming from the texture matrix [ position goes through world, view, projection, and texture ] . We can use texCoord to fetch texture: 1.  float4 color = tex2D( sampler,  float2( texX / texW, texY/texW ); 2.  float4 color = tex2Dporj( sampler, float4( texX, texY, texZ, texW ) ); The top-two methods will have the same result. Because tex2Dproj operator supports divide w in its interface. http://www.gamedev.net/community/forums/topic.asp?topic_id=408894 http://bbs.gameres.com/showthread.asp?threadid=104316

Bringing Large Scale Console Game to iOS

Y8ObbsOsNQEhMCEhMCEt The Bard's Tale Why? Device are fast enough Market segment is not as crowded Hugh potential user base Rich back data log of content Potentially very low cost Session1: port process - application framework  - development workflow Session 2 port-port - performance/memory opt. OpenGL Cocoa Touch App Bring it all together Workflow: Data deployment OpenAL limit 32 active sources, DirectSound 256 channels on XBOX -Sluggish -5.8G -> 2Glimited on iOS 60Hz?    - terriable for battery life 30 Hz   - Game may depend on 60Hz Hybrid    -   60hz, functionsliity intact   - 30hz : low GPU/ save energy    -60hz, at 5th device is optional VFP?? Candidate for NEON SIMD SGX GPUs: a few stats Render opt. -minimal vertex format size -texture size and mipmapping Alpha test and SGX - Fragment discard expensive -huge impact on fill rate -use alpha blend at all costs Eliminating Alpha blend