Variable getImportanceSamplesConst
getImportanceSamples: "\n// microfacet distribution (GGX and Charlie)\nstruct MicrofacetDistributionSample {\n pdf: f32,\n cosTheta: f32,\n sinTheta: f32,\n phi: f32\n}\n\n// https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.html\n// This implementation is based on https://bruop.github.io/ibl/,\n// https://www.tobias-franke.eu/log/2014/03/30/notes_on_importance_sampling.html\n// and https://developer.nvidia.com/gpugems/GPUGems3/gpugems3_ch20.html\nfn GGX(xi: vec2f, roughness: f32) -> MicrofacetDistributionSample {\n var ggx: MicrofacetDistributionSample;\n\n // evaluate sampling equations\n let alpha: f32 = max(roughness * roughness, EPSILON);\n ggx.cosTheta = sqrt((1.0 - xi.y) / (1.0 + (alpha * alpha - 1.0) * xi.y));\n ggx.sinTheta = sqrt(1.0 - ggx.cosTheta * ggx.cosTheta);\n ggx.phi = 2.0 * PI * xi.x;\n\n // evaluate GGX pdf (for half vector)\n ggx.pdf = DistributionGGX(ggx.cosTheta, roughness);\n\n // Apply the Jacobian to obtain a pdf that is parameterized by l\n // see https://bruop.github.io/ibl/\n // Typically you'd have the following:\n // float pdf = DistributionGGX(NoH, roughness) * NoH / (4.0 * VoH);\n // but since V = N => VoH == NoH\n ggx.pdf /= 4.0;\n\n return ggx;\n}\n\nfn Charlie(xi: vec2f, roughness: f32) -> MicrofacetDistributionSample {\n var charlie: MicrofacetDistributionSample;\n\n let alpha = max(roughness * roughness, EPSILON);\n charlie.sinTheta = pow(xi.y, alpha / (2.0 * alpha + 1.0));\n charlie.cosTheta = sqrt(1.0 - charlie.sinTheta * charlie.sinTheta);\n charlie.phi = 2.0 * PI * xi.x;\n\n // evaluate Charlie pdf (for half vector)\n charlie.pdf = D_Charlie(roughness, charlie.cosTheta);\n\n // Apply the Jacobian to obtain a pdf that is parameterized by l\n charlie.pdf /= 4.0;\n\n return charlie;\n}\n\n// getImportanceSampleGGX returns an importance sample direction with pdf in the .w component\nfn getImportanceSampleGGX(Xi: vec2f, N: vec3f, roughness: f32) -> vec4f {\n var importanceSample: MicrofacetDistributionSample;\n \n importanceSample = GGX(Xi, roughness);\n \n // transform the hemisphere sample to the normal coordinate frame\n // i.e. rotate the hemisphere to the normal direction\n let H: vec3f = normalize(vec3(\n importanceSample.sinTheta * cos(importanceSample.phi), \n importanceSample.sinTheta * sin(importanceSample.phi), \n importanceSample.cosTheta\n ));\n\n return vec4(H, importanceSample.pdf);\n}\n\nfn getImportanceSampleCharlie(Xi: vec2f, N: vec3f, roughness: f32) -> vec4f {\n var importanceSample: MicrofacetDistributionSample;\n\n importanceSample = Charlie(Xi, roughness);\n\n // transform the hemisphere sample to the normal coordinate frame\n // i.e. rotate the hemisphere to the normal direction\n let H: vec3f = normalize(vec3(\n importanceSample.sinTheta * cos(importanceSample.phi), \n importanceSample.sinTheta * sin(importanceSample.phi), \n importanceSample.cosTheta\n ));\n\n return vec4(H, importanceSample.pdf);\n}\n" = ...
Importance sample helper functions for GGX and Charlie sheen. Must be used with the
common,constants,BRDF_GGXandBRDFCharliechunks.