yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
11111e573
master
1//TEST_IGNORE_FILE: 2implementing "bsdf-sample"; 3 4struct ShadingData 5{ 6 float3 V; 7 float3 N; 8 float3 T; 9 float3 B; 10 11 float3 fromLocal(float3 v) 12 { 13 return T * v.x + B * v.y + N * v.z; 14 } 15 16 float3 toLocal(float3 v) 17 { 18 return float3(dot(v, T), dot(v, B), dot(v, N)); 19 } 20}; 21 22struct Auto_Bwd_ScatterSample : IDifferentiable 23{ 24 float3 wo; 25 float pdf; 26 float3 weight; 27}; 28 29struct Auto_Bwd_BSDFParameters : IDifferentiable 30{ 31 float3 albedo; 32 float roughness; 33}; 34 35[BackwardDifferentiable] 36bool bsdfGGXSample(in ShadingData sd, in Auto_Bwd_BSDFParameters params, out Auto_Bwd_ScatterSample result) 37{ 38 float3 wiLocal = no_diff(sd.toLocal(sd.V)); 39 float2 u = float2(0.8, 0.3); 40 41 if (wiLocal.z < 1e-6) 42 { 43 unused(result); 44 return false; 45 } 46 47 // Taken from Rendering.Materials.Microfacet. Follows the Walter et al. EGSR07 BTDF paper 48 float alphaSqr = params.roughness * params.roughness; 49 float phi = u.y * (2 * 3.1415926); 50 float tanThetaSqr = alphaSqr * u.x / (1 - u.x); 51 float cosTheta = 1 / sqrt(1 + tanThetaSqr); 52 float r = sqrt(max(1 - cosTheta * cosTheta, 0)); 53 54 float3 hLocal = float3(cos(phi) * r, sin(phi) * r, cosTheta); // half-vector local space 55 float wiDotH = dot(wiLocal, hLocal); 56 float3 woLocal = 2 * hLocal * wiDotH - wiLocal; // outgoing vector local space 57 58 float pdf = bsdfGGXPDF(hLocal, params) / (4.f * wiDotH); 59 result.wo = no_diff(sd.fromLocal(woLocal)); // wo to world. 60 result.pdf = detach(pdf); 61 result.weight = evalGGXDivByPDF(wiLocal, woLocal, hLocal, params) * pdf / detach(pdf); 62 63 return woLocal.z > 1e-6; 64} 65 66[BackwardDifferentiable] 67float3 F(float3 f0, float3 f90, float cosTheta) 68{ 69 return f0 + (f90 - f0) * pow(max(1 - cosTheta, 0.f), 5.f); 70} 71 72[BackwardDifferentiable] 73float evalLambdaGGX(float alphaSqr, float cosTheta) 74{ 75 float cosThetaSqr = cosTheta * cosTheta; 76 float tanThetaSqr = max(1 - cosThetaSqr, 0) / cosThetaSqr; 77 return 0.5 * (-1 + sqrt(1 + alphaSqr * tanThetaSqr)); 78} 79 80[BackwardDifferentiable] 81float G(float alpha, float cosThetaI, float cosThetaO) 82{ 83 float alphaSqr = alpha * alpha; 84 float lambdaI = evalLambdaGGX(alphaSqr, cosThetaI); 85 float lambdaO = evalLambdaGGX(alphaSqr, cosThetaO); 86 return 1.0 / (1 + lambdaI + lambdaO); 87} 88 89[BackwardDifferentiable] 90float3 evalGGXDivByPDF(in float3 wi, in float3 wo, in float3 h, in Auto_Bwd_BSDFParameters params) 91{ 92 const float3 F0Color = params.albedo; 93 let F90Color = float3(1.0, 1.0, 1.0); 94 return F(F0Color, F90Color, dot(wi, h)) * G(params.roughness, wi.z, wo.z) * dot(wi, h) / (wi.z * h.z); 95} 96 97[BackwardDifferentiable] 98float bsdfGGXPDF(in float3 hLocal, in Auto_Bwd_BSDFParameters params) 99{ 100 float cosTheta = hLocal.z; 101 102 float alpha = params.roughness; 103 float a2 = alpha * alpha; 104 float d = ((cosTheta * a2 - cosTheta) * cosTheta + 1); 105 106 return (a2 / (d * d * 3.1415926)) * cosTheta; 107}