Skip to content

Commit 957c3c4

Browse files
Merge pull request #966 from Devsh-Graphics-Programming/hlsl_path_tracer_example_no_quat
Final BxDF changes, drafts of Spherical Shape Sampling, RWMC and PAth Tracing
2 parents 5b634dd + dfcae2d commit 957c3c4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+2047
-272
lines changed

include/nbl/builtin/glsl/utils/morton.glsl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,18 @@ uint nbl_glsl_morton_decode2d8bComponent(in uint x)
2222
return x;
2323
}
2424

25+
uint nbl_glsl_morton_decode2d32bComponent(in uint x)
26+
{
27+
x &= 0x55555555u;
28+
x = (x ^ (x >> 1u)) & 0x33333333u;
29+
x = (x ^ (x >> 2u)) & 0x0f0f0f0fu;
30+
x = (x ^ (x >> 4u)) & 0x00ff00ffu;
31+
x = (x ^ (x >> 8u)) & 0x0000ffffu;
32+
x = (x ^ (x >> 16u));
33+
return x;
34+
}
35+
36+
2537
uvec2 nbl_glsl_morton_decode2d4b(in uint x)
2638
{
2739
return uvec2(nbl_glsl_morton_decode2d4bComponent(x), nbl_glsl_morton_decode2d4bComponent(x >> 1u));
@@ -32,4 +44,9 @@ uvec2 nbl_glsl_morton_decode2d8b(in uint x)
3244
return uvec2(nbl_glsl_morton_decode2d8bComponent(x), nbl_glsl_morton_decode2d8bComponent(x >> 1u));
3345
}
3446

47+
uvec2 nbl_glsl_morton_decode2d32b(in uint x)
48+
{
49+
return uvec2(nbl_glsl_morton_decode2d32bComponent(x), nbl_glsl_morton_decode2d32bComponent(x >> 1u));
50+
}
51+
3552
#endif

include/nbl/builtin/hlsl/bxdf/base/cook_torrance_base.hlsl

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "nbl/builtin/hlsl/bxdf/config.hlsl"
99
#include "nbl/builtin/hlsl/bxdf/ndf.hlsl"
1010
#include "nbl/builtin/hlsl/bxdf/fresnel.hlsl"
11+
#include "nbl/builtin/hlsl/sampling/basic.hlsl"
1112
#include "nbl/builtin/hlsl/bxdf/ndf/microfacet_to_light_transform.hlsl"
1213

1314
namespace nbl
@@ -130,19 +131,22 @@ struct SCookTorrance
130131

131132
template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>,
132133
typename C=bool_constant<!fresnel_type::ReturnsMonochrome> NBL_FUNC_REQUIRES(C::value && !fresnel_type::ReturnsMonochrome)
133-
static scalar_type __getScaledReflectance(NBL_CONST_REF_ARG(fresnel_type) orientedFresnel, NBL_CONST_REF_ARG(Interaction) interaction, scalar_type clampedVdotH)
134+
static scalar_type __getScaledReflectance(NBL_CONST_REF_ARG(fresnel_type) orientedFresnel, NBL_CONST_REF_ARG(Interaction) interaction, scalar_type clampedVdotH, bool transmitted, NBL_REF_ARG(spectral_type) outFresnelVal)
134135
{
135136
spectral_type throughputWeights = interaction.getLuminosityContributionHint();
136-
return hlsl::dot<spectral_type>(impl::__implicit_promote<spectral_type, typename fresnel_type::vector_type>::__call(orientedFresnel(clampedVdotH)), throughputWeights);
137+
spectral_type reflectance = orientedFresnel(clampedVdotH);
138+
outFresnelVal = hlsl::mix(reflectance, hlsl::promote<spectral_type>(1.0)-reflectance, transmitted);
139+
return hlsl::dot<spectral_type>(outFresnelVal, throughputWeights);
137140
}
138141
template<class Interaction=conditional_t<IsAnisotropic,anisotropic_interaction_type,isotropic_interaction_type>,
139142
typename C=bool_constant<fresnel_type::ReturnsMonochrome> NBL_FUNC_REQUIRES(C::value && fresnel_type::ReturnsMonochrome)
140-
static scalar_type __getScaledReflectance(NBL_CONST_REF_ARG(fresnel_type) orientedFresnel, NBL_CONST_REF_ARG(Interaction) interaction, scalar_type clampedVdotH)
143+
static scalar_type __getScaledReflectance(NBL_CONST_REF_ARG(fresnel_type) orientedFresnel, NBL_CONST_REF_ARG(Interaction) interaction, scalar_type clampedVdotH, bool transmitted, NBL_REF_ARG(spectral_type) outFresnelVal)
141144
{
142-
return orientedFresnel(clampedVdotH)[0];
145+
scalar_type reflectance = orientedFresnel(clampedVdotH)[0];
146+
return hlsl::mix(reflectance, scalar_type(1.0)-reflectance, transmitted);
143147
}
144148

