gpu-curtains
    Preparing search index...
    getPBRDirect: "\nfn BRDF_GGX(\n NdotV: f32,\n NdotL: f32,\n NdotH: f32,\n VdotH: f32,\n roughness: f32,\n specularF90: f32,\n specularColorBlended: vec3f,\n iridescenceFresnel: vec3f,\n iridescence: f32\n) -> vec3f {\n // cook-torrance brdf\n var F: vec3f = F_Schlick(specularColorBlended, specularF90, VdotH);\n F = mix(F, iridescenceFresnel, iridescence);\n\n let G: f32 = GeometrySmith(NdotL, NdotV, roughness);\n let D: f32 = DistributionGGX(NdotH, roughness);\n \n return G * D * F;\n}\n\nfn computeSpecularOcclusion(geometryNormal: vec3f, viewDirection: vec3f, occlusion: f32, roughness: f32) -> f32 {\n let NdotV: f32 = saturate(dot(geometryNormal, viewDirection));\n\treturn saturate(pow(NdotV + occlusion, exp2(- 16.0 * roughness - 1.0)) - 1.0 + occlusion);\n}\n\nfn BRDF_GGX_Singlescatter(\n normal: vec3f,\n viewDirection: vec3f,\n NdotL: f32,\n NdotV: f32,\n roughness: f32,\n specularF90: f32,\n specularColorBlended: vec3f,\n iridescenceFresnel: vec3f,\n iridescence: f32,\n directLight: DirectLight,\n) -> vec3f {\n let H: vec3f = normalize(viewDirection + directLight.direction);\n let NdotH: f32 = saturate(dot(normal, H));\n let VdotH: f32 = saturate(dot(viewDirection, H));\n\n return BRDF_GGX(NdotV, NdotL, NdotH, VdotH, roughness, specularF90, specularColorBlended, iridescenceFresnel, iridescence);\n}\n\n// GGX BRDF with multi-scattering energy compensation for direct lighting\n// Based on \"Practical Multiple Scattering Compensation for Microfacet Models\"\n// https://blog.selfshadow.com/publications/turquin/ms_comp_final.pdf\nfn BRDF_GGX_Multiscatter(\n dfgDirect: DFGDirect,\n specularF90: f32,\n specularColorBlended: vec3f,\n) -> vec3f {\n // Multi-scattering compensation\n let dfgV: vec2f = dfgDirect.dfgV;\n let dfgL: vec2f = dfgDirect.dfgL;\n\n\t// Single-scattering energy for view and light\n\tlet FssEss_V: vec3f = specularColorBlended * dfgV.x + specularF90 * dfgV.y;\n\tlet FssEss_L: vec3f = specularColorBlended * dfgL.x + specularF90 * dfgL.y;\n\n\tlet Ess_V: f32 = dfgV.x + dfgV.y;\n\tlet Ess_L: f32 = dfgL.x + dfgL.y;\n\n\t// Energy lost to multiple scattering\n\tlet Ems_V: f32 = 1.0 - Ess_V;\n\tlet Ems_L: f32 = 1.0 - Ess_L;\n\n\t// Average Fresnel reflectance\n\tlet Favg: vec3f = specularColorBlended + ( 1.0 - specularColorBlended ) * 0.047619; // 1/21\n\n\t// Multiple scattering contribution\n\tlet Fms: vec3f = FssEss_V * FssEss_L * Favg / ( 1.0 - Ems_V * Ems_L * Favg + EPSILON );\n\n\t// Energy compensation factor\n\tlet compensationFactor: f32 = Ems_V * Ems_L;\n\n\treturn Fms * compensationFactor;\n}\n\nfn getPBRDirect(\n normal: vec3f,\n viewDirection: vec3f,\n NdotL: f32,\n irradiance: vec3f,\n dfgDirect: DFGDirect,\n diffuseContribution: vec3f,\n specularF90: f32,\n specularColorBlended: vec3f,\n roughness: f32,\n iridescenceFresnel: vec3f,\n iridescence: f32,\n directLight: DirectLight\n) -> LightContribution {\n var lightContribution: LightContribution;\n\n let NdotV: f32 = saturate(dot(normal, viewDirection));\n\n let ggxSingleScatter: vec3f = BRDF_GGX_Singlescatter(\n normal,\n viewDirection,\n NdotL,\n NdotV,\n roughness,\n specularF90,\n specularColorBlended,\n iridescenceFresnel,\n iridescence,\n directLight\n );\n\n let ggxMultiScatter: vec3f = BRDF_GGX_Multiscatter(\n dfgDirect,\n specularF90,\n specularColorBlended,\n );\n\n let ggx: vec3f = ggxSingleScatter + ggxMultiScatter;\n \n lightContribution.diffuse += irradiance * BRDF_Lambert(diffuseContribution);\n lightContribution.specular += irradiance * ggx;\n\n return lightContribution;\n}\n" = ...

    Helper function chunk appended internally and used to compute PBR direct light contributions.