yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Yong HeSupport visibility control and default to `internal`. (#3380)11111e573

master
2.9 KiB107 linesraw
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}