-
Notifications
You must be signed in to change notification settings - Fork 65
Hlsl path tracer example #863
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: hlsl_bxdfs
Are you sure you want to change the base?
Changes from all commits
02d6d0f
129b50e
74261dc
ab3ae20
355cfec
ebf8fca
11180f4
4516051
d9a00c9
ffe9029
cee192e
b207312
673f788
69a257d
866e6d7
85e955f
3b167ab
19e3a35
6b5bf06
7b574da
1c773d9
326c885
6132a4e
0bd26c7
ebb1b15
7cb977d
67c525e
a8f209e
e8d2ed8
c47f446
642e46d
1137b6b
5cd4e6c
7e8dd81
f86dd0c
b154638
7892563
b21b789
1f461ff
df2321a
26adf95
0d80626
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O. | ||
// This file is part of the "Nabla Engine". | ||
// For conditions of distribution and use, see copyright notice in nabla.h | ||
#ifndef _NBL_BUILTIN_HLSL_MATH_MORTON_INCLUDED_ | ||
#define _NBL_BUILTIN_HLSL_MATH_MORTON_INCLUDED_ | ||
|
||
#include "nbl/builtin/hlsl/cpp_compat.hlsl" | ||
|
||
namespace nbl | ||
{ | ||
namespace hlsl | ||
{ | ||
namespace math | ||
{ | ||
|
||
namespace impl | ||
{ | ||
|
||
template<typename T, uint32_t bitDepth> | ||
struct MortonComponent; | ||
|
||
template<typename T> | ||
struct MortonComponent<T, 8u> | ||
{ | ||
static T decode2d(T x) | ||
{ | ||
x &= 0x55555555u; | ||
x = (x ^ (x >> 1u)) & 0x33333333u; | ||
x = (x ^ (x >> 2u)) & 0x0f0f0f0fu; | ||
x = (x ^ (x >> 4u)) & 0x00ff00ffu; | ||
return x; | ||
} | ||
}; | ||
|
||
template<typename T> | ||
struct MortonComponent<T, 32u> | ||
{ | ||
static T decode2d(T x) | ||
{ | ||
x &= 0x55555555u; | ||
x = (x ^ (x >> 1u)) & 0x33333333u; | ||
x = (x ^ (x >> 2u)) & 0x0f0f0f0fu; | ||
x = (x ^ (x >> 4u)) & 0x00ff00ffu; | ||
x = (x ^ (x >> 8u)) & 0x0000ffffu; | ||
x = (x ^ (x >> 16u)); | ||
return x; | ||
} | ||
}; | ||
|
||
} | ||
|
||
template<typename T, uint32_t bitDepth=sizeof(T)*8u> | ||
struct Morton | ||
{ | ||
using vector2_type = vector<T, 2>; | ||
using component_type = impl::MortonComponent<T, bitDepth>; | ||
|
||
static vector2_type decode2d(T x) | ||
{ | ||
return vector2_type(component_type::decode2d(x), component_type::decode2d(x >> 1u)); | ||
} | ||
}; | ||
|
||
} | ||
} | ||
} | ||
|
||
#endif | ||
Comment on lines
+1
to
+68
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. file will die after #860 is merged |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O. | ||
// This file is part of the "Nabla Engine". | ||
// For conditions of distribution and use, see copyright notice in nabla.h | ||
|
||
#ifndef _NBL_BUILTIN_HLSL_SAMPLING_BILINEAR_INCLUDED_ | ||
#define _NBL_BUILTIN_HLSL_SAMPLING_BILINEAR_INCLUDED_ | ||
|
||
#include <nbl/builtin/hlsl/cpp_compat.hlsl> | ||
#include <nbl/builtin/hlsl/limits.hlsl> | ||
#include <nbl/builtin/hlsl/sampling/linear.hlsl> | ||
|
||
namespace nbl | ||
{ | ||
namespace hlsl | ||
{ | ||
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>; | ||
|
||
static Bilinear<T> create(NBL_CONST_REF_ARG(vector4_type) bilinearCoeffs) | ||
{ | ||
Bilinear<T> retval; | ||
retval.bilinearCoeffs = bilinearCoeffs; | ||
return retval; | ||
} | ||
|
||
vector2_type generate(NBL_REF_ARG(scalar_type) rcpPdf, NBL_CONST_REF_ARG(vector2_type) _u) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we need some structs like template<typename V, typename P=float>
struct ValueAndPdf;
template<typename T, typename P=float>
struct ValueAndRcpPdf; in do as part of #811 P.S. can require that |
||
{ | ||
vector2_type u = _u; | ||
const vector2_type twiceAreasUnderXCurve = vector2_type(bilinearCoeffs[0] + bilinearCoeffs[1], bilinearCoeffs[2] + bilinearCoeffs[3]); | ||
Linear<scalar_type> lineary = Linear<scalar_type>::create(twiceAreasUnderXCurve); | ||
u.y = lineary.generate(u.y); | ||
|
||
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); | ||
|
||
rcpPdf = (twiceAreasUnderXCurve[0] + twiceAreasUnderXCurve[1]) / (4.0 * nbl::hlsl::mix(ySliceEndPoints[0], ySliceEndPoints[1], u.x)); | ||
|
||
return u; | ||
} | ||
|
||
scalar_type pdf(NBL_CONST_REF_ARG(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]); | ||
} | ||
|
||
vector4_type bilinearCoeffs; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. document which index/component maps to which vertex of the unit square |
||
}; | ||
|
||
} | ||
} | ||
} | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O. | ||
// This file is part of the "Nabla Engine". | ||
// For conditions of distribution and use, see copyright notice in nabla.h | ||
|
||
#ifndef _NBL_BUILTIN_HLSL_BOX_MULLER_TRANSFORM_INCLUDED_ | ||
#define _NBL_BUILTIN_HLSL_BOX_MULLER_TRANSFORM_INCLUDED_ | ||
|
||
#include "nbl/builtin/hlsl/math/functions.hlsl" | ||
#include "nbl/builtin/hlsl/numbers.hlsl" | ||
|
||
namespace nbl | ||
{ | ||
namespace hlsl | ||
{ | ||
|
||
template<typename T> | ||
vector<T,2> boxMullerTransform(vector<T,2> xi, T stddev) | ||
{ | ||
T sinPhi, cosPhi; | ||
math::sincos<T>(2.0 * numbers::pi<float> * xi.y - numbers::pi<float>, sinPhi, cosPhi); | ||
return vector<T,2>(cosPhi, sinPhi) * nbl::hlsl::sqrt(-2.0 * nbl::hlsl::log(xi.x)) * stddev; | ||
} | ||
Comment on lines
+16
to
+22
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. turn into struct with |
||
|
||
} | ||
} | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O. | ||
// This file is part of the "Nabla Engine". | ||
// For conditions of distribution and use, see copyright notice in nabla.h | ||
|
||
#ifndef _NBL_BUILTIN_HLSL_SAMPLING_LINEAR_INCLUDED_ | ||
#define _NBL_BUILTIN_HLSL_SAMPLING_LINEAR_INCLUDED_ | ||
|
||
#include <nbl/builtin/hlsl/cpp_compat.hlsl> | ||
#include <nbl/builtin/hlsl/limits.hlsl> | ||
|
||
namespace nbl | ||
{ | ||
namespace hlsl | ||
{ | ||
namespace sampling | ||
{ | ||
|
||
template<typename T> | ||
struct Linear | ||
{ | ||
using scalar_type = T; | ||
using vector2_type = vector<T, 2>; | ||
|
||
static Linear<T> create(NBL_CONST_REF_ARG(vector2_type) linearCoeffs) | ||
{ | ||
Linear<T> retval; | ||
retval.linearCoeffs = linearCoeffs; | ||
return retval; | ||
} | ||
|
||
scalar_type generate(scalar_type u) | ||
{ | ||
const scalar_type rcpDiff = 1.0 / (linearCoeffs[0] - linearCoeffs[1]); | ||
const vector2_type squaredCoeffs = linearCoeffs * linearCoeffs; | ||
return nbl::hlsl::abs(rcpDiff) < numeric_limits<scalar_type>::max ? (linearCoeffs[0] - nbl::hlsl::sqrt(nbl::hlsl::mix(squaredCoeffs[0], squaredCoeffs[1], u))) * rcpDiff : u; | ||
} | ||
|
||
vector2_type linearCoeffs; | ||
}; | ||
|
||
} | ||
} | ||
} | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O. | ||
// This file is part of the "Nabla Engine". | ||
// For conditions of distribution and use, see copyright notice in nabla.h | ||
|
||
#ifndef _NBL_BUILTIN_HLSL_SAMPLING_PROJECTED_SPHERICAL_TRIANGLE_INCLUDED_ | ||
#define _NBL_BUILTIN_HLSL_SAMPLING_PROJECTED_SPHERICAL_TRIANGLE_INCLUDED_ | ||
|
||
#include <nbl/builtin/hlsl/cpp_compat.hlsl> | ||
#include <nbl/builtin/hlsl/limits.hlsl> | ||
#include <nbl/builtin/hlsl/math/functions.hlsl> | ||
#include <nbl/builtin/hlsl/sampling/bilinear.hlsl> | ||
#include <nbl/builtin/hlsl/sampling/spherical_triangle.hlsl> | ||
|
||
namespace nbl | ||
{ | ||
namespace hlsl | ||
{ | ||
namespace sampling | ||
{ | ||
|
||
template<typename T> | ||
struct ProjectedSphericalTriangle | ||
{ | ||
using scalar_type = T; | ||
using vector2_type = vector<T, 2>; | ||
using vector3_type = vector<T, 3>; | ||
using vector4_type = vector<T, 4>; | ||
|
||
static ProjectedSphericalTriangle<T> create(NBL_CONST_REF_ARG(shapes::SphericalTriangle<T>) tri) | ||
{ | ||
ProjectedSphericalTriangle<T> retval; | ||
retval.tri = tri; | ||
return retval; | ||
} | ||
|
||
vector4_type computeBilinearPatch(NBL_CONST_REF_ARG(vector3_type) receiverNormal, bool isBSDF) | ||
{ | ||
const scalar_type minimumProjSolidAngle = 0.0; | ||
|
||
matrix<T, 3, 3> m = matrix<T, 3, 3>(tri.vertex0, tri.vertex1, tri.vertex2); | ||
const vector3_type bxdfPdfAtVertex = math::conditionalAbsOrMax(isBSDF, nbl::hlsl::mul(m, receiverNormal), (vector3_type)minimumProjSolidAngle); | ||
|
||
return bxdfPdfAtVertex.yyxz; | ||
} | ||
|
||
vector3_type generate(NBL_REF_ARG(scalar_type) rcpPdf, scalar_type solidAngle, NBL_CONST_REF_ARG(vector3_type) cos_vertices, NBL_CONST_REF_ARG(vector3_type) sin_vertices, scalar_type cos_a, scalar_type cos_c, scalar_type csc_b, scalar_type csc_c, NBL_CONST_REF_ARG(vector3_type) receiverNormal, bool isBSDF, NBL_CONST_REF_ARG(vector2_type) _u) | ||
{ | ||
vector2_type u; | ||
// pre-warp according to proj solid angle approximation | ||
vector4_type patch = computeBilinearPatch(receiverNormal, isBSDF); | ||
Bilinear<scalar_type> bilinear = Bilinear<scalar_type>::create(patch); | ||
u = bilinear.generate(rcpPdf, u); | ||
|
||
// now warp the points onto a spherical triangle | ||
const vector3_type L = sphtri.generate(solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, u); | ||
rcpPdf *= solidAngle; | ||
|
||
return L; | ||
} | ||
|
||
vector3_type generate(NBL_REF_ARG(scalar_type) rcpPdf, NBL_CONST_REF_ARG(vector3_type) receiverNormal, bool isBSDF, NBL_CONST_REF_ARG(vector2_type) u) | ||
{ | ||
scalar_type cos_a, cos_c, csc_b, csc_c; | ||
vector3_type cos_vertices, sin_vertices; | ||
const scalar_type solidAngle = tri.solidAngleOfTriangle(cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c); | ||
return generate(rcpPdf, solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, receiverNormal, isBSDF, u); | ||
} | ||
|
||
scalar_type pdf(scalar_type solidAngle, NBL_CONST_REF_ARG(vector3_type) cos_vertices, NBL_CONST_REF_ARG(vector3_type) sin_vertices, scalar_type cos_a, scalar_type cos_c, scalar_type csc_b, scalar_type csc_c, NBL_CONST_REF_ARG(vector3_type) receiverNormal, bool receiverWasBSDF, NBL_CONST_REF_ARG(vector3_type) L) | ||
{ | ||
scalar_type pdf; | ||
const vector2_type u = sphtri.generateInverse(pdf, solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, L); | ||
|
||
vector4_type patch = computeBilinearPatch(receiverNormal, receiverWasBSDF); | ||
Bilinear<scalar_type> bilinear = Bilinear<scalar_type>::create(patch); | ||
return pdf * bilinear.pdf(u); | ||
} | ||
|
||
scalar_type pdf(NBL_CONST_REF_ARG(vector3_type) receiverNormal, bool receiverWasBSDF, NBL_CONST_REF_ARG(vector3_type) L) | ||
{ | ||
scalar_type pdf; | ||
const vector2_type u = sphtri.generateInverse(pdf, L); | ||
|
||
vector4_type patch = computeBilinearPatch(receiverNormal, receiverWasBSDF); | ||
Bilinear<scalar_type> bilinear = Bilinear<scalar_type>::create(patch); | ||
return pdf * bilinear.pdf(u); | ||
} | ||
|
||
shapes::SphericalTriangle<T> tri; | ||
sampling::SphericalTriangle<T> sphtri; | ||
}; | ||
|
||
} | ||
} | ||
} | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be templated on
T
instead offloat
and live insampling.hlsl
(named same as the folder and namespace), do as part of #811P.S. for the constant you can use
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or you can put it in
sampling/basic.hlsl