|
|
|
|
|
|
bsdfData.diffuseColor = surfaceData.baseColor * (1.0 - surfaceData.metallic); |
|
|
|
bsdfData.fresnel0 = lerp(float3(surfaceData.specular, surfaceData.specular, surfaceData.specular), surfaceData.baseColor, surfaceData.metallic); |
|
|
|
|
|
|
|
bsdfData.tangentWS = surfaceData.tangentWS; |
|
|
|
bsdfData.bitangentWS = cross(surfaceData.normalWS, surfaceData.tangentWS); |
|
|
|
bsdfData.tangentWS = surfaceData.tangentWS; |
|
|
|
bsdfData.bitangentWS = cross(surfaceData.normalWS, surfaceData.tangentWS); |
|
|
|
ConvertAnisotropyToRoughness(bsdfData.roughness, surfaceData.anisotropy, bsdfData.roughnessT, bsdfData.roughnessB); |
|
|
|
bsdfData.anisotropy = surfaceData.anisotropy; |
|
|
|
|
|
|
|
|
|
|
bsdfData.fresnel0 = lerp(float3(specular, specular, specular), baseColor, metallic); |
|
|
|
|
|
|
|
bsdfData.tangentWS = UnpackNormalOctEncode(float2(inGBuffer2.rg * 2.0 - 1.0)); |
|
|
|
// TODO: Do we need to orthonormalize here, IIRC Eric say that we should |
|
|
|
bsdfData.bitangentWS = cross(bsdfData.normalWS, bsdfData.tangentWS); |
|
|
|
ConvertAnisotropyToRoughness(bsdfData.roughness, anisotropy, bsdfData.roughnessT, bsdfData.roughnessB); |
|
|
|
bsdfData.anisotropy = anisotropy; |
|
|
|
|
|
|
P1 -= positionWS; |
|
|
|
P2 -= positionWS; |
|
|
|
|
|
|
|
// Construct an orthonormal basis (local coordinate system) around N. |
|
|
|
// TODO: it could be stored in PreLightData. All LTC lights compute it more than once! |
|
|
|
// Also consider using 'bsdfData.tangentWS', 'bsdfData.bitangentWS', 'bsdfData.normalWS'. |
|
|
|
// Construct a view-dependent orthonormal basis around N. |
|
|
|
// TODO: it could be stored in PreLightData, since all LTC lights compute it more than once. |
|
|
|
float3x3 basis; |
|
|
|
basis[0] = normalize(V - bsdfData.normalWS * preLightData.NdotV); |
|
|
|
basis[1] = normalize(cross(bsdfData.normalWS, basis[0])); |
|
|
|
|
|
|
// ---------------------------------------------------------------------------- |
|
|
|
|
|
|
|
// Ref: Moving Frostbite to PBR (Appendix A) |
|
|
|
float3 IntegrateLambertIBLRef( LightLoopContext lightLoopContext, |
|
|
|
EnvLightData lightData, BSDFData bsdfData, |
|
|
|
uint sampleCount = 4096) |
|
|
|
float3 IntegrateLambertIBLRef(LightLoopContext lightLoopContext, |
|
|
|
float3 V, EnvLightData lightData, BSDFData bsdfData, |
|
|
|
uint sampleCount = 4096) |
|
|
|
float3 N = bsdfData.normalWS; |
|
|
|
float3 tangentX = bsdfData.tangentWS; |
|
|
|
float3x3 localToWorld = GetLocalFrame(N, tangentX); |
|
|
|
float3x3 localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS); |
|
|
|
float2 randNum = InitRandom(N.xy * 0.5 + 0.5); |
|
|
|
float2 randNum = InitRandom(V.xy * 0.5 + 0.5); |
|
|
|
|
|
|
|
for (uint i = 0; i < sampleCount; ++i) |
|
|
|
{ |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
float3 IntegrateDisneyDiffuseIBLRef(LightLoopContext lightLoopContext, |
|
|
|
float3 V, EnvLightData lightData, BSDFData bsdfData, |
|
|
|
float3 V, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, |
|
|
|
float3 N = bsdfData.normalWS; |
|
|
|
float3 tangentX = bsdfData.tangentWS; |
|
|
|
// This function call may modify the normal. |
|
|
|
float NdotV = GetShiftedNdotV(N, V, false); |
|
|
|
float3x3 localToWorld = GetLocalFrame(N, tangentX); |
|
|
|
float3x3 localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS); |
|
|
|
float2 randNum = InitRandom(N.xy * 0.5 + 0.5); |
|
|
|
float2 randNum = InitRandom(V.xy * 0.5 + 0.5); |
|
|
|
|
|
|
|
for (uint i = 0; i < sampleCount; ++i) |
|
|
|
{ |
|
|
|
|
|
|
float LdotH = dot(L, H); |
|
|
|
// Note: we call DisneyDiffuse that require to multiply by Albedo / PI. Divide by PI is already taken into account |
|
|
|
// in weightOverPdf of ImportanceSampleLambert call. |
|
|
|
float disneyDiffuse = DisneyDiffuse(NdotV, NdotL, LdotH, bsdfData.perceptualRoughness); |
|
|
|
float disneyDiffuse = DisneyDiffuse(preLightData.NdotV, NdotL, LdotH, bsdfData.perceptualRoughness); |
|
|
|
|
|
|
|
// diffuse Albedo is apply here as describe in ImportanceSampleLambert function |
|
|
|
float4 val = SampleEnv(lightLoopContext, lightData.envIndex, L, 0); |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
// Ref: Moving Frostbite to PBR (Appendix A) |
|
|
|
float3 IntegrateSpecularGGXIBLRef( LightLoopContext lightLoopContext, |
|
|
|
float3 V, EnvLightData lightData, BSDFData bsdfData, |
|
|
|
uint sampleCount = 4096) |
|
|
|
float3 IntegrateSpecularGGXIBLRef(LightLoopContext lightLoopContext, |
|
|
|
float3 V, PreLightData preLightData, EnvLightData lightData, BSDFData bsdfData, |
|
|
|
uint sampleCount = 4096) |
|
|
|
float3 N = bsdfData.normalWS; |
|
|
|
float3 tangentX = bsdfData.tangentWS; |
|
|
|
float3 tangentY = bsdfData.bitangentWS; |
|
|
|
// This function call may modify the normal. |
|
|
|
float NdotV = GetShiftedNdotV(N, V, false); |
|
|
|
float3x3 localToWorld = GetLocalFrame(N, tangentX); |
|
|
|
float3x3 localToWorld = float3x3(bsdfData.tangentWS, bsdfData.bitangentWS, bsdfData.normalWS); |
|
|
|
|
|
|
|
// Add some jittering on Hammersley2d |
|
|
|
float2 randNum = InitRandom(V.xy * 0.5 + 0.5); |
|
|
|
|
|
|
|
|
|
|
// GGX BRDF |
|
|
|
if (bsdfData.materialId == MATERIALID_LIT_ANISO) |
|
|
|
{ |
|
|
|
ImportanceSampleAnisoGGX(u, V, N, tangentX, tangentY, bsdfData.roughnessT, bsdfData.roughnessB, NdotV, L, VdotH, NdotL, weightOverPdf); |
|
|
|
ImportanceSampleAnisoGGX(u, V, localToWorld, bsdfData.roughnessT, bsdfData.roughnessB, preLightData.NdotV, L, VdotH, NdotL, weightOverPdf); |
|
|
|
ImportanceSampleGGX(u, V, localToWorld, bsdfData.roughness, NdotV, L, VdotH, NdotL, weightOverPdf); |
|
|
|
ImportanceSampleGGX(u, V, localToWorld, bsdfData.roughness, preLightData.NdotV, L, VdotH, NdotL, weightOverPdf); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef LIT_DISPLAY_REFERENCE_IBL |
|
|
|
|
|
|
|
specularLighting = IntegrateSpecularGGXIBLRef(lightLoopContext, V, lightData, bsdfData); |
|
|
|
specularLighting = IntegrateSpecularGGXIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData); |
|
|
|
diffuseLighting = IntegrateLambertIBLRef(lightData, bsdfData); |
|
|
|
diffuseLighting = IntegrateLambertIBLRef(lightData, V, bsdfData); |
|
|
|
diffuseLighting = IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, lightData, bsdfData); |
|
|
|
diffuseLighting = IntegrateDisneyDiffuseIBLRef(lightLoopContext, V, preLightData, lightData, bsdfData); |
|
|
|
#endif |
|
|
|
*/ |
|
|
|
diffuseLighting = float3(0.0, 0.0, 0.0); |
|
|
|
|
|
|
specularLighting *= bsdfData.specularOcclusion; |
|
|
|
diffuseLighting = float3(0.0, 0.0, 0.0); |
|
|
|
|
|
|
|
#endif |
|
|
|
#endif |
|
|
|
|
|
|
|
|