|
|
|
|
|
|
float3 specular; |
|
|
|
}; |
|
|
|
|
|
|
|
struct ImageBasedLighting |
|
|
|
struct IndirectLighting |
|
|
|
{ |
|
|
|
float3 specularReflected; |
|
|
|
float3 specularTransmitted; |
|
|
|
|
|
|
{ |
|
|
|
DirectLighting direct; |
|
|
|
ImageBasedLighting ibl; |
|
|
|
IndirectLighting indirect; |
|
|
|
}; |
|
|
|
|
|
|
|
void AccumulateDirectLighting(AggregateLighting dst, DirectLighting src) |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
void AccumulateImageBasedLighting(AggregateLighting dst, ImageBasedLighting src) |
|
|
|
void AccumulateIndirectLighting(AggregateLighting dst, IndirectLighting src) |
|
|
|
dst.ibl.specularReflected += src.specularReflected; |
|
|
|
dst.ibl.specularTransmitted += src.specularTransmitted; |
|
|
|
dst.indirect.specularReflected += src.specularReflected; |
|
|
|
dst.indirect.specularTransmitted += src.specularTransmitted; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
|
|
|
// EvaluateBSDF_SSLighting for screen space lighting |
|
|
|
// ---------------------------------------------------------------------------- |
|
|
|
|
|
|
|
ImageBasedLighting EvaluateBSDF_SSReflection(LightLoopContext lightLoopContext, |
|
|
|
IndirectLighting EvaluateBSDF_SSReflection(LightLoopContext lightLoopContext, |
|
|
|
ImageBasedLighting lighting; |
|
|
|
ZERO_INITIALIZE(ImageBasedLighting, lighting); |
|
|
|
IndirectLighting lighting; |
|
|
|
ZERO_INITIALIZE(IndirectLighting, lighting); |
|
|
|
|
|
|
|
// TODO |
|
|
|
|
|
|
|
|
|
|
ImageBasedLighting EvaluateBSDF_SSRefraction(LightLoopContext lightLoopContext, |
|
|
|
IndirectLighting EvaluateBSDF_SSRefraction(LightLoopContext lightLoopContext, |
|
|
|
ImageBasedLighting lighting; |
|
|
|
ZERO_INITIALIZE(ImageBasedLighting, lighting); |
|
|
|
IndirectLighting lighting; |
|
|
|
ZERO_INITIALIZE(IndirectLighting, lighting); |
|
|
|
|
|
|
|
#if HAS_REFRACTION |
|
|
|
// Refraction process: |
|
|
|
|
|
|
// ---------------------------------------------------------------------------- |
|
|
|
|
|
|
|
// _preIntegratedFGD and _CubemapLD are unique for each BRDF |
|
|
|
ImageBasedLighting EvaluateBSDF_Env(LightLoopContext lightLoopContext, |
|
|
|
IndirectLighting EvaluateBSDF_Env( LightLoopContext lightLoopContext, |
|
|
|
ImageBasedLighting lighting; |
|
|
|
ZERO_INITIALIZE(ImageBasedLighting, lighting); |
|
|
|
IndirectLighting lighting; |
|
|
|
ZERO_INITIALIZE(IndirectLighting, lighting); |
|
|
|
|
|
|
|
float3 positionWS = posInput.positionWS; |
|
|
|
float weight = 1.0; |
|
|
|
|
|
|
|
|
|
|
UpdateLightingHierarchyWeights(hierarchyWeight, weight); |
|
|
|
lighting.specularReflected *= weight; |
|
|
|
|
|
|
|
return lighting; |
|
|
|
} |
|
|
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
|
|
|
|
|
// Try to mimic multibounce with specular color. Not the point of the original formula but ok result. |
|
|
|
// Take the min of screenspace specular occlusion and visibility cone specular occlusion |
|
|
|
#if GTAO_MULTIBOUNCE_APPROX |
|
|
|
lighting.ibl.specularReflected *= GTAOMultiBounce(min(bsdfData.specularOcclusion, specularOcclusion), bsdfData.fresnel0); |
|
|
|
lighting.indirect.specularReflected *= GTAOMultiBounce(min(bsdfData.specularOcclusion, specularOcclusion), bsdfData.fresnel0); |
|
|
|
lighting.ibl.specularReflected *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion)); |
|
|
|
lighting.indirect.specularReflected *= lerp(_AmbientOcclusionParam.rgb, float3(1.0, 1.0, 1.0), min(bsdfData.specularOcclusion, specularOcclusion)); |
|
|
|
#endif |
|
|
|
|
|
|
|
// TODO: we could call a function like PostBSDF that will apply albedo and divide by PI once for the loop |
|
|
|
|
|
|
// If refraction is enable we use the transmittanceMask to lerp between current diffuse lighting and refraction value |
|
|
|
// Physically speaking, it should be transmittanceMask should be 1, but for artistic reasons, we let the value vary |
|
|
|
#if HAS_REFRACTION |
|
|
|
diffuseLighting = lerp(diffuseLighting, lighting.ibl.specularTransmitted, bsdfData.transmittanceMask); |
|
|
|
diffuseLighting = lerp(diffuseLighting, lighting.indirect.specularTransmitted, bsdfData.transmittanceMask); |
|
|
|
specularLighting = lighting.direct.specular + lighting.ibl.specularReflected; |
|
|
|
specularLighting = lighting.direct.specular + lighting.indirect.specularReflected; |
|
|
|
// Rescale the GGX to account for the multiple scattering. |
|
|
|
specularLighting *= 1.0 + bsdfData.fresnel0 * preLightData.energyCompensation; |
|
|
|
|
|
|
|