145-
bool __dotIsUnity(const vector3_type a, const vector3_type b, const scalar_type value)
149+
bool __dotIsValue(const vector3_type a, const vector3_type b, const scalar_type value)
146150
{
147151
const scalar_type ab = hlsl::dot(a, b);
148152
return hlsl::max(ab, value / ab) <= scalar_type(value + 1e-3);
@@ -209,11 +213,11 @@ struct SCookTorrance
209213
ray_dir_info_type V = interaction.getV();
210214
const matrix3x3_type fromTangent = interaction.getFromTangentSpace();
211215
// tangent frame orthonormality
212-
assert(__dotIsUnity(fromTangent[0],fromTangent[1],0.0));
213-
assert(__dotIsUnity(fromTangent[1],fromTangent[2],0.0));
214-
assert(__dotIsUnity(fromTangent[2],fromTangent[0],0.0));
216+
assert(__dotIsValue(fromTangent[0],fromTangent[1],0.0));
217+
assert(__dotIsValue(fromTangent[1],fromTangent[2],0.0));
218+
assert(__dotIsValue(fromTangent[2],fromTangent[0],0.0));
215219
// NDF sampling produced a unit length direction
216-
assert(__dotIsUnity(localH,localH,1.0));
220+
assert(__dotIsValue(localH,localH,1.0));
217221
const vector3_type H = hlsl::mul(interaction.getFromTangentSpace(), localH);
218222
Refract<scalar_type> r = Refract<scalar_type>::create(V.getDirection(), H);
219223

@@ -276,7 +280,7 @@ struct SCookTorrance
276280
const scalar_type NdotV = localV.z;
277281

278282
fresnel_type _f = __getOrientedFresnel(fresnel, NdotV);
279-
fresnel::OrientedEtaRcps<monochrome_type> rcpEta = _f.getOrientedEtaRcps();
283+
fresnel::OrientedEtaRcps<monochrome_type> rcpEta = _f.getRefractionOrientedEtaRcps();
280284

281285
const vector3_type upperHemisphereV = ieee754::flipSignIfRHSNegative<vector3_type>(localV, hlsl::promote<vector3_type>(NdotV));
282286
const vector3_type localH = ndf.generateH(upperHemisphereV, u.xy);
@@ -294,11 +298,14 @@ struct SCookTorrance
294298
assert(NdotV*VdotH >= scalar_type(0.0));
295299
}
296300

297-
const scalar_type reflectance = __getScaledReflectance(_f, interaction, hlsl::abs(VdotH));
301+
spectral_type dummy;
302+
const scalar_type reflectance = __getScaledReflectance(_f, interaction, hlsl::abs(VdotH), false, dummy);
298303

299304
scalar_type rcpChoiceProb;
300305
scalar_type z = u.z;
301-
bool transmitted = math::partitionRandVariable(reflectance, z, rcpChoiceProb);
306+
sampling::PartitionRandVariable<scalar_type> partitionRandVariable;
307+
partitionRandVariable.leftProb = reflectance;
308+
bool transmitted = partitionRandVariable(z, rcpChoiceProb);
302309

303310
const scalar_type LdotH = hlsl::mix(VdotH, ieee754::copySign(hlsl::sqrt(rcpEta.value2[0]*VdotH*VdotH + scalar_type(1.0) - rcpEta.value2[0]), -VdotH), transmitted);
304311
bool valid;
@@ -337,8 +344,9 @@ struct SCookTorrance
337344

