|
|
|
|
|
|
#define LTC_MULTI_GGX_FRESNEL_DISNEY_DIFFUSE_INDEX 2 // RGB, A unused |
|
|
|
|
|
|
|
// SSS parameters |
|
|
|
#define N_PROFILES 8 |
|
|
|
uint _TransmissionFlags; // One bit per profile; 1 = enabled |
|
|
|
float _ThicknessRemaps[N_PROFILES][2]; // Remap: 0 = start, 1 = end - start |
|
|
|
float4 _HalfRcpVariancesAndLerpWeights[N_PROFILES][2]; // 2x Gaussians per color channel, A is the the associated interpolation weight |
|
|
|
#define SSS_N_PROFILES 8 |
|
|
|
#define SSS_UNIT_CONVERSION (1.0 / 300.0) // From meters to 1/3 centimeters |
|
|
|
uint _TransmissionFlags; // One bit per profile; 1 = enabled |
|
|
|
float _ThicknessRemaps[SSS_N_PROFILES][2]; // Remap: 0 = start, 1 = end - start |
|
|
|
float4 _HalfRcpVariancesAndLerpWeights[SSS_N_PROFILES][2]; // 2x Gaussians per color channel, A is the the associated interpolation weight |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
// Helper functions/variable specific to this material |
|
|
|
|
|
|
// Thickness and SSS radius are decoupled for artists. |
|
|
|
// In theory, we should modify the thickness by the inverse of the radius scale of the profile. |
|
|
|
// thickness /= radiusScale; |
|
|
|
thickness *= 300; |
|
|
|
thickness /= SSS_UNIT_CONVERSION; |
|
|
|
|
|
|
|
float t2 = thickness * thickness; |
|
|
|
|
|
|
|
|
|
|
bsdfData.fresnel0 = 0.028; // TODO take from subsurfaceProfile |
|
|
|
bsdfData.subsurfaceProfile = surfaceData.subsurfaceProfile; |
|
|
|
// Make the Std. Dev. of 1 correspond to the effective radius of 1 cm (three-sigma rule). |
|
|
|
bsdfData.subsurfaceRadius = (1.0 / 300.0) * surfaceData.subsurfaceRadius; |
|
|
|
bsdfData.thickness = (1.0 / 300.0) * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] + |
|
|
|
_ThicknessRemaps[bsdfData.subsurfaceProfile][1] * surfaceData.thickness); |
|
|
|
bsdfData.subsurfaceRadius = SSS_UNIT_CONVERSION * surfaceData.subsurfaceRadius; |
|
|
|
bsdfData.thickness = SSS_UNIT_CONVERSION * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] + |
|
|
|
_ThicknessRemaps[bsdfData.subsurfaceProfile][1] * surfaceData.thickness); |
|
|
|
bsdfData.enableTransmission = (1 << bsdfData.subsurfaceProfile) & _TransmissionFlags; |
|
|
|
if (bsdfData.enableTransmission) |
|
|
|
{ |
|
|
|
|
|
|
} |
|
|
|
else if (surfaceData.materialId == MATERIALID_LIT_SSS) |
|
|
|
{ |
|
|
|
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(N_PROFILES)); |
|
|
|
outGBuffer2 = float4(surfaceData.subsurfaceRadius, surfaceData.thickness, 0.0, surfaceData.subsurfaceProfile * rcp(SSS_N_PROFILES)); |
|
|
|
} |
|
|
|
else if (surfaceData.materialId == MATERIALID_LIT_CLEAR_COAT) |
|
|
|
{ |
|
|
|
|
|
|
{ |
|
|
|
bsdfData.diffuseColor = baseColor; |
|
|
|
bsdfData.fresnel0 = 0.028; // TODO take from subsurfaceProfile |
|
|
|
bsdfData.subsurfaceProfile = N_PROFILES * inGBuffer2.a; |
|
|
|
bsdfData.subsurfaceProfile = SSS_N_PROFILES * inGBuffer2.a; |
|
|
|
bsdfData.subsurfaceRadius = (1.0 / 300.0) * inGBuffer2.r; |
|
|
|
bsdfData.thickness = (1.0 / 300.0) * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] + |
|
|
|
_ThicknessRemaps[bsdfData.subsurfaceProfile][1] * inGBuffer2.g); |
|
|
|
bsdfData.subsurfaceRadius = SSS_UNIT_CONVERSION * inGBuffer2.r; |
|
|
|
bsdfData.thickness = SSS_UNIT_CONVERSION * (_ThicknessRemaps[bsdfData.subsurfaceProfile][0] + |
|
|
|
_ThicknessRemaps[bsdfData.subsurfaceProfile][1] * inGBuffer2.g); |
|
|
|
bsdfData.enableTransmission = (1 << bsdfData.subsurfaceProfile) & _TransmissionFlags; |
|
|
|
if (bsdfData.enableTransmission) |
|
|
|
{ |
|
|
|