#ifndef BADDOG_PREINTEGRATED_FGD_INCLUDED #define BADDOG_PREINTEGRATED_FGD_INCLUDED #include "Packages/com.baddog.rendering.arealight/Shaders/PreIntegratedFGD.cs.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl" #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/GlobalSamplers.hlsl" //----------------------------------------------------------------------------- // Pre-Integrated FGD Texture Declarations //----------------------------------------------------------------------------- // Pre-integrated FGD (Fresnel, Geometric, Diffuse) textures // These textures store pre-computed BSDF integrals for efficient IBL and area light evaluation TEXTURE2D(_PreIntegratedFGD_GGXDisneyDiffuse); TEXTURE2D(_PreIntegratedFGD_CharlieAndFabric); TEXTURE2D(_PreIntegratedFGD_Marschner); // Use URP's standard linear clamp sampler from GlobalSamplers.hlsl // sampler_LinearClamp is defined in GlobalSamplers.hlsl and can be used directly //----------------------------------------------------------------------------- // Pre-Integrated FGD Functions (GGX + Disney Diffuse) //----------------------------------------------------------------------------- // 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, float F90, out float3 specularFGD, out float diffuseFGD, out float reflectivity) { // We want the LUT to contain the entire [0, 1] range, without losing half a texel at each side. float2 coordLUT = Remap01ToHalfTexelCoord(float2(sqrt(NdotV), perceptualRoughness), FGDTEXTURE_RESOLUTION); float3 preFGD = SAMPLE_TEXTURE2D_LOD(_PreIntegratedFGD_GGXDisneyDiffuse, sampler_LinearClamp, coordLUT, 0).xyz; // Pre-integrate GGX FGD // Integral{BSDF * dw} = // Integral{(F0 + (F90 - F0) * (1 - )^5) * (BSDF / F) * dw} = // (F90 - F0) * Integral{(1 - )^5 * (BSDF / F) * dw} + F0 * Integral{(BSDF / F) * dw}= // (F90 - F0) * x + F0 * y specularFGD = (F90 - fresnel0) * preFGD.xxx + fresnel0 * preFGD.yyy; // Pre integrate DisneyDiffuse FGD: // z = DisneyDiffuse // Remap from the [0, 1] to the [0.5, 1.5] range. diffuseFGD = preFGD.z + 0.5; reflectivity = preFGD.y; } // Overload without F90 parameter (defaults to 1.0) void GetPreIntegratedFGDGGXAndDisneyDiffuse(float NdotV, float perceptualRoughness, float3 fresnel0, out float3 specularFGD, out float diffuseFGD, out float reflectivity) { GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV, perceptualRoughness, fresnel0, 1.0, specularFGD, diffuseFGD, reflectivity); } // GGX + Lambert variant (for USE_DIFFUSE_LAMBERT_BRDF) void GetPreIntegratedFGDGGXAndLambert(float NdotV, float perceptualRoughness, float3 fresnel0, out float3 specularFGD, out float diffuseFGD, out float reflectivity) { GetPreIntegratedFGDGGXAndDisneyDiffuse(NdotV, perceptualRoughness, fresnel0, specularFGD, diffuseFGD, reflectivity); diffuseFGD = 1.0; } //----------------------------------------------------------------------------- // Pre-Integrated FGD Functions (Charlie + Fabric Lambert) //----------------------------------------------------------------------------- void GetPreIntegratedFGDCharlieAndFabricLambert(float NdotV, float perceptualRoughness, float3 fresnel0, out float3 specularFGD, out float diffuseFGD, out float reflectivity) { // Read the texture float3 preFGD = SAMPLE_TEXTURE2D_LOD(_PreIntegratedFGD_CharlieAndFabric, sampler_LinearClamp, float2(NdotV, perceptualRoughness), 0).xyz; specularFGD = lerp(preFGD.xxx, preFGD.yyy, fresnel0) * 2.0 * PI; // z = FabricLambert diffuseFGD = preFGD.z; reflectivity = preFGD.y; } #endif // BADDOG_PREINTEGRATED_FGD_INCLUDED