Skip to content

Commit 65a810f

Browse files
implement Beckmann Isotropic Transmissive
1 parent c2c8624 commit 65a810f

File tree

3 files changed

+53
-76
lines changed

3 files changed

+53
-76
lines changed

examples_tests/42.FragmentShaderPathTracer/common.glsl

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// basic settings
22
#define MAX_DEPTH 8
3-
#define SAMPLES 32
3+
#define SAMPLES 256
44

55
// firefly and variance reduction techniques
66
//#define KILL_DIFFUSE_SPECULAR_PATHS
@@ -203,7 +203,7 @@ BSDFNode bsdfs[BSDF_COUNT] = {
203203
{{uvec4(floatBitsToUint(vec3(1.02,1.02,1.3)),CONDUCTOR_OP),floatBitsToUint(vec4(1.0,1.0,2.0,0.0))}},
204204
{{uvec4(floatBitsToUint(vec3(1.02,1.3,1.02)),CONDUCTOR_OP),floatBitsToUint(vec4(1.0,2.0,1.0,0.0))}},
205205
{{uvec4(floatBitsToUint(vec3(1.02,1.3,1.02)),CONDUCTOR_OP),floatBitsToUint(vec4(1.0,2.0,1.0,0.15))}},
206-
{{uvec4(floatBitsToUint(vec3(1.4,1.45,1.5)),DIELECTRIC_OP),floatBitsToUint(vec4(0.0,0.0,0.0,0.05))}}
206+
{{uvec4(floatBitsToUint(vec3(1.4,1.45,1.5)),DIELECTRIC_OP),floatBitsToUint(vec4(0.0,0.0,0.0,0.125))}}
207207
};
208208

209209

@@ -281,7 +281,7 @@ bool anyHitProgram(in ImmutableRay_t _immutable)
281281
}
282282

283283

