Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 16 additions & 16 deletions include/nbl/builtin/hlsl/sampling/basic.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,29 @@ namespace sampling
template<typename T NBL_PRIMARY_REQUIRES(concepts::FloatingPointLikeScalar<T>)
struct PartitionRandVariable
{
using floating_point_type = T;
using uint_type = unsigned_integer_of_size_t<sizeof(floating_point_type)>;
using floating_point_type = T;
using uint_type = unsigned_integer_of_size_t<sizeof(floating_point_type)>;

bool operator()(NBL_REF_ARG(floating_point_type) xi, NBL_REF_ARG(floating_point_type) rcpChoiceProb)
{
const floating_point_type NextULPAfterUnity = bit_cast<floating_point_type>(bit_cast<uint_type>(floating_point_type(1.0)) + uint_type(1u));
const bool pickRight = xi >= leftProb * NextULPAfterUnity;
bool operator()(NBL_REF_ARG(floating_point_type) xi, NBL_REF_ARG(floating_point_type) rcpChoiceProb)
{
const floating_point_type NextULPAfterUnity = bit_cast<floating_point_type>(bit_cast<uint_type>(floating_point_type(1.0)) + uint_type(1u));
const bool pickRight = xi >= leftProb * NextULPAfterUnity;

// This is all 100% correct taking into account the above NextULPAfterUnity
xi -= pickRight ? leftProb : floating_point_type(0.0);
// This is all 100% correct taking into account the above NextULPAfterUnity
xi -= pickRight ? leftProb : floating_point_type(0.0);

rcpChoiceProb = floating_point_type(1.0) / (pickRight ? (floating_point_type(1.0) - leftProb) : leftProb);
xi *= rcpChoiceProb;
rcpChoiceProb = floating_point_type(1.0) / (pickRight ? (floating_point_type(1.0) - leftProb) : leftProb);
xi *= rcpChoiceProb;

return pickRight;
}
return pickRight;
}

floating_point_type leftProb;
floating_point_type leftProb;
};


}
}
}
} // namespace sampling
} // namespace hlsl
} // namespace nbl

#endif
73 changes: 40 additions & 33 deletions include/nbl/builtin/hlsl/sampling/bilinear.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -19,47 +19,54 @@ namespace sampling
template<typename T>
struct Bilinear
{
using scalar_type = T;
using vector2_type = vector<T, 2>;
using vector3_type = vector<T, 3>;
using vector4_type = vector<T, 4>;
using scalar_type = T;
using vector2_type = vector<T, 2>;
using vector3_type = vector<T, 3>;
using vector4_type = vector<T, 4>;

static Bilinear<T> create(const vector4_type bilinearCoeffs)
{
Bilinear<T> retval;
retval.bilinearCoeffs = bilinearCoeffs;
retval.twiceAreasUnderXCurve = vector2_type(bilinearCoeffs[0] + bilinearCoeffs[1], bilinearCoeffs[2] + bilinearCoeffs[3]);
return retval;
}
// BijectiveSampler concept types
using domain_type = vector2_type;
using codomain_type = vector2_type;
using density_type = scalar_type;
using sample_type = codomain_and_rcpPdf<codomain_type, density_type>;
using inverse_sample_type = domain_and_rcpPdf<domain_type, density_type>;

vector2_type generate(NBL_REF_ARG(scalar_type) rcpPdf, const vector2_type _u)
{
vector2_type u;
Linear<scalar_type> lineary = Linear<scalar_type>::create(twiceAreasUnderXCurve);
u.y = lineary.generate(_u.y);
static Bilinear<T> create(const vector4_type bilinearCoeffs)
{
Bilinear<T> retval;
retval.bilinearCoeffs = bilinearCoeffs;
retval.twiceAreasUnderXCurve = vector2_type(bilinearCoeffs[0] + bilinearCoeffs[1], bilinearCoeffs[2] + bilinearCoeffs[3]);
return retval;
}

const vector2_type ySliceEndPoints = vector2_type(nbl::hlsl::mix(bilinearCoeffs[0], bilinearCoeffs[2], u.y), nbl::hlsl::mix(bilinearCoeffs[1], bilinearCoeffs[3], u.y));
Linear<scalar_type> linearx = Linear<scalar_type>::create(ySliceEndPoints);
u.x = linearx.generate(_u.x);
vector2_type generate(NBL_REF_ARG(scalar_type) rcpPdf, const vector2_type _u)
{
vector2_type u;
Linear<scalar_type> lineary = Linear<scalar_type>::create(twiceAreasUnderXCurve);
u.y = lineary.generate(_u.y);

rcpPdf = (twiceAreasUnderXCurve[0] + twiceAreasUnderXCurve[1]) / (4.0 * nbl::hlsl::mix(ySliceEndPoints[0], ySliceEndPoints[1], u.x));
const vector2_type ySliceEndPoints = vector2_type(nbl::hlsl::mix(bilinearCoeffs[0], bilinearCoeffs[2], u.y), nbl::hlsl::mix(bilinearCoeffs[1], bilinearCoeffs[3], u.y));
Linear<scalar_type> linearx = Linear<scalar_type>::create(ySliceEndPoints);
u.x = linearx.generate(_u.x);

return u;
}
rcpPdf = (twiceAreasUnderXCurve[0] + twiceAreasUnderXCurve[1]) / (4.0 * nbl::hlsl::mix(ySliceEndPoints[0], ySliceEndPoints[1], u.x));

scalar_type pdf(const vector2_type u)
{
return 4.0 * nbl::hlsl::mix(nbl::hlsl::mix(bilinearCoeffs[0], bilinearCoeffs[1], u.x), nbl::hlsl::mix(bilinearCoeffs[2], bilinearCoeffs[3], u.x), u.y) / (bilinearCoeffs[0] + bilinearCoeffs[1] + bilinearCoeffs[2] + bilinearCoeffs[3]);
}
return u;
}

// unit square: x0y0 x1y0
// x0y1 x1y1
vector4_type bilinearCoeffs; // (x0y0, x0y1, x1y0, x1y1)
vector2_type twiceAreasUnderXCurve;
scalar_type pdf(const vector2_type u)
{
return 4.0 * nbl::hlsl::mix(nbl::hlsl::mix(bilinearCoeffs[0], bilinearCoeffs[1], u.x), nbl::hlsl::mix(bilinearCoeffs[2], bilinearCoeffs[3], u.x), u.y) / (bilinearCoeffs[0] + bilinearCoeffs[1] + bilinearCoeffs[2] + bilinearCoeffs[3]);
}

// unit square: x0y0 x1y0
// x0y1 x1y1
vector4_type bilinearCoeffs; // (x0y0, x0y1, x1y0, x1y1)
vector2_type twiceAreasUnderXCurve;
};

}
}
}
} // namespace sampling
} // namespace hlsl
} // namespace nbl

