浏览代码

Optimization for LTC area light: reusing already fetched FGD (clearcoat will now use FGD too instead of point-wise Fresnel term hack).

/main
Stephane Laroche 6 年前
当前提交
7f579046
共有 2 个文件被更改,包括 70 次插入9 次删除
  1. 2
      com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LtcData.GGX.cs
  2. 77
      com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl

2
com.unity.render-pipelines.high-definition/HDRP/Material/LTCAreaLight/LtcData.GGX.cs


// LTC area light Look up table (fit for GGX with height-correlated Smith's visibility term)
//-------------------------------------------------------------------------------------------
// This table is precomputed for squared roughness and normalized so that last entry
// This table is precomputed for sqrt(roughness) and normalized so that last entry
// is 1 and thus does not need to be store in a texture.
public static double[,] s_LtcGGXMatrixData = new double[k_LtcLUTResolution * k_LtcLUTResolution, k_LtcLUTMatrixDim * k_LtcLUTMatrixDim]
{

77
com.unity.render-pipelines.high-definition/HDRP/Material/Lit/Lit.hlsl


// 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.

正在加载...
取消
保存