284-
#define INTERSECTION_ERROR_BOUND_LOG2 (-13.0)
284+
#define INTERSECTION_ERROR_BOUND_LOG2 (-9.0)
285285
float getTolerance_common(in int depth)
286286
{
287287
float depthRcp = 1.0/float(depth);
@@ -332,7 +332,7 @@ void missProgram()
332332
#include <irr/builtin/glsl/bxdf/brdf/specular/ggx.glsl>
333333
#include <irr/builtin/glsl/bxdf/bsdf/diffuse/lambert.glsl>
334334
#include <irr/builtin/glsl/bxdf/bsdf/specular/dielectric.glsl>
335-
//#include <irr/builtin/glsl/bxdf/bsdf/specular/beckmann.glsl>
335+
#include <irr/builtin/glsl/bxdf/bsdf/specular/beckmann.glsl>
336336
irr_glsl_LightSample irr_glsl_bsdf_cos_generate(in irr_glsl_AnisotropicViewSurfaceInteraction interaction, in vec3 u, in BSDFNode bsdf, in float monochromeEta, out irr_glsl_AnisotropicMicrofacetCache _cache)
337337
{
338338
const float a = BSDFNode_getRoughness(bsdf);
@@ -353,8 +353,7 @@ irr_glsl_LightSample irr_glsl_bsdf_cos_generate(in irr_glsl_AnisotropicViewSurfa
353353
smpl = irr_glsl_ggx_cos_generate(interaction,u.xy,a,a,_cache);
354354
break;
355355
default:
356-
smpl = irr_glsl_smooth_dielectric_cos_generate(interaction,u,monochromeEta);
357-
//smpl = irr_glsl_beckmann_dielectric_cos_generate(interaction,u,a,a,monochromeEta,_cache);
356+
smpl = irr_glsl_beckmann_dielectric_cos_generate(interaction,u,a,a,monochromeEta,_cache);
358357
break;
359358
}
360359
return smpl;
@@ -399,8 +398,7 @@ vec3 irr_glsl_bsdf_cos_remainder_and_pdf(out float pdf, in irr_glsl_LightSample
399398
remainder = irr_glsl_ggx_cos_remainder_and_pdf_wo_clamps(pdf,irr_glsl_ggx_trowbridge_reitz(a2,_cache.isotropic.NdotH2),clampedNdotL,_sample.NdotL2,clampedNdotV,interaction.isotropic.NdotV_squared,reflectance,a2);
400399
break;
401400
default:
402-
remainder = vec3(irr_glsl_smooth_dielectric_cos_remainder_and_pdf(pdf,_sample,interaction.isotropic,monochromeEta));
403-
//remainder = vec3(irr_glsl_beckmann_dielectric_cos_remainder_and_pdf(pdf, _sample, interaction.isotropic, monochromeEta, a2));
401+
remainder = vec3(irr_glsl_beckmann_dielectric_cos_remainder_and_pdf(pdf, _sample, interaction.isotropic, _cache.isotropic, monochromeEta, a2));
404402
break;
405403
}
406404
}

include/irr/builtin/glsl/bxdf/bsdf/specular/beckmann.glsl

Lines changed: 36 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6,91 +6,79 @@
66
#include <irr/builtin/glsl/bxdf/brdf/specular/beckmann.glsl>
77
#include <irr/builtin/glsl/bxdf/bsdf/specular/common.glsl>
88

9-
irr_glsl_BxDFSample irr_glsl_beckmann_dielectric_cos_generate_wo_clamps(in vec3 localV, in bool backside, in vec3 upperHemisphereLocalV, in mat3 m, in vec3 u, in float ax, in float ay, in float rcpOrientedEta, in float orientedEta2, in float rcpOrientedEta2)
9+
irr_glsl_LightSample irr_glsl_beckmann_dielectric_cos_generate_wo_clamps(in vec3 localV, in bool backside, in vec3 upperHemisphereLocalV, in mat3 m, in vec3 u, in float ax, in float ay, in float rcpOrientedEta, in float orientedEta2, in float rcpOrientedEta2, out irr_glsl_AnisotropicMicrofacetCache _cache)
1010
{
1111
// thanks to this manouvre the H will always be in the upper hemisphere (NdotH>0.0)
1212
const vec3 H = irr_glsl_beckmann_cos_generate_wo_clamps(upperHemisphereLocalV,u.xy,ax,ay);
13-
14-
const float reflectance = 1.0;// irr_glsl_fresnel_dielectric_common(orientedEta2, upperHemisphereLocalV.z);
13+
14+
const float VdotH = dot(localV,H);
15+
const float reflectance = irr_glsl_fresnel_dielectric_common(orientedEta2,abs(VdotH));
1516

1617
float rcpChoiceProb;
1718
bool transmitted = irr_glsl_partitionRandVariable(reflectance, u.z, rcpChoiceProb);
1819

19-
const float VdotH = dot(localV,H);
20-
return irr_glsl_createBSDFSample(transmitted,H,localV,backside,VdotH,VdotH*VdotH,m,rcpOrientedEta,rcpOrientedEta2);
20+
vec3 localL;
21+
_cache = irr_glsl_calcAnisotropicMicrofacetCache(transmitted,localV,H,localL,rcpOrientedEta,rcpOrientedEta2);
22+
23+
return irr_glsl_createLightSampleTangentSpace(localV,localL,m);
2124
}
2225

23-
irr_glsl_BxDFSample irr_glsl_beckmann_dielectric_cos_generate(in irr_glsl_AnisotropicViewSurfaceInteraction interaction, in vec3 u, in float ax, in float ay, in float eta)
26+
irr_glsl_LightSample irr_glsl_beckmann_dielectric_cos_generate(in irr_glsl_AnisotropicViewSurfaceInteraction interaction, in vec3 u, in float ax, in float ay, in float eta, out irr_glsl_AnisotropicMicrofacetCache _cache)
2427
{
2528
const vec3 localV = irr_glsl_getTangentSpaceV(interaction);
26-
const float NdotV = localV.z;
2729

28-
float rcpOrientedEta, orientedEta2, rcpOrientedEta2;
29-
const bool backside = irr_glsl_getOrientedEtas(rcpOrientedEta, orientedEta2, rcpOrientedEta2, NdotV, eta);
30+
float orientedEta, rcpOrientedEta;
31+
const bool backside = irr_glsl_getOrientedEtas(orientedEta, rcpOrientedEta, interaction.isotropic.NdotV, eta);
3032

3133
const vec3 upperHemisphereV = backside ? (-localV):localV;
3234

3335
const mat3 m = irr_glsl_getTangentFrame(interaction);
34-
return irr_glsl_beckmann_dielectric_cos_generate_wo_clamps(localV,backside,upperHemisphereV,m,u,ax,ay, rcpOrientedEta,orientedEta2,rcpOrientedEta2);
36+
return irr_glsl_beckmann_dielectric_cos_generate_wo_clamps(localV,backside,upperHemisphereV,m, u,ax,ay, rcpOrientedEta,orientedEta*orientedEta,rcpOrientedEta*rcpOrientedEta,_cache);
3537
}
3638

3739

3840

3941
// isotropic PDF
40-
float irr_glsl_beckmann_dielectric_pdf_wo_clamps(in bool transmitted, in float reflectance, in float ndf, in float absNdotV, in float NdotV2, in float a2, out float onePlusLambda_V)
41-
{
42-
return irr_glsl_VNDF_fresnel_sampled_BRDF_pdf_to_BSDF_pdf(transmitted,reflectance,irr_glsl_beckmann_pdf_wo_clamps(ndf,absNdotV,NdotV2,a2,onePlusLambda_V));
43-
}
44-
45-
float irr_glsl_beckmann_dielectric_pdf_wo_clamps(in bool transmitted, in float reflectance, in float NdotH2, in float absNdotV, in float NdotV2, in float a2)
42+
float irr_glsl_beckmann_dielectric_pdf_wo_clamps(in bool transmitted, in float reflectance, in float ndf, in float absNdotV, in float NdotV2, in float VdotH, in float LdotH, in float VdotHLdotH, in float a2, in float orientedEta, out float onePlusLambda_V)
4643
{
47-
return irr_glsl_VNDF_fresnel_sampled_BRDF_pdf_to_BSDF_pdf(transmitted,reflectance,irr_glsl_beckmann_pdf_wo_clamps(NdotH2,absNdotV,NdotV2,a2));
44+
const float lambda = irr_glsl_smith_beckmann_Lambda(NdotV2, a2);
45+
return irr_glsl_smith_VNDF_pdf_wo_clamps(ndf,lambda,absNdotV,transmitted,VdotH,LdotH,VdotHLdotH,orientedEta,reflectance,onePlusLambda_V);
4846
}
4947

5048
// anisotropic PDF
51-
float irr_glsl_beckmann_dielectric_pdf_wo_clamps(in bool transmitted, in float reflectance, in float ndf, in float absNdotV, in float TdotV2, in float BdotV2, in float NdotV2, in float ax2, in float ay2, out float onePlusLambda_V)
52-
{
53-
return irr_glsl_VNDF_fresnel_sampled_BRDF_pdf_to_BSDF_pdf(transmitted,reflectance,irr_glsl_beckmann_pdf_wo_clamps(ndf,absNdotV,TdotV2,BdotV2,NdotV2,ax2,ay2,onePlusLambda_V));
54-
}
55-
56-
float irr_glsl_beckmann_dielectric_pdf_wo_clamps(in bool transmitted, in float reflectance, in float NdotH2, in float TdotH2, in float BdotH2, in float absNdotV, in float TdotV2, in float BdotV2, in float NdotV2, in float ax, in float ax2, in float ay, in float ay2)
49+
float irr_glsl_beckmann_dielectric_pdf_wo_clamps(in bool transmitted, in float reflectance, in float ndf, in float absNdotV, in float TdotV2, in float BdotV2, in float NdotV2, in float VdotH, in float LdotH, in float VdotHLdotH, in float ax2, in float ay2, in float orientedEta, out float onePlusLambda_V)
5750
{
58-
return irr_glsl_VNDF_fresnel_sampled_BRDF_pdf_to_BSDF_pdf(transmitted,reflectance,irr_glsl_beckmann_pdf_wo_clamps(NdotH2,TdotH2,BdotH2,absNdotV,TdotV2,BdotV2,NdotV2,ax,ax2,ay,ay2));
51+
float c2 = irr_glsl_smith_beckmann_C2(TdotV2, BdotV2, NdotV2, ax2, ay2);
52+
float lambda = irr_glsl_smith_beckmann_Lambda(c2);
53+
return irr_glsl_smith_VNDF_pdf_wo_clamps(ndf,lambda,absNdotV,transmitted,VdotH,LdotH,VdotHLdotH,orientedEta,reflectance,onePlusLambda_V);
5954
}
6055

6156

6257

63-
float irr_glsl_beckmann_dielectric_cos_remainder_and_pdf_wo_clamps(out float pdf, in float ndf, in bool transmitted, in float absNdotL, in float NdotL2, in float absNdotV, in float NdotV2, in float reflectance, in float transmission_relative_to_reflection_differential_factor, in float a2)
58+
float irr_glsl_beckmann_dielectric_cos_remainder_and_pdf_wo_clamps(out float pdf, in float ndf, in bool transmitted, in float NdotL2, in float absNdotV, in float NdotV2, in float VdotH, in float LdotH, in float VdotHLdotH, in float reflectance, in float orientedEta, in float a2)
6459
{
6560
float onePlusLambda_V;
66-
pdf = irr_glsl_beckmann_dielectric_pdf_wo_clamps(transmitted, 1.0, ndf, absNdotV, NdotV2, a2, onePlusLambda_V);
61+
pdf = irr_glsl_beckmann_dielectric_pdf_wo_clamps(transmitted, reflectance, ndf, absNdotV, NdotV2, VdotH, LdotH, VdotHLdotH, a2, orientedEta, onePlusLambda_V);
6762

68-
const float G2_over_G1 = irr_glsl_beckmann_smith_G2_over_G1(onePlusLambda_V, absNdotL, NdotL2, a2);
69-
return G2_over_G1;
70-
//return irr_glsl_VNDF_fresnel_sampled_BSDF_cos_remainder(transmitted,G2_over_G1,transmission_relative_to_reflection_differential_factor);
63+
return irr_glsl_beckmann_smith_G2_over_G1(onePlusLambda_V, NdotL2, a2);
7164
}
72-
float irr_glsl_beckmann_dielectric_cos_remainder_and_pdf(out float pdf, in irr_glsl_BxDFSample s, in irr_glsl_IsotropicViewSurfaceInteraction interaction, in float eta, in float a2)
73-
{
74-
const float NdotH2 = s.NdotH * s.NdotH;
75-
const float ndf = irr_glsl_beckmann(a2, NdotH2);
76-
77-
const float NdotL2 = s.NdotL * s.NdotL;
78-
79-
const float absNdotV = abs(interaction.NdotV);
80-
81-
float orientedEta, orientedEta2, rcpOrientedEta2;
82-
const bool backside = irr_glsl_getOrientedEtas(orientedEta, orientedEta2, rcpOrientedEta2, interaction.NdotV, eta);
83-
const float VdotH2 = s.VdotH * s.VdotH;
84-
const float LdotH = irr_glsl_refract_compute_NdotT(backside,VdotH2,rcpOrientedEta2);
8565

86-
const float VdotHLdotH = s.VdotH*LdotH;
87-
const bool transmitted = isnan(LdotH);//VdotHLdotH < 0.0;
88-
89-
const float reflectance = irr_glsl_fresnel_dielectric_common(orientedEta2,s.VdotH);
66+
float irr_glsl_beckmann_dielectric_cos_remainder_and_pdf(out float pdf, in irr_glsl_LightSample _sample, in irr_glsl_IsotropicViewSurfaceInteraction interaction, in irr_glsl_IsotropicMicrofacetCache _cache, in float eta, in float a2)
67+
{
68+
const float ndf = irr_glsl_beckmann(a2,_cache.NdotH2);
69+
70+
float orientedEta, rcpOrientedEta;
71+
const bool backside = irr_glsl_getOrientedEtas(orientedEta, rcpOrientedEta, _cache.VdotH, eta);
72+
const float orientedEta2 = orientedEta*orientedEta;
73+
const float rcpOrientedEta2 = rcpOrientedEta*rcpOrientedEta;
9074

91-
const float factor = 1.0;// irr_glsl_microfacet_transmission_relative_to_reflection_differential_factor(s.VdotH, LdotH, VdotHLdotH, 1.0 / orientedEta);
75+
const float VdotHLdotH = _cache.VdotH*_cache.LdotH;
76+
const bool transmitted = VdotHLdotH<0.0;
77+
78+
const float reflectance = irr_glsl_fresnel_dielectric_common(orientedEta2,abs(_cache.VdotH));
9279

93-
return irr_glsl_beckmann_dielectric_cos_remainder_and_pdf_wo_clamps(pdf, ndf, transmitted, abs(s.NdotL), NdotL2, absNdotV, interaction.NdotV_squared, reflectance, factor, a2);
80+
const float absNdotV = abs(interaction.NdotV);
81+
return irr_glsl_beckmann_dielectric_cos_remainder_and_pdf_wo_clamps(pdf, ndf, transmitted, _sample.NdotL2, absNdotV, interaction.NdotV_squared, _cache.VdotH, _cache.LdotH, VdotHLdotH, reflectance, orientedEta, a2);
9482
}
9583

9684
#if 0

include/irr/builtin/glsl/bxdf/bsdf/specular/common.glsl

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,19 @@
66
#include <irr/builtin/glsl/bxdf/common_samples.glsl>
77
#include <irr/builtin/glsl/bxdf/fresnel.glsl>
88

9-
// assert(VdotHLdotH<0.0)
10-
float irr_glsl_microfacet_transmission_relative_to_reflection_differential_factor(in float VdotH, in float LdotH, in float VdotHLdotH, in float orientedEta)
11-
{
12-
const float den_sqrt = VdotH+orientedEta*LdotH;
13-
return -4.0*VdotHLdotH/(den_sqrt*den_sqrt);
14-
}
15-
16-
float irr_glsl_microfacet_transmission_relative_to_reflection_differential_factor(in float VdotH, in float LdotH, in float orientedEta)
17-
{
18-
return irr_glsl_microfacet_transmission_relative_to_reflection_differential_factor(VdotH,LdotH,VdotH*LdotH,orientedEta);
19-
}
20-
21-
22-
// assuming VNDF sampling followed by transmission selection according to the fresnel has been used we can compute the remainder for every subsurface model
23-
float irr_glsl_VNDF_fresnel_sampled_BSDF_cos_remainder(in bool transmitted, in float G2_over_G1, in float transmission_relative_to_reflection_differential_factor)
24-
{
25-
return G2_over_G1*(transmitted ? transmission_relative_to_reflection_differential_factor:1.0);
26-
}
279

28-
float irr_glsl_VNDF_fresnel_sampled_BRDF_pdf_to_BSDF_pdf(in bool transmitted, in float reflectance, in float vndf_sampling_pdf)
10+
float irr_glsl_smith_VNDF_pdf_wo_clamps(in float ndf, in float lambda_V, in float absNdotV, in bool transmitted, in float VdotH, in float LdotH, in float VdotHLdotH, in float orientedEta, in float reflectance, out float onePlusLambda_V)
2911
{
30-
return (transmitted ? (1.0-reflectance):reflectance)*vndf_sampling_pdf;
12+
onePlusLambda_V = 1.0+lambda_V;
13+
14+
float denominator = absNdotV*onePlusLambda_V;
15+
if (transmitted)
16+
{
17+
const float VdotH_etaLdotH = (VdotH+orientedEta*LdotH);
18+
denominator *= VdotH_etaLdotH*VdotH_etaLdotH;
19+
}
20+
// VdotHLdotH is negative under transmission, so thats why fresnel transmission has a negative form
21+
return ndf*(transmitted ? VdotHLdotH:0.25)*(transmitted ? (reflectance-1.0):reflectance)/denominator;
3122
}
3223

3324
#endif

0 commit comments

Comments
 (0)