#endif
35 changes: 21 additions & 14 deletions include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#include "nbl/builtin/hlsl/math/functions.hlsl"
#include "nbl/builtin/hlsl/numbers.hlsl"
#include "nbl/builtin/hlsl/sampling/warp_and_pdf.hlsl"

namespace nbl
{
Expand All @@ -18,21 +19,27 @@ namespace sampling
template<typename T NBL_PRIMARY_REQUIRES(concepts::FloatingPointLikeScalar<T>)
struct BoxMullerTransform
{
using scalar_type = T;
using vector2_type = vector<T,2>;

vector2_type operator()(const vector2_type xi)
{
scalar_type sinPhi, cosPhi;
math::sincos<scalar_type>(2.0 * numbers::pi<scalar_type> * xi.y - numbers::pi<scalar_type>, sinPhi, cosPhi);
return vector2_type(cosPhi, sinPhi) * nbl::hlsl::sqrt(-2.0 * nbl::hlsl::log(xi.x)) * stddev;
}

T stddev;
using scalar_type = T;
using vector2_type = vector<T, 2>;

// ResamplableSampler concept types
using domain_type = vector2_type;
using codomain_type = vector2_type;
using density_type = scalar_type;
using sample_type = codomain_and_rcpPdf<codomain_type, density_type>;

vector2_type operator()(const vector2_type xi)
{
scalar_type sinPhi, cosPhi;
math::sincos<scalar_type>(2.0 * numbers::pi<scalar_type> * xi.y - numbers::pi<scalar_type>, sinPhi, cosPhi);
return vector2_type(cosPhi, sinPhi) * nbl::hlsl::sqrt(-2.0 * nbl::hlsl::log(xi.x)) * stddev;
}

T stddev;
};

}
}
}
} // namespace sampling
} // namespace hlsl
} // namespace nbl

#endif
55 changes: 29 additions & 26 deletions include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,37 @@ namespace sampling
{

template<typename T>
vector<T,2> concentricMapping(const vector<T,2> _u)
vector<T, 2> concentricMapping(const vector<T, 2> _u)
{
//map [0;1]^2 to [-1;1]^2
vector<T,2> u = 2.0f * _u - hlsl::promote<vector<T,2> >(1.0);

vector<T,2> p;
if (hlsl::all<vector<bool,2> >(glsl::equal(u, hlsl::promote<vector<T,2> >(0.0))))
p = hlsl::promote<vector<T,2> >(0.0);
else
{
T r;
T theta;
if (abs<T>(u.x) > abs<T>(u.y)) {
r = u.x;
theta = 0.25 * numbers::pi<T> * (u.y / u.x);
} else {
r = u.y;
theta = 0.5 * numbers::pi<T> - 0.25 * numbers::pi<T> * (u.x / u.y);
}

p = r * vector<T,2>(cos<T>(theta), sin<T>(theta));
}

return p;
//map [0;1]^2 to [-1;1]^2
vector<T, 2> u = 2.0f * _u - hlsl::promote<vector<T, 2> >(1.0);

vector<T, 2> p;
if (hlsl::all<vector<bool, 2> >(glsl::equal(u, hlsl::promote<vector<T, 2> >(0.0))))
p = hlsl::promote<vector<T, 2> >(0.0);
else
{
T r;
T theta;
if (abs<T>(u.x) > abs<T>(u.y))
{
r = u.x;
theta = 0.25 * numbers::pi<T> * (u.y / u.x);
}
else
{
r = u.y;
theta = 0.5 * numbers::pi<T> - 0.25 * numbers::pi<T> * (u.x / u.y);
}

p = r * vector<T, 2>(cos<T>(theta), sin<T>(theta));
}

return p;
}

}
}
}
} // namespace sampling
} // namespace hlsl
} // namespace nbl

#endif
Loading
Loading