浏览代码

Merge pull request #1222 from Unity-Technologies/Share-GetPreIntegratedFGD-function

Share GetPreIntegratedFGD
/main
GitHub 7 年前
当前提交
4a8c5ab6
共有 3 个文件被更改,包括 51 次插入29 次删除
  1. 24
      ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/BSDF.hlsl
  2. 34
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl
  3. 22
      ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/PreIntegratedFGD/PreIntegratedFGD.hlsl

24
ScriptableRenderPipeline/Core/CoreRP/ShaderLibrary/BSDF.hlsl


// Ref: https://seblagarde.wordpress.com/2013/04/29/memo-on-fresnel-equations/
// Fresnel dieletric / dielectric
real F_Fresnel(real ior, real u)
real F_FresnelDieletric(real ior, real u)
}
// Fresnel dieletric / conductor
real3 F_FresnelConductor(real3 eta, real3 etak, real cosTheta)
{
real cosTheta2 = cosTheta * cosTheta;
real sinTheta2 = 1.0 - cosTheta2;
real3 eta2 = eta * eta;
real3 etak2 = etak * etak;
real3 t0 = eta2 - etak2 - sinTheta2;
real3 a2plusb2 = sqrt(t0 * t0 + 4.0 * eta2 * etak2);
real3 t1 = a2plusb2 + cosTheta2;
real3 a = sqrt(0.5 * (a2plusb2 + t0));
real3 t2 = 2.0 * a * cosTheta;
real3 Rs = (t1 - t2) / (t1 + t2);
real3 t3 = cosTheta2 * a2plusb2 + sinTheta2 * sinTheta2;
real3 t4 = t2 * sinTheta2;
real3 Rp = Rs * (t3 - t4) / (t3 + t4);
return 0.5 * (Rp + Rs);
}
//-----------------------------------------------------------------------------

34
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/Lit/Lit.hlsl


bsdfData.thickness = max(thickness, 0.0001);
}
// For image based lighting, a part of the BSDF is pre-integrated.
// This is done both for specular and diffuse (in case of DisneyDiffuse)
void GetPreIntegratedFGD(float NdotV, float perceptualRoughness, float3 fresnel0, out float3 specularFGD, out float diffuseFGD, out float reflectivity)
{
// Pre-integrate GGX FGD
// Integral{BSDF * <N,L> dw} =
// Integral{(F0 + (1 - F0) * (1 - <V,H>)^5) * (BSDF / F) * <N,L> dw} =
// (1 - F0) * Integral{(1 - <V,H>)^5 * (BSDF / F) * <N,L> dw} + F0 * Integral{(BSDF / F) * <N,L> dw}=
// (1 - F0) * x + F0 * y = lerp(x, y, F0)
// Pre integrate DisneyDiffuse FGD:
// z = DisneyDiffuse
float3 preFGD = SAMPLE_TEXTURE2D_LOD(_PreIntegratedFGD, s_linear_clamp_sampler, float2(NdotV, perceptualRoughness), 0).xyz;
specularFGD = lerp(preFGD.xxx, preFGD.yyy, fresnel0);
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
diffuseFGD = 1.0;
#else
// Remap from the [0, 1] to the [0.5, 1.5] range.
diffuseFGD = preFGD.z + 0.5;
#endif
reflectivity = preFGD.y;
}
// This function is use to help with debugging and must be implemented by any lit material
// Implementer must take into account what are the current override component and
// adjust SurfaceData properties accordingdly

// IBL
// Handle IBL + multiscattering
float reflectivity;
GetPreIntegratedFGD(NdotV, preLightData.iblPerceptualRoughness, bsdfData.fresnel0, preLightData.specularFGD, preLightData.diffuseFGD, reflectivity);
float specularReflectivity;
GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV, preLightData.iblPerceptualRoughness, bsdfData.fresnel0, preLightData.specularFGD, preLightData.diffuseFGD, specularReflectivity);
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
preLightData.diffuseFGD = 1.0;
#endif
iblR = reflect(-V, iblN);
// This is a ad-hoc tweak to better match reference of anisotropic GGX.

// We deem the intensity difference of a couple of percent for high values of roughness
// to not be worth the cost of another precomputed table.
// Note: this formulation bakes the BSDF non-symmetric!
preLightData.energyCompensation = 1.0 / reflectivity - 1.0;
preLightData.energyCompensation = 1.0 / specularReflectivity - 1.0;
#else
preLightData.energyCompensation = 0.0;
#endif // LIT_USE_GGX_ENERGY_COMPENSATION

22
ScriptableRenderPipeline/HDRenderPipeline/HDRP/Material/PreIntegratedFGD/PreIntegratedFGD.hlsl


TEXTURE2D(_PreIntegratedFGD);
// For image based lighting, a part of the BSDF is pre-integrated.
// This is done both for specular GGX height-correlated and DisneyDiffuse
// reflectivity is Integral{(BSDF_GGX / F) - use for multiscattering
void GetPreIntegratedFGDGGXAndDisneyDiffuse(float NdotV, float perceptualRoughness, float3 fresnel0, out float3 GGXSpecularFGD, out float disneyDiffuseFGD, out float reflectivity)
{
float3 preFGD = SAMPLE_TEXTURE2D_LOD(_PreIntegratedFGD, s_linear_clamp_sampler, float2(NdotV, perceptualRoughness), 0).xyz;
// Pre-integrate GGX FGD
// Integral{BSDF * <N,L> dw} =
// Integral{(F0 + (1 - F0) * (1 - <V,H>)^5) * (BSDF / F) * <N,L> dw} =
// (1 - F0) * Integral{(1 - <V,H>)^5 * (BSDF / F) * <N,L> dw} + F0 * Integral{(BSDF / F) * <N,L> dw}=
// (1 - F0) * x + F0 * y = lerp(x, y, F0)
GGXSpecularFGD = lerp(preFGD.xxx, preFGD.yyy, fresnel0);
// Pre integrate DisneyDiffuse FGD:
// z = DisneyDiffuse
// Remap from the [0, 1] to the [0.5, 1.5] range.
disneyDiffuseFGD = preFGD.z + 0.5;
reflectivity = preFGD.y;
}
正在加载...
取消
保存