338345
NBL_IF_CONSTEXPR(IsBSDF)
339346
{
340-
const scalar_type reflectance = __getScaledReflectance(_f, interaction, hlsl::abs(cache.getVdotH()));
341-
return hlsl::mix(reflectance, scalar_type(1.0) - reflectance, cache.isTransmission()) * DG1.projectedLightMeasure;
347+
spectral_type dummy;
348+
const scalar_type reflectance = __getScaledReflectance(_f, interaction, hlsl::abs(cache.getVdotH()), cache.isTransmission(), dummy);
349+
return reflectance * DG1.projectedLightMeasure;
342350
}
343351
else
344352
{
@@ -389,10 +397,9 @@ struct SCookTorrance
389397
quo = hlsl::promote<spectral_type>(G2_over_G1);
390398
else
391399
{
392-
const scalar_type scaled_reflectance = __getScaledReflectance(_f, interaction, hlsl::abs(cache.getVdotH()));
393-
spectral_type reflectance = impl::__implicit_promote<spectral_type, typename fresnel_type::vector_type>::__call(_f(hlsl::abs(cache.getVdotH())));
394-
quo = hlsl::mix(reflectance / scaled_reflectance,
395-
(hlsl::promote<spectral_type>(1.0) - reflectance) / (scalar_type(1.0) - scaled_reflectance), cache.isTransmission()) * G2_over_G1;
400+
spectral_type reflectance;
401+
const scalar_type scaled_reflectance = __getScaledReflectance(_f, interaction, hlsl::abs(cache.getVdotH()), cache.isTransmission(), reflectance);
402+
quo = reflectance / scaled_reflectance * G2_over_G1;
396403
}
397404
}
398405
else
@@ -409,6 +416,18 @@ struct SCookTorrance
409416
fresnel_type fresnel; // always front-facing
410417
};
411418

419+
420+
template<class Config, class N, class F>
421+
struct traits<SCookTorrance<Config,N,F> >
422+
{
423+
using __type = SCookTorrance<Config,N,F>;
424+
425+
NBL_CONSTEXPR_STATIC_INLINE BxDFType type = conditional_value<__type::IsBSDF, BxDFType, BxDFType::BT_BSDF, BxDFType::BT_BRDF>::value;
426+
NBL_CONSTEXPR_STATIC_INLINE bool IsMicrofacet = true;
427+
NBL_CONSTEXPR_STATIC_INLINE bool clampNdotV = !__type::IsBSDF;
428+
NBL_CONSTEXPR_STATIC_INLINE bool clampNdotL = !__type::IsBSDF;
429+
};
430+
412431
}
413432
}
414433
}

include/nbl/builtin/hlsl/bxdf/common.hlsl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ struct SIsotropicMicrofacetCache
615615

616616
// not coming from the medium (reflected) OR
617617
// exiting at the macro scale AND ( (not L outside the cone of possible directions given IoR with constraint VdotH*LdotH<0.0) OR (microfacet not facing toward the macrosurface, i.e. non heightfield profile of microsurface) )
618-
const bool valid = ComputeMicrofacetNormal<scalar_type>::isValidMicrofacet(transmitted, VdotL, retval.absNdotH, computeMicrofacetNormal.orientedEta);
618+
const bool valid = ComputeMicrofacetNormal<scalar_type>::isValidMicrofacet(transmitted, VdotL, retval.absNdotH, fresnel::OrientedEtas<monochrome_type>::create(1.0, computeMicrofacetNormal.orientedEta));
619619
if (valid)
620620
{
621621
retval.VdotH = hlsl::dot<vector3_type>(computeMicrofacetNormal.V,H);
@@ -638,7 +638,7 @@ struct SIsotropicMicrofacetCache
638638
const bool transmitted = ComputeMicrofacetNormal<scalar_type>::isTransmissionPath(NdotV,NdotL);
639639

640640
ComputeMicrofacetNormal<scalar_type> computeMicrofacetNormal = ComputeMicrofacetNormal<scalar_type>::create(V,L,N,1.0);
641-
computeMicrofacetNormal.orientedEta = orientedEtas;
641+
computeMicrofacetNormal.orientedEta = orientedEtas.value[0];
642642

643643
return create(transmitted, computeMicrofacetNormal, VdotL, N, H);
644644
}
@@ -664,7 +664,7 @@ struct SIsotropicMicrofacetCache
664664
const bool transmitted = ComputeMicrofacetNormal<scalar_type>::isTransmissionPath(interaction.getNdotV(),_sample.getNdotL());
665665

666666
ComputeMicrofacetNormal<scalar_type> computeMicrofacetNormal = ComputeMicrofacetNormal<scalar_type>::create(V,L,N,1.0);
667-
computeMicrofacetNormal.orientedEta = orientedEtas;
667+
computeMicrofacetNormal.orientedEta = orientedEtas.value[0];
668668

669669
return create(transmitted, computeMicrofacetNormal, hlsl::dot<vector3_type>(V, L), N, H);
670670
}

0 commit comments

Comments
 (0)