@@ -135,6 +135,35 @@ struct MxDielectricParams : public MxMicrofacetBaseParams {
135
135
{
136
136
return transmission_tint * (1 .0f - fresnel_dielectric (cos_theta, ior));
137
137
}
138
+
139
+ OSL_HOSTDEVICE Color3 dirAlbedoR (float cos_theta) const
140
+ {
141
+ float iorRatio = (ior - 1 .0f ) / (ior + 1 .0f );
142
+ Color3 f0 (iorRatio * iorRatio);
143
+ Color3 f90 (1 .0f );
144
+
145
+ // Rational quadratic fit for GGX directional albedo
146
+ // https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl
147
+ float x = OIIO::clamp (cos_theta, 0 .0f , 1 .0f );
148
+ float y = sqrtf (roughness_x * roughness_y); // average alpha
149
+ float x2 = x * x;
150
+ float y2 = y * y;
151
+ Vec2 num = Vec2 (0 .1003f , 0 .9345f ) + Vec2 (-0 .6303f , -2 .323f ) * x
152
+ + Vec2 (9 .748f , 2 .229f ) * y + Vec2 (-2 .038f , -3 .748f ) * x * y
153
+ + Vec2 (29 .34f , 1 .424f ) * x2 + Vec2 (-8 .245f , -0 .7684f ) * y2
154
+ + Vec2 (-26 .44f , 1 .436f ) * x2 * y
155
+ + Vec2 (19 .99f , 0 .2913f ) * x * y2
156
+ + Vec2 (-5 .448f , 0 .6286f ) * x2 * y2;
157
+ Vec2 den = Vec2 (1 .0f , 1 .0f ) + Vec2 (-1 .765f , 0 .2281f ) * x
158
+ + Vec2 (8 .263f , 15 .94f ) * y + Vec2 (11 .53f , -55 .83f ) * x * y
159
+ + Vec2 (28 .96f , 13 .08f ) * x2 + Vec2 (-7 .507f , 41 .26f ) * y2
160
+ + Vec2 (-36 .11f , 54 .9f ) * x2 * y
161
+ + Vec2 (15 .86f , 300 .2f ) * x * y2
162
+ + Vec2 (33 .37f , -285 .1f ) * x2 * y2;
163
+ float a = OIIO::clamp (num.x / den.x , 0 .0f , 1 .0f );
164
+ float b = OIIO::clamp (num.y / den.y , 0 .0f , 1 .0f );
165
+ return reflection_tint * (f0 * a + f90 * b);
166
+ }
138
167
};
139
168
140
169
struct MxConductorParams : public MxMicrofacetBaseParams {
@@ -151,6 +180,13 @@ struct MxConductorParams : public MxMicrofacetBaseParams {
151
180
152
181
OSL_HOSTDEVICE Color3 evalT (float cos_theta) const { return Color3 (0 .0f ); }
153
182
183
+ OSL_HOSTDEVICE Color3 dirAlbedoR (float cos_theta) const
184
+ {
185
+ // TODO: Integrate the MaterialX fit for GGX directional albedo, which
186
+ // may improve multiscatter compensation for conductors.
187
+ return evalR (cos_theta);
188
+ }
189
+
154
190
// Avoid function was declared but never referenced
155
191
// float get_ior() const
156
192
// {
@@ -180,6 +216,31 @@ struct MxGeneralizedSchlickParams : public MxMicrofacetBaseParams {
180
216
* (Color3 (1 .0f )
181
217
- fresnel_generalized_schlick (cos_theta, f0, f90, exponent));
182
218
}
219
+
220
+ OSL_HOSTDEVICE Color3 dirAlbedoR (float cos_theta) const
221
+ {
222
+ // Rational quadratic fit for GGX directional albedo
223
+ // https://github.com/AcademySoftwareFoundation/MaterialX/blob/main/libraries/pbrlib/genglsl/lib/mx_microfacet_specular.glsl
224
+ float x = OIIO::clamp (cos_theta, 0 .0f , 1 .0f );
225
+ float y = sqrtf (roughness_x * roughness_y); // average alpha
226
+ float x2 = x * x;
227
+ float y2 = y * y;
228
+ Vec2 num = Vec2 (0 .1003f , 0 .9345f ) + Vec2 (-0 .6303f , -2 .323f ) * x
229
+ + Vec2 (9 .748f , 2 .229f ) * y + Vec2 (-2 .038f , -3 .748f ) * x * y
230
+ + Vec2 (29 .34f , 1 .424f ) * x2 + Vec2 (-8 .245f , -0 .7684f ) * y2
231
+ + Vec2 (-26 .44f , 1 .436f ) * x2 * y
232
+ + Vec2 (19 .99f , 0 .2913f ) * x * y2
233
+ + Vec2 (-5 .448f , 0 .6286f ) * x2 * y2;
234
+ Vec2 den = Vec2 (1 .0f , 1 .0f ) + Vec2 (-1 .765f , 0 .2281f ) * x
235
+ + Vec2 (8 .263f , 15 .94f ) * y + Vec2 (11 .53f , -55 .83f ) * x * y
236
+ + Vec2 (28 .96f , 13 .08f ) * x2 + Vec2 (-7 .507f , 41 .26f ) * y2
237
+ + Vec2 (-36 .11f , 54 .9f ) * x2 * y
238
+ + Vec2 (15 .86f , 300 .2f ) * x * y2
239
+ + Vec2 (33 .37f , -285 .1f ) * x2 * y2;
240
+ float a = OIIO::clamp (num.x / den.x , 0 .0f , 1 .0f );
241
+ float b = OIIO::clamp (num.y / den.y , 0 .0f , 1 .0f );
242
+ return reflection_tint * (f0 * a + f90 * b);
243
+ }
183
244
};
184
245
185
246
struct MxTranslucentParams {
0 commit comments