Closed but0n closed 6 years ago
This guy is Lee Perry Smith
https://sketchfab.com/models/mhw51tRkmIB97P0OfM7YN5Y3RCd
https://sketchfab.com/models/4d07eb2030db4406bc7eee971d1d3a97 SSSSS
即便加上了SSSSS,皮肤可以逼真很多。但对于薄的地方,比如耳朵,除了SSS的贡献,还有很大一部分其实来自于光线的透射,也就是translucency的贡献。只有SSSSS也无法表达出耳朵的透光,需要另一个方法来做这件事情。幸运的是,Jorge Jimenez也开发出了这样的方法,并且也可以整理成一个screen space的post process。更有意思的是,translucency的结果只要直接叠加到原先shading上就可以了。可以单独使用,也可以和前面的SSSSS联合使用。
这个screen space translucency的输入是normal、diffuse、shading和shadow map,都是deferred rendering里现成的东西。所以可以很容易集成到现有pipeline。
Translucency + SSS SSS = PBR + Blur
The main consequence is that we have less information to work with in screen space, as opposed to algorithms that work in 3D or texture space. We lose irradiance in all points of the surface not seen from the camera, because only the visible pixels are rendered. So, we can no longer calculate the transmittance of light through thin parts of an object.
http://www.neilblevins.com/cg_education/translucency/translucency.htm
Translucency and Sub-Surface Scattering By Neil Blevins Created On: Sept 12th 2001 Updated On: June 12th 2006
As renderers become more advanced, expect to see these sorts of effects become more commonplace in our work. In the meantime, remember, SSS can be simulated in a number of ways, and no two ways work the same, and no one way works perfectly for all situations, so know your methods.
Light:
// This function can be precomputed for efficiency
float3 T(float s) {
return float3(0.233, 0.455, 0.649) * exp(-s * s / 0.0064) +
float3(0.1, 0.336, 0.344) * exp(-s * s / 0.0484) +
float3(0.118, 0.198, 0.0) * exp(-s * s / 0.187) +
float3(0.113, 0.007, 0.007) * exp(-s * s / 0.567) +
float3(0.358, 0.004, 0.0) * exp(-s * s / 1.99) +
float3(0.078, 0.0, 0.0) * exp(-s * s / 7.41);
}
Blend factor 最常用的alpha blending是SrcRGB SrcAlpha + DstRGB (1 – SrcAlpha)这样的方式。而这里需要的是RGB分别用不同的系数(但全屏都用那组系数),来模拟不同频率的光有不同的穿透力。所以这里SrcBlend需要设置为BLEND_FACTOR,DestBlend设置为INV_BLEND_FACTOR。并且在设置alpha blending状态的时候提供一个float4的factor,分别代表RGBA的系数。
vec3 vLTLight = vLight + vNormal * fLTDistortion;
float fLTDot = pow(dot(vEye, -vLTLight), iLTPower) * fLTScale;
vec3 fLT = fLightAttenuation * (fLTDot + fLTAmbient) * fLTThickness;
outColor.rgb += cDiffuseAlbedo * cLightDiffuse * fLT;
From:
float fLTDot = pow(dot(c.V, -vLTLight), 4.0) * 1.0;
To:
float fLTDot = pow(dot(c.N, -vLTLight), 4.0) * 1.0;
Backup
vec3 T(float s) {
return vec3(0.233, 0.455, 0.649) * exp(-s * s / 0.0064) +
vec3(0.1, 0.336, 0.344) * exp(-s * s / 0.0484) +
vec3(0.118, 0.198, 0.0) * exp(-s * s / 0.187) +
vec3(0.113, 0.007, 0.007) * exp(-s * s / 0.567) +
vec3(0.358, 0.004, 0.0) * exp(-s * s / 1.99) +
vec3(0.078, 0.0, 0.0) * exp(-s * s / 7.41);
}
vec3 translucency(vec3 l, st_core c) {
float thick = 1.0 -texture2D(uv_Thickness, xlv_TEXCOORD0).r;
vec3 vLTLight = normalize(l);
float fLTDot = pow(max(dot(c.N, -vLTLight), 0.4), 2.0) * 1.0;
vec3 fLT = 1.0 * (fLTDot + 0.0) * thick * T(thick);
return fLT;
}
论文里是视线方向和光照方向的点积(下图), 类似于高光的处理, 上图是法线和光照方向的点积
Screen-Space Sub Surface Scattering
http://iryoku.com/sssss/