浏览代码

Clean up multi-bounce GGX code

/Yibing-Project-2
Evgenii Golubev 7 年前
当前提交
5447c95b
共有 4 个文件被更改,包括 33 次插入46 次删除
  1. 8
      ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl
  2. 43
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl
  3. 2
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl
  4. 26
      ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/ComputeGgxEnergyCompensationFactors.shader

8
ScriptableRenderPipeline/Core/ShaderLibrary/ImageBasedLighting.hlsl


return acc / sampleCount;
}
float ComputeGgxEnergyCompensationFactor(float3 V, float3 N, float roughness, uint sampleCount = 4096)
float IntegrateGgxWithoutFresnel(float3 V, float3 N, float roughness, uint sampleCount = 4096)
{
float NdotV = saturate(dot(N, V));
float total = 0;

float3 L;
float VdotH, NdotL, weight;
// Compute Weight = BSDF * NdotL / PDF.
// Compute Weight = BSDF * NdotL / PDF. F = 1.
total += weight * rcp(sampleCount);
total += weight;
return saturate(total);
return saturate(total * rcp(sampleCount));
}
uint GetIBLRuntimeFilterSampleCount(uint mipLevel)

43
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Lit.hlsl


// Reference Lambert diffuse / GGX Specular for IBL and area lights
#ifdef HAS_LIGHTLOOP // Both reference define below need to be define only if LightLoop is present, else we get a compile error
//#define LIT_DISPLAY_REFERENCE_AREA
//#define LIT_DISPLAY_REFERENCE_IBL
// #define LIT_DISPLAY_REFERENCE_AREA
// #define LIT_DISPLAY_REFERENCE_IBL
// #define LIT_DIFFUSE_LAMBERT_BRDF
#define LIT_DIFFUSE_LAMBERT_BRDF
#define LIT_USE_GGX_ENERGY_COMPENSATION
// Sampler use by area light, gaussian pyramid, ambient occlusion etc...
SamplerState s_linear_clamp_sampler;

// GGX
float partLambdaV;
float3 energyCompensation;
float TdotV;
float BdotV;

preLightData.iblMipLevel = PerceptualRoughnessToMipmapLevel(iblPerceptualRoughness);
}
#ifdef LIT_USE_GGX_ENERGY_COMPENSATION
#if 1 // Evgenii's horrible hack to match Eric's results for gold in Mitsuba
float3 cbsdfInt = preLightData.specularFGD;
float3 Kms = 1 / cbsdfInt - 1;
float3 Fms = Sqr(bsdfData.fresnel0);
preLightData.energyCompensation = (1 + Fms * Kms);
preLightData.specularFGD = lerp(Fms, 1, cbsdfInt); // Equivalent to (specularFGD * energyCompensation)
#else // Emmanuel's reference implementation for metals
float cbsdfInt = SAMPLE_TEXTURE2D_LOD(_GgxEnergyCompensationFactors, s_linear_clamp_sampler, float2(NdotV, bsdfData.perceptualRoughness), 0).r;
float Kms = 1 / cbsdfInt - 1;
float3 Fms = bsdfData.fresnel0;
preLightData.energyCompensation = (1 + Fms * Kms);
preLightData.specularFGD *= preLightData.energyCompensation;
#endif
#else
preLightData.energyCompensation = 1;
#endif // LIT_USE_GGX_ENERGY_COMPENSATION
// Area light
// UVs for sampling the LUTs
float theta = FastACosPos(NdotV); // For Area light - UVs for sampling the LUTs

);
#endif
}
specularLighting += F * DV;
#define MS_GGX 1
#define MS_GGX_IMAGEWORKS 0
specularLighting += F * DV * preLightData.energyCompensation;
#if MS_GGX
#if MS_GGX_IMAGEWORKS
float ecV = SAMPLE_TEXTURE2D_LOD(_GgxEnergyCompensationFactors, s_linear_clamp_sampler, float2(NdotV, bsdfData.perceptualRoughness), 0).r;
float ecL = SAMPLE_TEXTURE2D_LOD(_GgxEnergyCompensationFactors, s_linear_clamp_sampler, float2(NdotL, bsdfData.perceptualRoughness), 0).r;
specularLighting += F * ecV * ecL;
#else
float ecV = SAMPLE_TEXTURE2D_LOD(_GgxEnergyCompensationFactors, s_linear_clamp_sampler, float2(NdotV, bsdfData.perceptualRoughness), 0).r;
specularLighting += F * DV * ecV;
#endif // MS_GGX_IMAGEWORKS
#endif // MS_GGX
#ifdef LIT_DIFFUSE_LAMBERT_BRDF
float diffuseTerm = Lambert();

2
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/LitReference.hlsl


}
}
return acc / sampleCount;
return acc * preLightData.energyCompensation / sampleCount;
}

26
ScriptableRenderPipeline/HDRenderPipeline/Material/Lit/Resources/ComputeGgxEnergyCompensationFactors.shader


float3 N = float3(0, 0, 1);
float3 V = float3(sqrt(1 - NdotV * NdotV), 0, NdotV);
float fDir = ComputeGgxEnergyCompensationFactor(V, N, roughness);
#define MS_GGX_IMAGEWORKS 0
#if MS_GGX_IMAGEWORKS
float fAvg = 0;
const uint numSamples = 128;
for (uint i = 0; i < numSamples; i++)
{
NdotV = (i + 0.5) * rcp(numSamples);
V = float3(sqrt(1 - NdotV * NdotV), 0, NdotV);
float cbsdfInt = IntegrateGgxWithoutFresnel(V, N, roughness);
fAvg += ComputeGgxEnergyCompensationFactor(V, N, roughness) * NdotV * (2 * rcp(numSamples));
}
// f_ms = f[NdotV, perceptualRoughness] * f[NdotL, perceptualRoughness].
float f = (1 - fDir) * rsqrt(PI * (1 - fAvg));
#else
// f_ms = f[NdotV, perceptualRoughness] * f_ss.
float f = 1 / fDir - 1;
#endif
return f.xxxx;
return cbsdfInt.xxxx;
}
ENDHLSL

正在加载...
取消
保存