forked from LeenkxTeam/LNXSDK
97 lines
3.7 KiB
GLSL
97 lines
3.7 KiB
GLSL
|
|
// Separable SSS Transmittance Function, ref to sss_pass
|
|
vec3 SSSSTransmittance(mat4 LWVP, vec3 p, vec3 n, vec3 l, float lightFar, sampler2DShadow shadowMap, vec3 sssColor, float sssRadius
|
|
#ifdef _ShadowMapAtlas
|
|
, vec4 tileBounds
|
|
#endif
|
|
) {
|
|
const float translucency = 0.85;
|
|
vec4 shrinkedPos = vec4(p - 0.005 * n, 1.0);
|
|
vec4 shadowPos = LWVP * shrinkedPos;
|
|
vec2 shadowUV = shadowPos.xy / shadowPos.w;
|
|
#ifdef _ShadowMapAtlas
|
|
shadowUV = clamp(shadowUV, tileBounds.xy, tileBounds.zw);
|
|
#endif
|
|
float scale = 2.5 * (1.0 - translucency) / max(sssRadius, 0.001);
|
|
float d1 = texture(shadowMap, vec3(shadowUV, shadowPos.z)).r;
|
|
float d2 = shadowPos.z;
|
|
d1 *= lightFar;
|
|
d2 *= lightFar;
|
|
float d = scale * abs(d1 - d2) * 1000.0;
|
|
|
|
if (d > 10.0) return vec3(0.0);
|
|
float dd = -d * d;
|
|
vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) +
|
|
vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) +
|
|
vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) +
|
|
vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) +
|
|
vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) +
|
|
vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
|
|
profile *= mix(vec3(1.0), sssColor, 0.8);
|
|
return profile * clamp(0.5 + dot(l, -n), 0.0, 1.0);
|
|
}
|
|
|
|
#ifdef _ShadowMapAtlas
|
|
vec3 SSSSTransmittanceCubeAtlas(sampler2DShadow shadowMap, vec3 lightPos, vec3 p, vec3 n, vec3 l, float lightFar, vec2 lightProj, int index, vec3 sssColor, float sssRadius) {
|
|
const float translucency = 0.85;
|
|
vec3 shrinkedPos = p - 0.005 * n;
|
|
vec3 ld = normalize(shrinkedPos - lightPos);
|
|
#ifdef _InvY
|
|
ld.y = -ld.y;
|
|
#endif
|
|
float d2 = lpToDepth(ld, lightProj);
|
|
int faceIndex = 0;
|
|
int lightIndex = index * 6;
|
|
vec2 uv = sampleCube(ld, faceIndex);
|
|
vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex];
|
|
vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
|
|
#ifdef _FlipY
|
|
uvtiled.y = 1.0 - uvtiled.y;
|
|
#endif
|
|
float d1 = texture(shadowMap, vec3(uvtiled, d2)).r;
|
|
d1 *= lightFar;
|
|
d2 *= lightFar;
|
|
float scale = 2.5 * (1.0 - translucency) / max(sssRadius, 0.001);
|
|
// d1/d2 are in meters, sssRadius is in mm, exponential constants are in mm^2
|
|
float d = scale * abs(d1 - d2) * 1000.0; // Convert distance to mm
|
|
|
|
if (d > 10.0) return vec3(0.0);
|
|
float dd = -d * d;
|
|
vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) +
|
|
vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) +
|
|
vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) +
|
|
vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) +
|
|
vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) +
|
|
vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
|
|
profile *= mix(vec3(1.0), sssColor, 0.8);
|
|
return profile * clamp(0.5 + dot(l, -n), 0.0, 1.0);
|
|
}
|
|
#endif
|
|
|
|
vec3 SSSSTransmittanceCube(samplerCubeShadow shadowMapCube, vec3 lightPos, vec3 p, vec3 n, vec3 l, float lightFar, vec2 lightProj, vec3 sssColor, float sssRadius) {
|
|
const float translucency = 0.85;
|
|
vec3 shrinkedPos = p - 0.005 * n;
|
|
vec3 ld = normalize(shrinkedPos - lightPos);
|
|
#ifdef _InvY
|
|
ld.y = -ld.y;
|
|
#endif
|
|
float d2 = lpToDepth(ld, lightProj);
|
|
float d1 = texture(shadowMapCube, vec4(ld, d2)).r;
|
|
d1 *= lightFar;
|
|
d2 *= lightFar;
|
|
float scale = 2.5 * (1.0 - translucency) / max(sssRadius, 0.001);
|
|
// d1/d2 are in meters, sssRadius is in mm, exponential constants are in mm^2
|
|
float d = scale * abs(d1 - d2) * 1000.0; // Convert distance to mm
|
|
|
|
if (d > 10.0) return vec3(0.0);
|
|
float dd = -d * d;
|
|
vec3 profile = vec3(0.233, 0.455, 0.649) * exp(dd / 0.0064) +
|
|
vec3(0.1, 0.336, 0.344) * exp(dd / 0.0484) +
|
|
vec3(0.118, 0.198, 0.0) * exp(dd / 0.187) +
|
|
vec3(0.113, 0.007, 0.007) * exp(dd / 0.567) +
|
|
vec3(0.358, 0.004, 0.0) * exp(dd / 1.99) +
|
|
vec3(0.078, 0.0, 0.0) * exp(dd / 7.41);
|
|
profile *= mix(vec3(1.0), sssColor, 0.8);
|
|
return profile * clamp(0.5 + dot(l, -n), 0.0, 1.0);
|
|
}
|