|
|
|
|
|
|
// Configuration |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
|
|
|
|
// Use the same FGD table than for environments, since it is the same |
|
|
|
// (Saves fetches and VGPRs in PreLightData. |
|
|
|
#define LTC_USE_COMMON_FGD |
|
|
|
|
|
|
|
|
|
|
|
// Choose between Lambert diffuse and Disney diffuse (enable only one of them) |
|
|
|
// #define LIT_DIFFUSE_LAMBERT_BRDF |
|
|
|
#define LIT_USE_GGX_ENERGY_COMPENSATION |
|
|
|
|
|
|
float3 iblR; // Dominant specular direction, used for IBL in EvaluateBSDF_Env() |
|
|
|
float iblPerceptualRoughness; |
|
|
|
|
|
|
|
float3 specularFGD; // Store preconvoled BRDF for both specular and diffuse |
|
|
|
float3 specularFGD; // Store preintegrated BSDF for both specular and diffuse |
|
|
|
float diffuseFGD; |
|
|
|
|
|
|
|
// Area lights (17 VGPRs) |
|
|
|
|
|
|
float3x3 ltcTransformSpecular; // Inverse transformation for GGX (4x VGPRs) |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#endif |
|
|
|
float coatIblF; // Fresnel term for view vector |
|
|
|
float coatIblF; // Fresnel term for view vector or specularFGD term for coat (if LTC_USE_COMMON_FGD) |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#endif |
|
|
|
|
|
|
|
#if HAS_REFRACTION |
|
|
|
// Refraction |
|
|
|
|
|
|
|
|
|
|
preLightData.coatPartLambdaV = GetSmithJointGGXPartLambdaV(NdotV, CLEAR_COAT_ROUGHNESS); |
|
|
|
preLightData.coatIblR = reflect(-V, N); |
|
|
|
|
|
|
|
//#ifndef LTC_USE_COMMON_FGD |
|
|
|
//#endif |
|
|
|
} |
|
|
|
|
|
|
|
float3 iblN, iblR; |
|
|
|
|
|
|
preLightData.orthoBasisViewNormal[2] = N; |
|
|
|
preLightData.orthoBasisViewNormal[1] = cross(preLightData.orthoBasisViewNormal[2], preLightData.orthoBasisViewNormal[0]); |
|
|
|
|
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#endif |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#endif |
|
|
|
#endif //LIT_DIFFUSE_LAMBERT_BRDF |
|
|
|
#endif //LTC_USE_COMMON_FGD #else we will use preLightData.diffuseFGD; |
|
|
|
|
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
//#else we will use preLightData.specularFGD; |
|
|
|
#endif |
|
|
|
|
|
|
|
if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_CLEAR_COAT)) |
|
|
|
{ |
|
|
|
|
|
|
preLightData.ltcTransformCoat._m22 = 1.0; |
|
|
|
preLightData.ltcTransformCoat._m00_m02_m11_m20 = SAMPLE_TEXTURE2D_ARRAY_LOD(_LtcData, s_linear_clamp_sampler, uv, LTC_GGX_MATRIX_INDEX, 0); |
|
|
|
|
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#else |
|
|
|
// We will use the original FGD table and since we paid the cost of the fetch, we now have |
|
|
|
// the proper FGD for the coat too, so assign it to coatIblF instead of the non integrated |
|
|
|
// Fresnel Schlick above. The compiler should also remove the Schlick evaluation (not used). |
|
|
|
// That also saves another VGPR. |
|
|
|
float dFGD; |
|
|
|
float3 sFGD; |
|
|
|
GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV, CLEAR_COAT_PERCEPTUAL_ROUGHNESS, float3(1.0,1.0,1.0)*CLEAR_COAT_F0, sFGD, dFGD, specularReflectivity); |
|
|
|
preLightData.coatIblF = sFGD.x * bsdfData.coatMask; |
|
|
|
#endif |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
// refraction (forward only) |
|
|
|
|
|
|
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformDiffuse); |
|
|
|
ltcValue *= lightData.diffuseScale; |
|
|
|
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF(). |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#else |
|
|
|
lighting.diffuse = preLightData.diffuseFGD * ltcValue; |
|
|
|
#endif |
|
|
|
|
|
|
|
UNITY_BRANCH if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION)) |
|
|
|
{ |
|
|
|
|
|
|
// Evaluate the specular part |
|
|
|
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformSpecular); |
|
|
|
ltcValue *= lightData.specularScale; |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#else |
|
|
|
lighting.specular = preLightData.specularFGD * ltcValue; |
|
|
|
#endif |
|
|
|
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformCoat); |
|
|
|
ltcValue *= lightData.specularScale; |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
ltcValue = LTCEvaluate(P1, P2, B, preLightData.ltcTransformCoat); |
|
|
|
ltcValue *= lightData.specularScale; |
|
|
|
#else |
|
|
|
lighting.diffuse *= (1.0 - preLightData.coatIblF); |
|
|
|
lighting.specular *= (1.0 - preLightData.coatIblF); |
|
|
|
lighting.specular += preLightData.coatIblF * ltcValue; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
// Save ALU by applying 'lightData.color' only once. |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
// EvaluateBSDF_Area - Approximation with Linearly Transformed Cosines |
|
|
|
// EvaluateBSDF_Rect - Approximation with Linearly Transformed Cosines |
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
|
|
|
|
// #define ELLIPSOIDAL_ATTENUATION |
|
|
|
|
|
|
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformDiffuse)); |
|
|
|
ltcValue *= lightData.diffuseScale; |
|
|
|
// We don't multiply by 'bsdfData.diffuseColor' here. It's done only once in PostEvaluateBSDF(). |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#else |
|
|
|
lighting.diffuse = preLightData.diffuseFGD * ltcValue; |
|
|
|
#endif |
|
|
|
|
|
|
|
UNITY_BRANCH if (HasFeatureFlag(bsdfData.materialFeatures, MATERIALFEATUREFLAGS_LIT_TRANSMISSION)) |
|
|
|
{ |
|
|
|
|
|
|
// Polygon irradiance in the transformed configuration. |
|
|
|
ltcValue = PolygonIrradiance(mul(lightVerts, preLightData.ltcTransformSpecular)); |
|
|
|
ltcValue *= lightData.specularScale; |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
#else |
|
|
|
lighting.specular += preLightData.specularFGD * ltcValue; |
|
|
|
#endif |
|
|
|
lighting.diffuse *= (1.0 - preLightData.ltcMagnitudeCoatFresnel); |
|
|
|
lighting.specular *= (1.0 - preLightData.ltcMagnitudeCoatFresnel); |
|
|
|
#ifndef LTC_USE_COMMON_FGD |
|
|
|
lighting.diffuse *= (1.0 - preLightData.ltcMagnitudeCoatFresnel); |
|
|
|
lighting.specular *= (1.0 - preLightData.ltcMagnitudeCoatFresnel); |
|
|
|
#else |
|
|
|
lighting.diffuse *= (1.0 - preLightData.coatIblF); |
|
|
|
lighting.specular *= (1.0 - preLightData.coatIblF); |
|
|
|
lighting.specular += preLightData.coatIblF * ltcValue; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
// Save ALU by applying 'lightData.color' only once. |
|
|
|