From 02d6d0f3e543aaad7d4e52ecf753a826879b8904 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 4 Feb 2025 14:16:42 +0700 Subject: [PATCH 01/23] initial example --- examples_tests | 2 +- .../hlsl/sampling/box_muller_transform.hlsl | 27 +++++++++++++++++++ src/nbl/builtin/CMakeLists.txt | 1 + 3 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl diff --git a/examples_tests b/examples_tests index d7f7a87fa0..b171724bb0 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit d7f7a87fa08a56a16cd1bcc7d4d9fd48fc8c278c +Subproject commit b171724bb0db3bf6f144d6eb077e95ddea806cbd diff --git a/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl b/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl new file mode 100644 index 0000000000..efa8d66e2b --- /dev/null +++ b/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl @@ -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 +vector boxMullerTransform(vector xi, T stddev) +{ + T sinPhi, cosPhi; + nbl::hlsl::sincos(2.0 * numbers::pi * xi.y - numbers::pi, sinPhi, cosPhi); + return vector(cosPhi, sinPhi) * nbl::hlsl::sqrt(-2.0 * nbl::hlsl::log(xi.x)) * stddev; +} + +} +} + +#endif \ No newline at end of file diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 35f22d6ba1..abab705d13 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -313,6 +313,7 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/line.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/beziers.hlsl") #sampling LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/concentric_mapping.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/box_muller_transform.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/cos_weighted.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/uniform.hlsl") # From 129b50e530f2a3d5b673df8ddaab004b9404fd80 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 6 Feb 2025 16:03:31 +0700 Subject: [PATCH 02/23] use bxdf creation params struct --- examples_tests | 2 +- include/nbl/builtin/hlsl/bxdf/common.hlsl | 15 +++++++++ include/nbl/builtin/hlsl/bxdf/reflection.hlsl | 26 ++++++++++++++++ .../nbl/builtin/hlsl/bxdf/transmission.hlsl | 31 +++++++++++++++++++ 4 files changed, 73 insertions(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index b171724bb0..5a5fbfe55a 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit b171724bb0db3bf6f144d6eb077e95ddea806cbd +Subproject commit 5a5fbfe55aa4cf062c562f19507ba30de085b7a6 diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index e518f0dcba..050366c6dc 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -844,6 +844,7 @@ enum BxDFClampMode : uint16_t BCM_ABS }; +// unified param struct for calls to BxDF::eval, BxDF::pdf, BxDF::quotient_and_pdf template) struct SBxDFParams { @@ -976,6 +977,20 @@ struct SBxDFParams Scalar uNdotV; }; +// unified param struct for calls to BxDF::create +template) +struct SBxDFCreationParams +{ + bool is_aniso; + Scalar A; + vector Axy; + Spectrum ior0; + Spectrum ior1; + Scalar eta; + Spectrum eta2; + Spectrum luminosityContributionHint; +}; + // fresnel stuff namespace impl { diff --git a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl index bf534e2f8d..b074bcaddb 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl @@ -59,6 +59,11 @@ struct SLambertianBxDF return retval; } + static this_t create(SBxDFCreationParams params) + { + return create(); + } + scalar_type __eval_pi_factored_out(scalar_type maxNdotL) { return maxNdotL; @@ -117,6 +122,11 @@ struct SOrenNayarBxDF return retval; } + static this_t create(SBxDFCreationParams params) + { + return create(params.A); + } + scalar_type __rec_pi_factored_out_wo_clamps(scalar_type VdotL, scalar_type maxNdotL, scalar_type maxNdotV) { scalar_type A2 = A * 0.5; @@ -342,6 +352,14 @@ struct SBeckmannBxDF return retval; } + static this_t create(SBxDFCreationParams params) + { + if (params.is_aniso) + return create(params.Axy.x, params.Axy.y, params.ior0, params.ior1); + else + return create(params.A, params.ior0, params.ior1); + } + scalar_type __eval_DG_wo_clamps(params_t params) { if (params.is_aniso) @@ -570,6 +588,14 @@ struct SGGXBxDF return retval; } + static this_t create(SBxDFCreationParams params) + { + if (params.is_aniso) + return create(params.Axy.x, params.Axy.y, params.ior0, params.ior1); + else + return create(params.A, params.ior0, params.ior1); + } + scalar_type __eval_DG_wo_clamps(params_t params) { if (params.is_aniso) diff --git a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl index 17682a7384..18d80e93aa 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl @@ -63,6 +63,11 @@ struct SLambertianBxDF return retval; } + static this_t create(SBxDFCreationParams params) + { + return create(); + } + scalar_type __eval_pi_factored_out(scalar_type absNdotL) { return absNdotL; @@ -124,6 +129,11 @@ struct SSmoothDielectricBxDF return retval; } + static this_t create(SBxDFCreationParams params) + { + return create(params.eta); + } + spectral_type eval(params_t params) { return (spectral_type)0; @@ -205,6 +215,11 @@ struct SSmoothDielectricBxDF return retval; } + static this_t create(SBxDFCreationParams params) + { + return create(params.eta2, params.luminosityContributionHint); + } + spectral_type eval(params_t params) { return (spectral_type)0; @@ -299,6 +314,14 @@ struct SBeckmannDielectricBxDF return retval; } + static this_t create(SBxDFCreationParams params) + { + if (params.is_aniso) + return create(params.eta, params.Axy.x, params.Axy.y); + else + return create(params.eta, params.A); + } + spectral_type eval(params_t params) { scalar_type orientedEta, dummy; @@ -466,6 +489,14 @@ struct SGGXDielectricBxDF return retval; } + static this_t create(SBxDFCreationParams params) + { + if (params.is_aniso) + return create(params.eta, params.Axy.x, params.Axy.y); + else + return create(params.eta, params.A); + } + spectral_type eval(params_t params) { scalar_type orientedEta, dummy; From 74261dc22e7f375e12abf4de232e13ea5ebcbee5 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 7 Feb 2025 14:37:25 +0700 Subject: [PATCH 03/23] triangle and rectangle shapes --- examples_tests | 2 +- .../nbl/builtin/hlsl/shapes/rectangle.hlsl | 51 ++++++++++ include/nbl/builtin/hlsl/shapes/triangle.hlsl | 99 +++++++++++++++++++ src/nbl/builtin/CMakeLists.txt | 2 + 4 files changed, 153 insertions(+), 1 deletion(-) create mode 100644 include/nbl/builtin/hlsl/shapes/rectangle.hlsl create mode 100644 include/nbl/builtin/hlsl/shapes/triangle.hlsl diff --git a/examples_tests b/examples_tests index 5a5fbfe55a..85e67ad0c4 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 5a5fbfe55aa4cf062c562f19507ba30de085b7a6 +Subproject commit 85e67ad0c4012d7d8d2014489327036d89b0bf57 diff --git a/include/nbl/builtin/hlsl/shapes/rectangle.hlsl b/include/nbl/builtin/hlsl/shapes/rectangle.hlsl new file mode 100644 index 0000000000..854a326aaf --- /dev/null +++ b/include/nbl/builtin/hlsl/shapes/rectangle.hlsl @@ -0,0 +1,51 @@ +// 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_SHAPES_RECTANGLE_INCLUDED_ +#define _NBL_BUILTIN_HLSL_SHAPES_RECTANGLE_INCLUDED_ + +#include +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace shapes +{ + +template +struct SphericalRectangle +{ + using scalar_type = T; + using vector3_type = vector; + using vector4_type = vector; + using matrix3x3_type = matrix; + + static SphericalRectangle create(NBL_CONST_REF_ARG(vector3_type) observer, NBL_CONST_REF_ARG(vector3_type) rectangleOrigin, NBL_CONST_REF_ARG(vector3_type) T, NBL_CONST_REF_ARG(vector3_type) B, NBL_CONST_REF_ARG(vector3_type) N) + { + matrix3x3_type TBN = nbl::hlsl::transpose(matrix3x3_type(T, B, isotropic_type::N)); + return nbl::hlsl::mul(TBN, rectangleOrigin - observer); + } + + scalar_type solidAngleOfRectangle(NBL_CONST_REF_ARG(vector3_type) r0, NBL_CONST_REF_ARG(vector) rectangleExtents) + { + const vector4_type denorm_n_z = vector4_type(-r0.y, r0.x + rectangleExtents.x, r0.y + rectangleExtents.y, -r0.x); + const vector4_type n_z = denorm_n_z / nbl::hlsl::sqrt((vector4_type)(r0.z * r0.z) + denorm_n_z * denorm_n_z); + const vector4_type cosGamma = vec4( + -n_z[0] * n_z[1], + -n_z[1] * n_z[2], + -n_z[2] * n_z[3], + -n_z[3] * n_z[0] + ); + return math::getSumofArccosABCD(cosGamma[0], cosGamma[1], cosGamma[2], cosGamma[3]) - 2 * numbers::pi; + } +} + +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/shapes/triangle.hlsl b/include/nbl/builtin/hlsl/shapes/triangle.hlsl new file mode 100644 index 0000000000..f7ce67a1c9 --- /dev/null +++ b/include/nbl/builtin/hlsl/shapes/triangle.hlsl @@ -0,0 +1,99 @@ +// 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_SHAPES_TRIANGLE_INCLUDED_ +#define _NBL_BUILTIN_HLSL_SHAPES_TRIANGLE_INCLUDED_ + +#include +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace shapes +{ + +template +struct SphericalTriangle +{ + using scalar_type = T; + using vector3_type = vector; + + static SphericalTriangle create(NBL_CONST_REF_ARG(vector3_type) vertex0, NBL_CONST_REF_ARG(vector3_type) vertex1, NBL_CONST_REF_ARG(vector3_type) vertex2, NBL_CONST_REF_ARG(vector3_type) origin) + { + SphericalTriangle retval; + retval.vertex0 = nbl::hlsl::normalize(vertex0 - origin); + retval.vertex1 = nbl::hlsl::normalize(vertex1 - origin); + retval.vertex2 = nbl::hlsl::normalize(vertex2 - origin); + return retval; + } + + bool pyramidAngles(NBL_REF_ARG(vector3_type) cos_sides, NBL_REF_ARG(vector3_type) csc_sides) + { + cos_sides = vector3_type(nbl::hlsl::dot(vertex1, vertex2), nbl::hlsl::dot(vertex2, vertex0), nbl::hlsl::dot(vertex0, vertex1)); + csc_sides = 1.0 / nbl::hlsl::sqrt((vector3_type)(1.f) - cos_sides * cos_sides); + return nbl::hlsl::any(csc_sides >= (vector3_type)(numeric_limits::max)); + } + + scalar_type solidAngleOfTriangle(NBL_REF_ARG(vector3_type) cos_vertices, NBL_REF_ARG(vector3_type) sin_vertices, NBL_REF_ARG(scalar_type) cos_a, NBL_REF_ARG(scalar_type) cos_c, NBL_REF_ARG(scalar_type) csc_b, NBL_REF_ARG(scalar_type) csc_c) + { + vector3_type cos_sides,csc_sides; + if (pyramidAngles(cos_sides, csc_sides)) + return 0.f; + + // these variables might eventually get optimized out + cos_a = cos_sides[0]; + cos_c = cos_sides[2]; + csc_b = csc_sides[1]; + csc_c = csc_sides[2]; + + // Both vertices and angles at the vertices are denoted by the same upper case letters A, B, and C. The angles A, B, C of the triangle are equal to the angles between the planes that intersect the surface of the sphere or, equivalently, the angles between the tangent vectors of the great circle arcs where they meet at the vertices. Angles are in radians. The angles of proper spherical triangles are (by convention) less than PI + cos_vertices = clamp((cos_sides - cos_sides.yzx * cos_sides.zxy) * csc_sides.yzx * csc_sides.zxy, (vector3_type)(-1.f), (vector3_type)1.f); // using Spherical Law of Cosines (TODO: do we need to clamp anymore? since the pyramid angles method introduction?) + sin_vertices = sqrt((vector3_type)1.f - cos_vertices * cos_vertices); + + return math::getArccosSumofABC_minus_PI(cos_vertices[0], cos_vertices[1], cos_vertices[2], sin_vertices[0], sin_vertices[1], sin_vertices[2]); + } + + scalar_type solidAngleOfTriangle() + { + vector3_type dummy0,dummy1; + scalar_type dummy2,dummy3,dummy4,dummy5; + return solidAngleOfTriangle(dummy0,dummy1,dummy2,dummy3,dummy4,dummy5); + } + + scalar_type projectedSolidAngleOfTriangle(NBL_CONST_REF_ARG(vector3_type) receiverNormal, NBL_REF_ARG(vector3_type) cos_sides, NBL_REF_ARG(vector3_type) csc_sides, NBL_REF_ARG(vector3_type) cos_vertices) + { + if (pyramidAngles(cos_sides, csc_sides)) + return 0.f; + + vector3_type awayFromEdgePlane0 = nbl::hlsl::cross(vertex1, vertex2) * csc_sides[0]; + vector3_type awayFromEdgePlane1 = nbl::hlsl::cross(vertex2, vertex0) * csc_sides[1]; + vector3_type awayFromEdgePlane2 = nbl::hlsl::cross(vertex0, vertex1) * csc_sides[2]; + + // useless here but could be useful somewhere else + cos_vertices[0] = nbl::hlsl::dot(awayFromEdgePlane1, awayFromEdgePlane2); + cos_vertices[1] = nbl::hlsl::dot(awayFromEdgePlane2, awayFromEdgePlane0); + cos_vertices[2] = nbl::hlsl::dot(awayFromEdgePlane0, awayFromEdgePlane1); + // TODO: above dot products are in the wrong order, either work out which is which, or try all 6 permutations till it works + cos_vertices = nbl::hlsl::clamp((cos_sides - cos_sides.yzx * cos_sides.zxy) * csc_sides.yzx * csc_sides.zxy, (vector3_type)(-1.f), (vector3_type)1.f); + + matrix mat = + const vector3_type externalProducts = nbl::hlsl::abs(nbl::hlsl::transpose(awayFromEdgePlane) * receiverNormal); + + const vector3_type pyramidAngles = acos(cos_sides); + return nbl::hlsl::dot(pyramidAngles, externalProducts) / (2.f * numbers::pi); + } + + vector3_type vertex0; + vector3_type vertex1; + vector3_type vertex2; +}; + +} +} +} + +#endif diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index abab705d13..a79f9ac31a 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -311,6 +311,8 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/circle.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/ellipse.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/line.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/beziers.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/triangle.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/rectangle.hlsl") #sampling LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/concentric_mapping.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/box_muller_transform.hlsl") From ab3ae20171ed7ea0d78338114eb420e9f179b459 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 10 Feb 2025 16:58:22 +0700 Subject: [PATCH 04/23] more sampling methods --- examples_tests | 2 +- .../nbl/builtin/hlsl/sampling/bilinear.hlsl | 61 ++++++++ include/nbl/builtin/hlsl/sampling/linear.hlsl | 45 ++++++ .../projected_spherical_triangle.hlsl | 94 +++++++++++++ .../hlsl/sampling/spherical_triangle.hlsl | 132 ++++++++++++++++++ src/nbl/builtin/CMakeLists.txt | 4 + 6 files changed, 337 insertions(+), 1 deletion(-) create mode 100644 include/nbl/builtin/hlsl/sampling/bilinear.hlsl create mode 100644 include/nbl/builtin/hlsl/sampling/linear.hlsl create mode 100644 include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl create mode 100644 include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl diff --git a/examples_tests b/examples_tests index 85e67ad0c4..2c500b1e06 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 85e67ad0c4012d7d8d2014489327036d89b0bf57 +Subproject commit 2c500b1e06e3e83b2a427bf0aa1ef27878467e0b diff --git a/include/nbl/builtin/hlsl/sampling/bilinear.hlsl b/include/nbl/builtin/hlsl/sampling/bilinear.hlsl new file mode 100644 index 0000000000..1d5f9a91e8 --- /dev/null +++ b/include/nbl/builtin/hlsl/sampling/bilinear.hlsl @@ -0,0 +1,61 @@ +// 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 +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace sampling +{ + +template +struct Bilinear +{ + using scalar_type = T; + using vector2_type = vector; + using vector3_type = vector; + using vector4_type = vector; + + static Bilinear create(NBL_CONST_REF_ARG(vector4_type) bilinearCoeffs) + { + Bilinear retval; + retval.bilinearCoeffs = bilinearCoeffs; + return retval; + } + + vector2_type generate(NBL_REG_ARG(scalar_type) rcpPdf, NBL_CONST_REF_ARG(vector2_type) u) + { + const vector2_type twiceAreasUnderXCurve = vector2_type(bilinearCoeffs[0] + bilinearCoeffs[1], bilinearCoeffs[2] + bilinearCoeffs[3]); + Linear lineary = Linear::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 linearx = Linear::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; +}; + +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/sampling/linear.hlsl b/include/nbl/builtin/hlsl/sampling/linear.hlsl new file mode 100644 index 0000000000..8b9b3fb058 --- /dev/null +++ b/include/nbl/builtin/hlsl/sampling/linear.hlsl @@ -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_BILINEAR_INCLUDED_ +#define _NBL_BUILTIN_HLSL_SAMPLING_BILINEAR_INCLUDED_ + +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace sampling +{ + +template +struct Linear +{ + using scalar_type = T; + using vector2_type = vector; + + static Linear create(NBL_CONST_REF_ARG(vector2_type) linearCoeffs) + { + Linear 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::max ? (linearCoeffs[0] - nbl::hlsl::sqrt(nbl::hlsl::mix(squaredCoeffs[0], squaredCoeffs[1], u))) * rcpDiff : u; + } + + vector2_type linearCoeffs; +}; + +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl b/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl new file mode 100644 index 0000000000..5832e9aab2 --- /dev/null +++ b/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl @@ -0,0 +1,94 @@ +// 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 +#include +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace sampling +{ + +template +struct ProjectedSphericalTriangle +{ + using scalar_type = T; + using vector2_type = vector; + using vector3_type = vector; + using vector4_type = vector; + + static ProjectedSphericalTriangle create(NBL_CONST_REG_ARG(shapes::SphericalTriangle) tri) + { + ProjectedSphericalTriangle retval; + retval.tri = tri; + return retval; + } + + vector4_type computeBilinearPatch(NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool isBSDF) + { + const scalar_type minimumProjSolidAngle = 0.0; + + matrix m = matrix(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_REG_ARG(scalar_type) rcpPdf, scalar_type solidAngle, NBL_CONST_REG_ARG(vector3_type) cos_vertices, NBL_CONST_REG_ARG(vector3_type) sin_vertices, scalar_type cos_a, scalar_type cos_c, scalar_type csc_b, scalar_type csc_c, NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool isBSDF, NBL_CONST_REG_ARG(vector2_type) u) + { + // pre-warp according to proj solid angle approximation + vector4_type patch = computeBilinearPatch(receiverNormal, isBSDF); + Bilinear bilinear = Bilinear::create(patch); + u = bilinear.generate(rcpPdf, u); + + // now warp the points onto a spherical triangle + const vector3_type L = tri.generate(solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, u); + rcpPdf *= solidAngle; + + return L; + } + + vector3_type generate(NBL_REG_ARG(scalar_type) rcpPdf, NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool isBSDF, NBL_CONST_REG_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_REG_ARG(vector3_type) cos_vertices, NBL_CONST_REG_ARG(vector3_type) sin_vertices, scalar_type cos_a, scalar_type cos_c, scalar_type csc_b, scalar_type csc_c, NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool receiverWasBSDF, NBL_CONST_REG_ARG(vector3_type) L) + { + scalar_type pdf; + const vector2_type u = tri.generateInverse(pdf, solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, L); + + vector4_type patch = computeBilinearPatch(receiverNormal, receiverWasBSDF); + Bilinear bilinear = Bilinear::create(patch); + return pdf * bilinear.pdf(u); + } + + scalar_type pdf(NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool receiverWasBSDF, NBL_CONST_REG_ARG(vector3_type) L) + { + scalar_type pdf; + const vector2_type u = tri.generateInverse(pdf, L); + + vector4_type patch = computeBilinearPatch(receiverNormal, receiverWasBSDF); + Bilinear bilinear = Bilinear::create(patch); + return pdf * bilinear.pdf(u); + } + + shapes::SphericalTriangle tri; +}; + +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl b/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl new file mode 100644 index 0000000000..9501cdc3d1 --- /dev/null +++ b/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl @@ -0,0 +1,132 @@ +// 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_SPHERICAL_TRIANGLE_INCLUDED_ +#define _NBL_BUILTIN_HLSL_SAMPLING_SPHERICAL_TRIANGLE_INCLUDED_ + +#include +#include +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace sampling +{ + +template +struct SphericalTriangle +{ + using scalar_type = T; + using vector2_type = vector; + using vector3_type = vector; + + static SphericalTriangle create(NBL_CONST_REG_ARG(shapes::SphericalTriangle) tri) + { + SphericalTriangle retval; + retval.tri = tri; + return retval; + } + + vector3_type slerp_delta(NBL_CONST_REF_ARG(vector3_type) start, NBL_CONST_REF_ARG(vector3_type) preScaledWaypoint, scalar_type cosAngleFromStart) + { + vector3_type planeNormal = nbl::hlsl::cross(start,preScaledWaypoint); + + cosAngleFromStart *= 0.5; + const scalar_type sinAngle = nbl::hlsl::sqrt(0.5 - cosAngleFromStart); + const scalar_type cosAngle = nbl::hlsl::sqrt(0.5 + cosAngleFromStart); + + planeNormal *= sinAngle; + const vector3_type precompPart = nbl::hlsl::cross(planeNormal, start) * 2.0; + + return precompPart * cosAngle + nbl::hlsl::cross(planeNormal, precompPart); + } + + // WARNING: can and will return NAN if one or three of the triangle edges are near zero length + vector3_type generate(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(vector2_type) u) + { + scalar_type negSinSubSolidAngle,negCosSubSolidAngle; + math::sincos(solidAngle * u.x - numbers::pi, negSinSubSolidAngle, negCosSubSolidAngle); + + const scalar_type p = negCosSubSolidAngle * sin_vertices[0] - negSinSubSolidAngle * cos_vertices[0]; + const scalar_type q = -negSinSubSolidAngle * sin_vertices[0] - negCosSubSolidAngle * cos_vertices[0]; + + // TODO: we could optimize everything up and including to the first slerp, because precision here is just godawful + scalar_type u_ = q - cos_vertices[0]; + scalar_type v_ = p + sin_vertices[0] * cos_c; + + // the slerps could probably be optimized by sidestepping `normalize` calls and accumulating scaling factors + vector3_type C_s = tri.vertex0; + if (csc_b < numeric_limits::max) + { + const scalar_type cosAngleAlongAC = ((v_ * q - u_ * p) * cos_vertices[0] - v_) / ((v_ * p + u_ * q) * sin_vertices[0]); + if (nbl::hlsl::abs(cosAngleAlongAC) < 1.f) + C_s += slerp_delta(tri.vertex0, tri.vertex2 * csc_b, cosAngleAlongAC); + } + + vector3_type retval = tri.vertex1; + const scalar_type cosBC_s = nbl::hlsl::dot(C_s, tri.vertex1); + const scalar_type csc_b_s = 1.0 / nbl::hlsl::sqrt(1.0 - cosBC_s * cosBC_s); + if (csc_b_s < numeric_limits::max) + { + const scalar_type cosAngleAlongBC_s = nbl::hlsl::clamp(1.0 + cosBC_s * u.y - u.y, -1.f, 1.f); + if (nbl::hlsl::abs(cosAngleAlongBC_s) < 1.f) + retval += slerp_delta(tri.vertex1, C_s * csc_b_s, cosAngleAlongBC_s); + } + return retval; + } + + vector3_type generate(NBL_REF_ARG(scalar_type) rcpPdf, NBL_CONST_REF_ARG(vector2_type) u) + { + scalar_type cos_a, cos_c, csc_b, csc_c; + vector3_type cos_vertices, sin_vertices; + + rcpPdf = tri.solidAngleOfTriangle(cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c); + + return generate(rcpPdf, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, u); + } + + vector2_type generateInverse(NBL_REF_ARG(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) L) + { + pdf = 1.0 / solidAngle; + + const scalar_type cosAngleAlongBC_s = nbl::hlsl::dot(L, tri.vertex1); + const scalar_type csc_a_ = 1.0 / nbl::hlsl::sqrt(1.0 - cosAngleAlongBC_s * cosAngleAlongBC_s); + const scalar_type cos_b_ = nbl::hlsl::dot(L, tri.vertex0); + + const scalar_type cosB_ = (cos_b_ - cosAngleAlongBC_s * cos_c) * csc_a_ * csc_c; + const scalar_type sinB_ = nbl::hlsl::sqrt(1.0 - cosB_ * cosB_); + + const scalar_type cosC_ = sin_vertices[0] * sinB_* cos_c - cos_vertices[0] * cosB_; + const scalar_type sinC_ = nbl::hlsl::sqrt(1.0 - cosC_ * cosC_); + + const scalar_type subTriSolidAngleRatio = math::getArccosSumofABC_minus_PI(cos_vertices[0], cosB_, cosC_, sin_vertices[0], sinB_, sinC_) * pdf; + const scalar_type u = subTriSolidAngleRatio > numeric_limits::min ? subTriSolidAngleRatio : 0.0; + + const scalar_type cosBC_s = (cos_vertices[0] + cosB_ * cosC_) / (sinB_ * sinC_); + const scalar_type v = (1.0 - cosAngleAlongBC_s) / (1.0 - (cosBC_s < asfloat(0x3f7fffff) ? cosBC_s : cos_c)); + + return vector2_type(u,v); + } + + vector2_type generateInverse(NBL_REF_ARG(scalar_type) pdf, NBL_CONST_REF_ARG(vector3_type) L) + { + 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 generateInverse(pdf, solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, L); + } + + shapes::SphericalTriangle tri; +}; + +} +} +} + +#endif diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index a79f9ac31a..5cc0108874 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -314,9 +314,13 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/beziers.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/triangle.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/shapes/rectangle.hlsl") #sampling +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/linear.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/bilinear.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/concentric_mapping.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/box_muller_transform.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/cos_weighted.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/spherical_triangle.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/projected_spherical_triangle.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/uniform.hlsl") # LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/ndarray_addressing.hlsl") From 355cfecdcd508151435f01b49c7f9a1e02975a23 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 11 Feb 2025 14:03:51 +0700 Subject: [PATCH 05/23] spherical rectangle --- examples_tests | 2 +- .../hlsl/sampling/spherical_rectangle.hlsl | 86 +++++++++++++++++++ .../nbl/builtin/hlsl/shapes/rectangle.hlsl | 15 +++- include/nbl/builtin/hlsl/shapes/triangle.hlsl | 2 +- src/nbl/builtin/CMakeLists.txt | 1 + 5 files changed, 102 insertions(+), 4 deletions(-) create mode 100644 include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl diff --git a/examples_tests b/examples_tests index 2c500b1e06..e6a99165c1 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 2c500b1e06e3e83b2a427bf0aa1ef27878467e0b +Subproject commit e6a99165c1b153977192f9722381fc24f566c9ca diff --git a/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl b/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl new file mode 100644 index 0000000000..83224bfabd --- /dev/null +++ b/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl @@ -0,0 +1,86 @@ +// 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_SPHERICAL_RECTANGLE_INCLUDED_ +#define _NBL_BUILTIN_HLSL_SAMPLING_SPHERICAL_RECTANGLE_INCLUDED_ + +#include +#include +#include +#include + +namespace nbl +{ +namespace hlsl +{ +namespace sampling +{ + +template +struct SphericalRectangle +{ + using scalar_type = T; + using vector2_type = vector; + using vector3_type = vector; + using vector4_type = vector; + + static SphericalRectangle create(NBL_CONST_REG_ARG(shapes::SphericalRectangle) rect) + { + SphericalRectangle retval; + retval.rect = rect; + return retval; + } + + vector2_type generate(NBL_CONST_REF_ARG(vector2_type) rectangleExtents, NBL_CONST_REF_ARG(vector2_type) uv, NBL_REF_ARG(scalar_type) S) + { + const vector4_type denorm_n_z = vector4_type(-rect.r0.y, rect.r0.x + rectangleExtents.x, rect.r0.y + rectangleExtents.y, -rect.r0.x); + const vector4_type n_z = denorm_n_z / nbl::hlsl::sqrt(vector4_type(rect.r0.z * rect.r0.z) + denorm_n_z * denorm_n_z); + const vector4_type cosGamma = vector4_type( + -n_z[0] * n_z[1], + -n_z[1] * n_z[2], + -n_z[2] * n_z[3], + -n_z[3] * n_z[0] + ); + + scalar_type p = math::getSumofArccosAB(cosGamma[0], cosGamma[1]); + scalar_type q = math::getSumofArccosAB(cosGamma[2], cosGamma[3]); + + const scalar_type k = 2 * numbers::pi - q; + const scalar_type b0 = n_z[0]; + const scalar_type b1 = n_z[2]; + S = p + q - 2 * numbers::pi; + + const scalar_type CLAMP_EPS = 1e-5f; + + // flip z axsis if rect.r0.z > 0 + const uint32_t zFlipMask = (asuint(rect.r0.z) ^ 0x80000000u) & 0x80000000u; + rect.r0.z = asfloat(asuint(rect.r0.z) ^ zFlipMask); + vector3_type r1 = rect.r0 + vector3_type(rectangleExtents.x, rectangleExtents.y, 0); + + const scalar_type au = uv.x * S + k; + const scalar_type fu = (nbl::hlsl::cos(au) * b0 - b1) / nbl::hlsl::sin(au); + const scalar_type cu_2 = nbl::hlsl::max(fu * fu + b0 * b0, 1.f); // forces `cu` to be in [-1,1] + const scalar_type cu = asfloat(asuint(1.0 / nbl::hlsl::sqrt(cu_2)) ^ (asuint(fu) & 0x80000000u)); + + scalar_type xu = -(cu * rect.r0.z) * 1.0 / nbl::hlsl::sqrt(1 - cu * cu); + xu = nbl::hlsl::clamp(xu, rect.r0.x, r1.x); // avoid Infs + const scalar_type d_2 = xu * xu + rect.r0.z * rect.r0.z; + const scalar_type d = nbl::hlsl::sqrt(d_2); + + const scalar_type h0 = rect.r0.y / nbl::hlsl::sqrt(d_2 + rect.r0.y * rect.r0.y); + const scalar_type h1 = r1.y / nbl::hlsl::sqrt(d_2 + r1.y * r1.y); + const scalar_type hv = h0 + uv.y * (h1 - h0), hv2 = hv * hv; + const scalar_type yv = (hv2 < 1 - CLAMP_EPS) ? (hv * d) / nbl::hlsl::sqrt(1 - hv2) : r1.y; + + return vector2_type((xu - rect.r0.x) / rectangleExtents.x, (yv - rect.r0.y) / rectangleExtents.y); + } + + shapes::SphericalRectangle rect; +}; + +} +} +} + +#endif diff --git a/include/nbl/builtin/hlsl/shapes/rectangle.hlsl b/include/nbl/builtin/hlsl/shapes/rectangle.hlsl index 854a326aaf..a61f23cafa 100644 --- a/include/nbl/builtin/hlsl/shapes/rectangle.hlsl +++ b/include/nbl/builtin/hlsl/shapes/rectangle.hlsl @@ -24,13 +24,22 @@ struct SphericalRectangle using vector4_type = vector; using matrix3x3_type = matrix; + static SphericalRectangle create(NBL_CONST_REF_ARG(vector3_type) observer, NBL_CONST_REF_ARG(vector3_type) rectangleOrigin, NBL_CONST_REF_ARG(matrix3x3_type) basis) + { + SphericalRectangle retval; + retval.r0 = nbl::hlsl::mul(basis, rectangleOrigin - observer); + return retval; + } + static SphericalRectangle create(NBL_CONST_REF_ARG(vector3_type) observer, NBL_CONST_REF_ARG(vector3_type) rectangleOrigin, NBL_CONST_REF_ARG(vector3_type) T, NBL_CONST_REF_ARG(vector3_type) B, NBL_CONST_REF_ARG(vector3_type) N) { + SphericalRectangle retval; matrix3x3_type TBN = nbl::hlsl::transpose(matrix3x3_type(T, B, isotropic_type::N)); - return nbl::hlsl::mul(TBN, rectangleOrigin - observer); + retval.r0 = nbl::hlsl::mul(TBN, rectangleOrigin - observer); + return retval; } - scalar_type solidAngleOfRectangle(NBL_CONST_REF_ARG(vector3_type) r0, NBL_CONST_REF_ARG(vector) rectangleExtents) + scalar_type solidAngleOfRectangle(NBL_CONST_REF_ARG(vector) rectangleExtents) { const vector4_type denorm_n_z = vector4_type(-r0.y, r0.x + rectangleExtents.x, r0.y + rectangleExtents.y, -r0.x); const vector4_type n_z = denorm_n_z / nbl::hlsl::sqrt((vector4_type)(r0.z * r0.z) + denorm_n_z * denorm_n_z); @@ -42,6 +51,8 @@ struct SphericalRectangle ); return math::getSumofArccosABCD(cosGamma[0], cosGamma[1], cosGamma[2], cosGamma[3]) - 2 * numbers::pi; } + + vector3_type r0; } } diff --git a/include/nbl/builtin/hlsl/shapes/triangle.hlsl b/include/nbl/builtin/hlsl/shapes/triangle.hlsl index f7ce67a1c9..59ba508596 100644 --- a/include/nbl/builtin/hlsl/shapes/triangle.hlsl +++ b/include/nbl/builtin/hlsl/shapes/triangle.hlsl @@ -49,7 +49,7 @@ struct SphericalTriangle cos_c = cos_sides[2]; csc_b = csc_sides[1]; csc_c = csc_sides[2]; - + // Both vertices and angles at the vertices are denoted by the same upper case letters A, B, and C. The angles A, B, C of the triangle are equal to the angles between the planes that intersect the surface of the sphere or, equivalently, the angles between the tangent vectors of the great circle arcs where they meet at the vertices. Angles are in radians. The angles of proper spherical triangles are (by convention) less than PI cos_vertices = clamp((cos_sides - cos_sides.yzx * cos_sides.zxy) * csc_sides.yzx * csc_sides.zxy, (vector3_type)(-1.f), (vector3_type)1.f); // using Spherical Law of Cosines (TODO: do we need to clamp anymore? since the pyramid angles method introduction?) sin_vertices = sqrt((vector3_type)1.f - cos_vertices * cos_vertices); diff --git a/src/nbl/builtin/CMakeLists.txt b/src/nbl/builtin/CMakeLists.txt index 5cc0108874..82d081138a 100644 --- a/src/nbl/builtin/CMakeLists.txt +++ b/src/nbl/builtin/CMakeLists.txt @@ -321,6 +321,7 @@ LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/box_muller_transform LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/cos_weighted.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/spherical_triangle.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/projected_spherical_triangle.hlsl") +LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/spherical_rectangle.hlsl") LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/sampling/uniform.hlsl") # LIST_BUILTIN_RESOURCE(NBL_RESOURCES_TO_EMBED "hlsl/ndarray_addressing.hlsl") From 11180f45db44a5599bbaa08f342686cce315713e Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 17 Feb 2025 16:58:42 +0700 Subject: [PATCH 06/23] fix aniso cache bug --- examples_tests | 2 +- include/nbl/builtin/hlsl/bxdf/common.hlsl | 9 +++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/examples_tests b/examples_tests index 83d8a92584..159d1533e8 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 83d8a92584c28d9ad31c9853f6abb59922bc2249 +Subproject commit 159d1533e8d82e3c5e82165e8b79ea67c0f23111 diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 050366c6dc..71bde312fe 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -610,6 +610,7 @@ struct SAnisotropicMicrofacetCache : SIsotropicMicrofacetCache using ray_dir_info_type = ray_dir_info::SBasic; using anisotropic_type = surface_interactions::SAnisotropic; + using isocache_type = SIsotropicMicrofacetCache; using sample_type = SLightSample; // always valid by construction @@ -671,7 +672,9 @@ struct SAnisotropicMicrofacetCache : SIsotropicMicrofacetCache const scalar_type orientedEta, const scalar_type rcpOrientedEta, NBL_REF_ARG(vector3_type) H ) { - const bool valid = this_t::compute(retval,transmitted,V,L,N,NdotL,VdotL,orientedEta,rcpOrientedEta,H); + isocache_type iso = (isocache_type)retval; + const bool valid = isocache_type::compute(iso,transmitted,V,L,N,NdotL,VdotL,orientedEta,rcpOrientedEta,H); + retval = (this_t)iso; if (valid) { retval.TdotH = nbl::hlsl::dot(T,H); @@ -687,8 +690,10 @@ struct SAnisotropicMicrofacetCache : SIsotropicMicrofacetCache const scalar_type eta ) { + isocache_type iso = (isocache_type)retval; vector3_type H; - const bool valid = this_t::compute(retval,interaction,_sample,eta,H); + const bool valid = isocache_type::compute(iso,interaction,_sample,eta,H); + retval = (this_t)iso; if (valid) { retval.TdotH = nbl::hlsl::dot(interaction.T,H); From 451605197b486b8da5970d10274f63825c407256 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 18 Feb 2025 15:24:42 +0700 Subject: [PATCH 07/23] init func to modify bxdf params directly --- examples_tests | 2 +- include/nbl/builtin/hlsl/bxdf/common.hlsl | 9 +++-- include/nbl/builtin/hlsl/bxdf/reflection.hlsl | 34 +++++++++++++++--- .../nbl/builtin/hlsl/bxdf/transmission.hlsl | 36 ++++++++++++++++--- 4 files changed, 66 insertions(+), 15 deletions(-) diff --git a/examples_tests b/examples_tests index 159d1533e8..a7350db7d7 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 159d1533e8d82e3c5e82165e8b79ea67c0f23111 +Subproject commit a7350db7d7e422fa5086982b3327103c06cfbe44 diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 71bde312fe..f4ae69aafc 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -987,11 +987,10 @@ template Axy; - Spectrum ior0; - Spectrum ior1; - Scalar eta; + vector A; // roughness + Spectrum ior0; // source ior + Spectrum ior1; // destination ior + Scalar eta; // in most cases, eta will be calculated from ior0 and ior1; see monochromeEta in pathtracer.hlsl Spectrum eta2; Spectrum luminosityContributionHint; }; diff --git a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl index b074bcaddb..76d00c268c 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl @@ -64,6 +64,11 @@ struct SLambertianBxDF return create(); } + void init(SBxDFCreationParams params) + { + // do nothing + } + scalar_type __eval_pi_factored_out(scalar_type maxNdotL) { return maxNdotL; @@ -124,7 +129,12 @@ struct SOrenNayarBxDF static this_t create(SBxDFCreationParams params) { - return create(params.A); + return create(params.A.x); + } + + void init(SBxDFCreationParams params) + { + A = params.A.x; } scalar_type __rec_pi_factored_out_wo_clamps(scalar_type VdotL, scalar_type maxNdotL, scalar_type maxNdotV) @@ -355,9 +365,16 @@ struct SBeckmannBxDF static this_t create(SBxDFCreationParams params) { if (params.is_aniso) - return create(params.Axy.x, params.Axy.y, params.ior0, params.ior1); + return create(params.A.x, params.A.y, params.ior0, params.ior1); else - return create(params.A, params.ior0, params.ior1); + return create(params.A.x, params.ior0, params.ior1); + } + + void init(SBxDFCreationParams params) + { + A = params.A; + ior0 = params.ior0; + ior1 = params.ior1; } scalar_type __eval_DG_wo_clamps(params_t params) @@ -591,9 +608,16 @@ struct SGGXBxDF static this_t create(SBxDFCreationParams params) { if (params.is_aniso) - return create(params.Axy.x, params.Axy.y, params.ior0, params.ior1); + return create(params.A.x, params.A.y, params.ior0, params.ior1); else - return create(params.A, params.ior0, params.ior1); + return create(params.A.x, params.ior0, params.ior1); + } + + void init(SBxDFCreationParams params) + { + A = params.A; + ior0 = params.ior0; + ior1 = params.ior1; } scalar_type __eval_DG_wo_clamps(params_t params) diff --git a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl index 18d80e93aa..99e7e5f6a8 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl @@ -68,6 +68,11 @@ struct SLambertianBxDF return create(); } + void init(SBxDFCreationParams params) + { + // do nothing + } + scalar_type __eval_pi_factored_out(scalar_type absNdotL) { return absNdotL; @@ -134,6 +139,11 @@ struct SSmoothDielectricBxDF return create(params.eta); } + void init(SBxDFCreationParams params) + { + eta = params.eta; + } + spectral_type eval(params_t params) { return (spectral_type)0; @@ -220,6 +230,12 @@ struct SSmoothDielectricBxDF return create(params.eta2, params.luminosityContributionHint); } + void init(SBxDFCreationParams params) + { + eta2 = params.eta2; + luminosityContributionHint = params.luminosityContributionHint; + } + spectral_type eval(params_t params) { return (spectral_type)0; @@ -317,9 +333,15 @@ struct SBeckmannDielectricBxDF static this_t create(SBxDFCreationParams params) { if (params.is_aniso) - return create(params.eta, params.Axy.x, params.Axy.y); + return create(params.eta, params.A.x, params.A.y); else - return create(params.eta, params.A); + return create(params.eta, params.A.x); + } + + void init(SBxDFCreationParams params) + { + A = params.A; + eta = params.eta; } spectral_type eval(params_t params) @@ -492,9 +514,15 @@ struct SGGXDielectricBxDF static this_t create(SBxDFCreationParams params) { if (params.is_aniso) - return create(params.eta, params.Axy.x, params.Axy.y); + return create(params.eta, params.A.x, params.A.y); else - return create(params.eta, params.A); + return create(params.eta, params.A.x); + } + + void init(SBxDFCreationParams params) + { + A = params.A; + eta = params.eta; } spectral_type eval(params_t params) From d9a00c9998e9ec33a1cdcbf132bcbf5c1dfc7652 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 20 Feb 2025 16:55:35 +0700 Subject: [PATCH 08/23] bug fixes --- examples_tests | 2 +- .../nbl/builtin/hlsl/bxdf/bxdf_traits.hlsl | 2 +- include/nbl/builtin/hlsl/bxdf/common.hlsl | 2 +- include/nbl/builtin/hlsl/bxdf/geom_smith.hlsl | 4 ++-- include/nbl/builtin/hlsl/bxdf/reflection.hlsl | 8 +++---- .../nbl/builtin/hlsl/bxdf/transmission.hlsl | 9 +++++--- .../hlsl/sampling/box_muller_transform.hlsl | 2 +- .../hlsl/sampling/concentric_mapping.hlsl | 2 +- .../projected_spherical_triangle.hlsl | 12 +++++----- .../hlsl/sampling/spherical_triangle.hlsl | 2 +- .../nbl/builtin/hlsl/shapes/rectangle.hlsl | 22 +++++++++---------- include/nbl/builtin/hlsl/shapes/triangle.hlsl | 4 ++-- 12 files changed, 37 insertions(+), 34 deletions(-) diff --git a/examples_tests b/examples_tests index a7350db7d7..2f77555ce4 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit a7350db7d7e422fa5086982b3327103c06cfbe44 +Subproject commit 2f77555ce484c2f8ecb390e68fc3f4c830b23ef7 diff --git a/include/nbl/builtin/hlsl/bxdf/bxdf_traits.hlsl b/include/nbl/builtin/hlsl/bxdf/bxdf_traits.hlsl index e63cf0113e..78b23830bc 100644 --- a/include/nbl/builtin/hlsl/bxdf/bxdf_traits.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/bxdf_traits.hlsl @@ -101,4 +101,4 @@ struct bxdf_traits > } } -#endif \ No newline at end of file +#endif diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index f4ae69aafc..6acdbab74b 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -874,7 +874,7 @@ struct SBxDFParams return retval; } - template && surface_interactions::Anisotropic) + template && surface_interactions::Anisotropic) static SBxDFParams create(LightSample _sample, Aniso interaction, BxDFClampMode clamp = BCM_NONE) { this_t retval; diff --git a/include/nbl/builtin/hlsl/bxdf/geom_smith.hlsl b/include/nbl/builtin/hlsl/bxdf/geom_smith.hlsl index 61aa10399c..5a6f6cdf26 100644 --- a/include/nbl/builtin/hlsl/bxdf/geom_smith.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/geom_smith.hlsl @@ -236,12 +236,12 @@ struct GGX scalar_type G1_wo_numerator(scalar_type NdotX, scalar_type NdotX2, scalar_type a2, scalar_type one_minus_a2) { - return 1.0 / (NdotX + ggx_devsh_part(NdotX2,a2,one_minus_a2)); + return 1.0 / (NdotX + devsh_part(NdotX2,a2,one_minus_a2)); } scalar_type G1_wo_numerator(scalar_type NdotX, scalar_type TdotX2, scalar_type BdotX2, scalar_type NdotX2, scalar_type ax2, scalar_type ay2) { - return 1.0 / (NdotX + ggx_devsh_part(TdotX2, BdotX2, NdotX2, ax2, ay2)); + return 1.0 / (NdotX + devsh_part(TdotX2, BdotX2, NdotX2, ax2, ay2)); } scalar_type G1_wo_numerator(scalar_type NdotX, scalar_type devsh_part) diff --git a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl index 76d00c268c..8f4da11b05 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl @@ -232,7 +232,7 @@ struct SBlinnPhongBxDF ndf::SAnisotropicParams ndfparams = ndf::SAnisotropicParams::create(params.NdotH, 1.0 / (1.0 - params.NdotH2), params.TdotH2, params.BdotH2, n.x, n.y); ndf::BlinnPhong blinn_phong; scalar_type DG = blinn_phong(ndfparams); - if (any>(a2 > (vector2_type)numeric_limits::min)) + if (any >(a2 > (vector2_type)numeric_limits::min)) { smith::SAnisotropicParams smithparams = smith::SAnisotropicParams::create(a2.x, a2.y, params.TdotV2, params.BdotV2, params.NdotV2, params.TdotL2, params.BdotL2, params.NdotL2, 0); smith::Beckmann beckmann; @@ -245,7 +245,7 @@ struct SBlinnPhongBxDF ndf::SIsotropicParams ndfparams = ndf::SIsotropicParams::create(n, params.NdotH, params.NdotH2); ndf::BlinnPhong blinn_phong; scalar_type NG = blinn_phong(ndfparams); - if (any>(a2 > (vector2_type)numeric_limits::min)) + if (any >(a2 > (vector2_type)numeric_limits::min)) { smith::SIsotropicParams smithparams = smith::SIsotropicParams::create(a2.x, params.NdotV2, params.NdotL2, 0); smith::Beckmann beckmann; @@ -386,7 +386,7 @@ struct SBeckmannBxDF ndf::SAnisotropicParams ndfparams = ndf::SAnisotropicParams::create(A.x, A.y, ax2, ay2, params.TdotH2, params.BdotH2, params.NdotH2); ndf::Beckmann beckmann_ndf; scalar_type NG = beckmann_ndf(ndfparams); - if (any>(A > (vector2_type)numeric_limits::min)) + if (any >(A > (vector2_type)numeric_limits::min)) { smith::SAnisotropicParams smithparams = smith::SAnisotropicParams::create(ax2, ay2, params.TdotV2, params.BdotV2, params.NdotV2, params.TdotL2, params.BdotL2, params.NdotL2, 0); smith::Beckmann beckmann_smith; @@ -629,7 +629,7 @@ struct SGGXBxDF ndf::SAnisotropicParams ndfparams = ndf::SAnisotropicParams::create(A.x, A.y, ax2, ay2, params.TdotH2, params.BdotH2, params.NdotH2); ndf::GGX ggx_ndf; scalar_type NG = ggx_ndf(ndfparams); - if (any>(A > (vector2_type)numeric_limits::min)) + if (any >(A > (vector2_type)numeric_limits::min)) { smith::SAnisotropicParams smithparams = smith::SAnisotropicParams::create(ax2, ay2, params.NdotV, params.TdotV2, params.BdotV2, params.NdotV2, params.NdotL, params.TdotL2, params.BdotL2, params.NdotL2); smith::GGX ggx_smith; diff --git a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl index 99e7e5f6a8..1d6bf8ead6 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl @@ -110,8 +110,11 @@ struct SLambertianBxDF // microfacet bxdfs -template && IsotropicMicrofacetCache && AnisotropicMicrofacetCache) -struct SSmoothDielectricBxDF +template // NBL_FUNC_REQUIRES(Sample && IsotropicMicrofacetCache && AnisotropicMicrofacetCache) // dxc won't let me put this in +struct SSmoothDielectricBxDF; + +template +struct SSmoothDielectricBxDF { using this_t = SSmoothDielectricBxDF; using scalar_type = typename LightSample::scalar_type; @@ -200,7 +203,7 @@ struct SSmoothDielectricBxDF scalar_type eta; }; -template && IsotropicMicrofacetCache && AnisotropicMicrofacetCache) +template struct SSmoothDielectricBxDF { using this_t = SSmoothDielectricBxDF; diff --git a/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl b/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl index efa8d66e2b..57a18589fd 100644 --- a/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl +++ b/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl @@ -24,4 +24,4 @@ vector boxMullerTransform(vector xi, T stddev) } } -#endif \ No newline at end of file +#endif diff --git a/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl b/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl index 2b06581740..60865e7c8e 100644 --- a/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl +++ b/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl @@ -39,4 +39,4 @@ vector concentricMapping(vector _u) } } -#endif \ No newline at end of file +#endif diff --git a/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl b/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl index 5832e9aab2..945ca053b8 100644 --- a/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl +++ b/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl @@ -25,14 +25,14 @@ struct ProjectedSphericalTriangle using vector3_type = vector; using vector4_type = vector; - static ProjectedSphericalTriangle create(NBL_CONST_REG_ARG(shapes::SphericalTriangle) tri) + static ProjectedSphericalTriangle create(NBL_CONST_REF_ARG(shapes::SphericalTriangle) tri) { ProjectedSphericalTriangle retval; retval.tri = tri; return retval; } - vector4_type computeBilinearPatch(NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool isBSDF) + vector4_type computeBilinearPatch(NBL_CONST_REF_ARG(vector3_type) receiverNormal, bool isBSDF) { const scalar_type minimumProjSolidAngle = 0.0; @@ -42,7 +42,7 @@ struct ProjectedSphericalTriangle return bxdfPdfAtVertex.yyxz; } - vector3_type generate(NBL_REG_ARG(scalar_type) rcpPdf, scalar_type solidAngle, NBL_CONST_REG_ARG(vector3_type) cos_vertices, NBL_CONST_REG_ARG(vector3_type) sin_vertices, scalar_type cos_a, scalar_type cos_c, scalar_type csc_b, scalar_type csc_c, NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool isBSDF, NBL_CONST_REG_ARG(vector2_type) u) + 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) { // pre-warp according to proj solid angle approximation vector4_type patch = computeBilinearPatch(receiverNormal, isBSDF); @@ -56,7 +56,7 @@ struct ProjectedSphericalTriangle return L; } - vector3_type generate(NBL_REG_ARG(scalar_type) rcpPdf, NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool isBSDF, NBL_CONST_REG_ARG(vector2_type) u) + 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; @@ -64,7 +64,7 @@ struct ProjectedSphericalTriangle 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_REG_ARG(vector3_type) cos_vertices, NBL_CONST_REG_ARG(vector3_type) sin_vertices, scalar_type cos_a, scalar_type cos_c, scalar_type csc_b, scalar_type csc_c, NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool receiverWasBSDF, NBL_CONST_REG_ARG(vector3_type) L) + 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 = tri.generateInverse(pdf, solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, L); @@ -74,7 +74,7 @@ struct ProjectedSphericalTriangle return pdf * bilinear.pdf(u); } - scalar_type pdf(NBL_CONST_REG_ARG(vector3_type) receiverNormal, bool receiverWasBSDF, NBL_CONST_REG_ARG(vector3_type) L) + 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 = tri.generateInverse(pdf, L); diff --git a/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl b/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl index 9501cdc3d1..1d4fda454d 100644 --- a/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl +++ b/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl @@ -24,7 +24,7 @@ struct SphericalTriangle using vector2_type = vector; using vector3_type = vector; - static SphericalTriangle create(NBL_CONST_REG_ARG(shapes::SphericalTriangle) tri) + static SphericalTriangle create(NBL_CONST_REF_ARG(shapes::SphericalTriangle) tri) { SphericalTriangle retval; retval.tri = tri; diff --git a/include/nbl/builtin/hlsl/shapes/rectangle.hlsl b/include/nbl/builtin/hlsl/shapes/rectangle.hlsl index a61f23cafa..47d3927f31 100644 --- a/include/nbl/builtin/hlsl/shapes/rectangle.hlsl +++ b/include/nbl/builtin/hlsl/shapes/rectangle.hlsl @@ -16,25 +16,25 @@ namespace hlsl namespace shapes { -template +template struct SphericalRectangle { - using scalar_type = T; - using vector3_type = vector; - using vector4_type = vector; - using matrix3x3_type = matrix; + using scalar_type = Scalar; + using vector3_type = vector; + using vector4_type = vector; + using matrix3x3_type = matrix; - static SphericalRectangle create(NBL_CONST_REF_ARG(vector3_type) observer, NBL_CONST_REF_ARG(vector3_type) rectangleOrigin, NBL_CONST_REF_ARG(matrix3x3_type) basis) + static SphericalRectangle create(NBL_CONST_REF_ARG(vector3_type) observer, NBL_CONST_REF_ARG(vector3_type) rectangleOrigin, NBL_CONST_REF_ARG(matrix3x3_type) basis) { - SphericalRectangle retval; + SphericalRectangle retval; retval.r0 = nbl::hlsl::mul(basis, rectangleOrigin - observer); return retval; } - static SphericalRectangle create(NBL_CONST_REF_ARG(vector3_type) observer, NBL_CONST_REF_ARG(vector3_type) rectangleOrigin, NBL_CONST_REF_ARG(vector3_type) T, NBL_CONST_REF_ARG(vector3_type) B, NBL_CONST_REF_ARG(vector3_type) N) + static SphericalRectangle create(NBL_CONST_REF_ARG(vector3_type) observer, NBL_CONST_REF_ARG(vector3_type) rectangleOrigin, NBL_CONST_REF_ARG(vector3_type) T, NBL_CONST_REF_ARG(vector3_type) B, NBL_CONST_REF_ARG(vector3_type) N) { - SphericalRectangle retval; - matrix3x3_type TBN = nbl::hlsl::transpose(matrix3x3_type(T, B, isotropic_type::N)); + SphericalRectangle retval; + matrix3x3_type TBN = nbl::hlsl::transpose(matrix3x3_type(T, B, N)); retval.r0 = nbl::hlsl::mul(TBN, rectangleOrigin - observer); return retval; } @@ -53,7 +53,7 @@ struct SphericalRectangle } vector3_type r0; -} +}; } } diff --git a/include/nbl/builtin/hlsl/shapes/triangle.hlsl b/include/nbl/builtin/hlsl/shapes/triangle.hlsl index 59ba508596..d904ed7246 100644 --- a/include/nbl/builtin/hlsl/shapes/triangle.hlsl +++ b/include/nbl/builtin/hlsl/shapes/triangle.hlsl @@ -80,8 +80,8 @@ struct SphericalTriangle // TODO: above dot products are in the wrong order, either work out which is which, or try all 6 permutations till it works cos_vertices = nbl::hlsl::clamp((cos_sides - cos_sides.yzx * cos_sides.zxy) * csc_sides.yzx * csc_sides.zxy, (vector3_type)(-1.f), (vector3_type)1.f); - matrix mat = - const vector3_type externalProducts = nbl::hlsl::abs(nbl::hlsl::transpose(awayFromEdgePlane) * receiverNormal); + matrix awayFromEdgePlane = matrix(awayFromEdgePlane0, awayFromEdgePlane1, awayFromEdgePlane2); + const vector3_type externalProducts = nbl::hlsl::abs(/* transposed already */awayFromEdgePlane * receiverNormal); const vector3_type pyramidAngles = acos(cos_sides); return nbl::hlsl::dot(pyramidAngles, externalProducts) / (2.f * numbers::pi); From ffe9029c78af7b2d1bf4d77cbf900d632960edd9 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 21 Feb 2025 14:16:59 +0700 Subject: [PATCH 09/23] fix sampling bugs #2 --- examples_tests | 2 +- include/nbl/builtin/hlsl/sampling/bilinear.hlsl | 2 +- include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl | 2 +- include/nbl/builtin/hlsl/sampling/linear.hlsl | 4 ++-- .../builtin/hlsl/sampling/projected_spherical_triangle.hlsl | 1 + include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl | 2 +- 6 files changed, 7 insertions(+), 6 deletions(-) diff --git a/examples_tests b/examples_tests index 2f77555ce4..99aed4777c 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 2f77555ce484c2f8ecb390e68fc3f4c830b23ef7 +Subproject commit 99aed4777c208c5acc4e66bb7ea8dc48f814c8d0 diff --git a/include/nbl/builtin/hlsl/sampling/bilinear.hlsl b/include/nbl/builtin/hlsl/sampling/bilinear.hlsl index 1d5f9a91e8..3542e2dfef 100644 --- a/include/nbl/builtin/hlsl/sampling/bilinear.hlsl +++ b/include/nbl/builtin/hlsl/sampling/bilinear.hlsl @@ -31,7 +31,7 @@ struct Bilinear return retval; } - vector2_type generate(NBL_REG_ARG(scalar_type) rcpPdf, NBL_CONST_REF_ARG(vector2_type) u) + vector2_type generate(NBL_REF_ARG(scalar_type) rcpPdf, NBL_CONST_REF_ARG(vector2_type) u) { const vector2_type twiceAreasUnderXCurve = vector2_type(bilinearCoeffs[0] + bilinearCoeffs[1], bilinearCoeffs[2] + bilinearCoeffs[3]); Linear lineary = Linear::create(twiceAreasUnderXCurve); diff --git a/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl b/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl index 57a18589fd..dcac2279be 100644 --- a/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl +++ b/include/nbl/builtin/hlsl/sampling/box_muller_transform.hlsl @@ -17,7 +17,7 @@ template vector boxMullerTransform(vector xi, T stddev) { T sinPhi, cosPhi; - nbl::hlsl::sincos(2.0 * numbers::pi * xi.y - numbers::pi, sinPhi, cosPhi); + math::sincos(2.0 * numbers::pi * xi.y - numbers::pi, sinPhi, cosPhi); return vector(cosPhi, sinPhi) * nbl::hlsl::sqrt(-2.0 * nbl::hlsl::log(xi.x)) * stddev; } diff --git a/include/nbl/builtin/hlsl/sampling/linear.hlsl b/include/nbl/builtin/hlsl/sampling/linear.hlsl index 8b9b3fb058..12d445eefe 100644 --- a/include/nbl/builtin/hlsl/sampling/linear.hlsl +++ b/include/nbl/builtin/hlsl/sampling/linear.hlsl @@ -2,8 +2,8 @@ // 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_ +#ifndef _NBL_BUILTIN_HLSL_SAMPLING_LINEAR_INCLUDED_ +#define _NBL_BUILTIN_HLSL_SAMPLING_LINEAR_INCLUDED_ #include #include diff --git a/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl b/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl index 945ca053b8..cfc96dc9cb 100644 --- a/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl +++ b/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl @@ -8,6 +8,7 @@ #include #include #include +#include #include namespace nbl diff --git a/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl b/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl index 83224bfabd..c42bf8e464 100644 --- a/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl +++ b/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl @@ -25,7 +25,7 @@ struct SphericalRectangle using vector3_type = vector; using vector4_type = vector; - static SphericalRectangle create(NBL_CONST_REG_ARG(shapes::SphericalRectangle) rect) + static SphericalRectangle create(NBL_CONST_REF_ARG(shapes::SphericalRectangle) rect) { SphericalRectangle retval; retval.rect = rect; From b2073128e066d3c068362c9b505a2fe14e1f43fb Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 21 Feb 2025 16:57:49 +0700 Subject: [PATCH 10/23] fix rank type trait for matrix/vector --- examples_tests | 2 +- include/nbl/builtin/hlsl/type_traits.hlsl | 14 +++++++++++++- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/examples_tests b/examples_tests index a1a8ec03bc..a802a97943 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit a1a8ec03bcc90c0f46ffba6d7c50e05a633834b4 +Subproject commit a802a97943bd9e17187a306f8058c21d2774678b diff --git a/include/nbl/builtin/hlsl/type_traits.hlsl b/include/nbl/builtin/hlsl/type_traits.hlsl index 3443a9d9b7..17d0ed827e 100644 --- a/include/nbl/builtin/hlsl/type_traits.hlsl +++ b/include/nbl/builtin/hlsl/type_traits.hlsl @@ -612,7 +612,19 @@ NBL_CONSTEXPR bool is_matrix_v = is_matrix::value; #ifdef __HLSL_VERSION template -struct rank : integral_constant::value ? 2 : (is_vector::value ? 1 : 0)> { }; +struct rank : integral_constant, + uint64_t, + 2ull, + conditional_value< + is_vector_v, + uint64_t, + 1ull, + 0ull + >::value + >::value +> { }; template struct rank : integral_constant::value> { }; From 69a257d878df518902acd56b3be52e8a28c35337 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 25 Feb 2025 16:57:01 +0700 Subject: [PATCH 11/23] temporary fix for dxc bug issue 7154 --- examples_tests | 2 +- include/nbl/builtin/hlsl/bxdf/common.hlsl | 38 +++++++++++------------ include/nbl/builtin/hlsl/limits.hlsl | 4 +-- 3 files changed, 22 insertions(+), 22 deletions(-) diff --git a/examples_tests b/examples_tests index 3827fd3c33..f97757bffc 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 3827fd3c330eaac4c11478330cfb0f4a362f99c6 +Subproject commit f97757bffcc28ad208a10dfb485214b8d9e1fdd1 diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 6acdbab74b..6e5174f73c 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -312,8 +312,8 @@ NBL_CONCEPT_END( ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((T::createFromTangentSpace(pV,rdirinfo,frame)), ::nbl::hlsl::is_same_v, T)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((T::create(rdirinfo,pVdotL,pV)), ::nbl::hlsl::is_same_v, T)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((T::create(rdirinfo,pVdotL,pV,pV,pV)), ::nbl::hlsl::is_same_v, T)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((T::template create(pV,iso)), ::nbl::hlsl::is_same_v, T)) - ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((T::template create(pV,aniso)), ::nbl::hlsl::is_same_v, T)) + //((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((T::template create(pV,iso)), ::nbl::hlsl::is_same_v, T)) // NOTE: temporarily commented out due to dxc bug https://github.com/microsoft/DirectXShaderCompiler/issues/7154 + //((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((T::template create(pV,aniso)), ::nbl::hlsl::is_same_v, T)) ((NBL_CONCEPT_REQ_EXPR_RET_TYPE)((_sample.getTangentSpaceL()), ::nbl::hlsl::is_same_v, typename T::vector3_type)) ) && surface_interactions::Anisotropic && surface_interactions::Isotropic && ray_dir_info::Basic; @@ -380,21 +380,21 @@ struct SLightSample return retval; } - // overloads for surface_interactions - template - static this_t create(NBL_CONST_REF_ARG(vector3_type) L, NBL_CONST_REF_ARG(surface_interactions::SIsotropic) interaction) - { - const vector3_type V = interaction.V.getDirection(); - const scalar_type VdotL = nbl::hlsl::dot(V,L); - return create(L, VdotL, interaction.N); - } - template - static this_t create(NBL_CONST_REF_ARG(vector3_type) L, NBL_CONST_REF_ARG(surface_interactions::SAnisotropic) interaction) - { - const vector3_type V = interaction.V.getDirection(); - const scalar_type VdotL = nbl::hlsl::dot(V,L); - return create(L,VdotL,interaction.T,interaction.B,interaction.N); - } + // overloads for surface_interactions, NOTE: temporarily commented out due to dxc bug https://github.com/microsoft/DirectXShaderCompiler/issues/7154 + // template + // static this_t create(NBL_CONST_REF_ARG(vector3_type) L, NBL_CONST_REF_ARG(surface_interactions::SIsotropic) interaction) + // { + // const vector3_type V = interaction.V.getDirection(); + // const scalar_type VdotL = nbl::hlsl::dot(V,L); + // return create(L, VdotL, interaction.N); + // } + // template + // static this_t create(NBL_CONST_REF_ARG(vector3_type) L, NBL_CONST_REF_ARG(surface_interactions::SAnisotropic) interaction) + // { + // const vector3_type V = interaction.V.getDirection(); + // const scalar_type VdotL = nbl::hlsl::dot(V,L); + // return create(L,VdotL,interaction.T,interaction.B,interaction.N); + // } // vector3_type getTangentSpaceL() NBL_CONST_MEMBER_FUNC { @@ -875,7 +875,7 @@ struct SBxDFParams } template && surface_interactions::Anisotropic) - static SBxDFParams create(LightSample _sample, Aniso interaction, BxDFClampMode clamp = BCM_NONE) + static this_t create(LightSample _sample, Aniso interaction, BxDFClampMode clamp = BCM_NONE) { this_t retval; retval.NdotV = clamp == BCM_ABS ? abs(interaction.NdotV) : @@ -922,7 +922,7 @@ struct SBxDFParams } template && surface_interactions::Anisotropic && AnisotropicMicrofacetCache) - static SBxDFParams create(LightSample _sample, Aniso interaction, Cache cache, BxDFClampMode clamp = BCM_NONE) + static this_t create(LightSample _sample, Aniso interaction, Cache cache, BxDFClampMode clamp = BCM_NONE) { this_t retval; retval.NdotH = cache.NdotH; diff --git a/include/nbl/builtin/hlsl/limits.hlsl b/include/nbl/builtin/hlsl/limits.hlsl index 146957dc3e..5fe682c9e3 100644 --- a/include/nbl/builtin/hlsl/limits.hlsl +++ b/include/nbl/builtin/hlsl/limits.hlsl @@ -129,7 +129,7 @@ struct num_base : type_identity NBL_CONSTEXPR_STATIC_INLINE int32_t float_max_decimal_exponent = 4*S16 + 30*S32 + 232*S64; NBL_CONSTEXPR_STATIC_INLINE int32_t float_exponent_bits = 8 * size - 1 - (float_digits-1); - NBL_CONSTEXPR_STATIC_INLINE int32_t float_max_exponent = 1 << (float_exponent_bits-1); + NBL_CONSTEXPR_STATIC_INLINE int32_t float_max_exponent = int32_t(1) << (float_exponent_bits-1); NBL_CONSTEXPR_STATIC_INLINE int32_t float_min_exponent = 3 - float_max_exponent; NBL_CONSTEXPR_STATIC_INLINE bool is_bool = is_same::value; @@ -146,7 +146,7 @@ struct num_base : type_identity // (TODO) think about what this means for HLSL // identifies floating-point types that can represent the special value "quiet not-a-number" (NaN) - NBL_CONSTEXPR_STATIC_INLINE bool has_quiet_NaN = !is_integer; + NBL_CONSTEXPR_STATIC_INLINE bool has_quiet_NaN = !is_integer; // identifies floating-point types that can represent the special value "signaling not-a-number" (NaN) NBL_CONSTEXPR_STATIC_INLINE bool has_signaling_NaN = !is_integer; // identifies the denormalization style used by the floating-point type From 866e6d7f15ce25e0573341a5d8631354f5b081a0 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Wed, 26 Feb 2025 16:55:23 +0700 Subject: [PATCH 12/23] some bug fixes again --- examples_tests | 2 +- include/nbl/builtin/hlsl/bxdf/reflection.hlsl | 20 ++++++------ .../nbl/builtin/hlsl/bxdf/transmission.hlsl | 32 +++++++++---------- .../nbl/builtin/hlsl/sampling/bilinear.hlsl | 3 +- .../hlsl/sampling/concentric_mapping.hlsl | 2 +- .../projected_spherical_triangle.hlsl | 12 ++++--- .../hlsl/sampling/spherical_rectangle.hlsl | 2 +- .../nbl/builtin/hlsl/shapes/rectangle.hlsl | 2 +- include/nbl/builtin/hlsl/shapes/triangle.hlsl | 2 +- 9 files changed, 40 insertions(+), 37 deletions(-) diff --git a/examples_tests b/examples_tests index f97757bffc..8e759f24d5 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit f97757bffcc28ad208a10dfb485214b8d9e1fdd1 +Subproject commit 8e759f24d5b386291660f50af1c04efbff3eff08 diff --git a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl index 8f4da11b05..4609216144 100644 --- a/include/nbl/builtin/hlsl/bxdf/reflection.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/reflection.hlsl @@ -18,13 +18,13 @@ namespace reflection { // still need these? -template && surface_interactions::Isotropic && surface_interactions::Anisotropic && ray_dir_info::Basic && is_scalar_v) LightSample cos_generate(NBL_CONST_REF_ARG(Iso) interaction) { return LightSample(interaction.V.reflect(interaction.N,interaction.NdotV),interaction.NdotV,interaction.N); } -template && surface_interactions::Isotropic && surface_interactions::Anisotropic && ray_dir_info::Basic && is_scalar_v) LightSample cos_generate(NBL_CONST_REF_ARG(Aniso) interaction) { @@ -441,14 +441,14 @@ struct SBeckmannBxDF scalar_type sinTheta = sqrt(1.0 - cosTheta * cosTheta); scalar_type tanTheta = sinTheta / cosTheta; scalar_type cotTheta = 1.0 / tanTheta; - + scalar_type a = -1.0; scalar_type c = erf(cosTheta); scalar_type sample_x = max(u.x, 1.0e-6); scalar_type theta = acos(cosTheta); scalar_type fit = 1.0 + theta * (-0.876 + theta * (0.4265 - 0.0594*theta)); scalar_type b = c - (1.0 + c) * pow(1.0-sample_x, fit); - + scalar_type normalization = 1.0 / (1.0 + c + numbers::inv_sqrtpi * tanTheta * exp(-cosTheta*cosTheta)); const int ITER_THRESHOLD = 10; @@ -475,7 +475,7 @@ struct SBeckmannBxDF slope.x = erfInv(b); slope.y = erfInv(2.0 * max(u.y, 1.0e-6) - 1.0); } - + scalar_type sinTheta = sqrt(1.0 - V.z*V.z); scalar_type cosPhi = sinTheta==0.0 ? 1.0 : clamp(V.x/sinTheta, -1.0, 1.0); scalar_type sinPhi = sinTheta==0.0 ? 0.0 : clamp(V.y/sinTheta, -1.0, 1.0); @@ -494,7 +494,7 @@ struct SBeckmannBxDF { const vector3_type localV = interaction.getTangentSpaceV(); const vector3_type H = __generate(localV, u); - + cache = anisocache_type::create(localV, H); ray_dir_info_type localL; localL.direction = math::reflect(localV, H, cache.VdotH); @@ -558,7 +558,7 @@ struct SBeckmannBxDF const spectral_type reflectance = fresnelConductor(ior0, ior1, params.VdotH); quo = reflectance * G2_over_G1; } - + return quotient_pdf_type::create(quo, _pdf); } @@ -679,7 +679,7 @@ struct SGGXBxDF scalar_type t2 = r * sin(phi); scalar_type s = 0.5 * (1.0 + V.z); t2 = (1.0 - s)*sqrt(1.0 - t1*t1) + s*t2; - + //reprojection onto hemisphere //TODO try it wothout the max(), not sure if -t1*t1-t2*t2>-1.0 vector3_type H = t1*T1 + t2*T2 + sqrt(max(0.0, 1.0-t1*t1-t2*t2))*V; @@ -691,7 +691,7 @@ struct SGGXBxDF { const vector3_type localV = interaction.getTangentSpaceV(); const vector3_type H = __generate(localV, u); - + cache = anisocache_type::create(localV, H); ray_dir_info_type localL; localL.direction = math::reflect(localV, H, cache.VdotH); @@ -753,7 +753,7 @@ struct SGGXBxDF const spectral_type reflectance = fresnelConductor(ior0, ior1, params.VdotH); quo = reflectance * G2_over_G1; } - + return quotient_pdf_type::create(quo, _pdf); } diff --git a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl index 1d6bf8ead6..38de552f00 100644 --- a/include/nbl/builtin/hlsl/bxdf/transmission.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/transmission.hlsl @@ -17,13 +17,13 @@ namespace bxdf namespace transmission { -template && surface_interactions::Isotropic && surface_interactions::Anisotropic && ray_dir_info::Basic && is_scalar_v) LightSample cos_generate(NBL_CONST_REF_ARG(Iso) interaction) { return LightSample(interaction.V.transmit(),-1.f,interaction.N); } -template && surface_interactions::Isotropic && surface_interactions::Anisotropic && ray_dir_info::Basic && is_scalar_v) LightSample cos_generate(NBL_CONST_REF_ARG(Aniso) interaction) { @@ -169,7 +169,7 @@ struct SSmoothDielectricBxDF scalar_type orientedEta, rcpOrientedEta; const bool backside = math::getOrientedEtas(orientedEta, rcpOrientedEta, interaction.NdotV, eta); bool dummy; - return __generate_wo_clamps(interaction.V.direction, interaction.T, interaction.B, interaction.N, backside, interaction.NdotV, + return __generate_wo_clamps(interaction.V.direction, interaction.T, interaction.B, interaction.N, backside, interaction.NdotV, interaction.NdotV, interaction.NdotV*interaction.NdotV, u, rcpOrientedEta, orientedEta*orientedEta, rcpOrientedEta*rcpOrientedEta, dummy); } @@ -178,7 +178,7 @@ struct SSmoothDielectricBxDF scalar_type orientedEta, rcpOrientedEta; const bool backside = math::getOrientedEtas(orientedEta, rcpOrientedEta, interaction.NdotV, eta); bool dummy; - return __generate_wo_clamps(interaction.V.direction, interaction.T, interaction.B, interaction.N, backside, interaction.NdotV, + return __generate_wo_clamps(interaction.V.direction, interaction.T, interaction.B, interaction.N, backside, interaction.NdotV, nbl::hlsl::abs(interaction.NdotV), interaction.NdotV*interaction.NdotV, u, rcpOrientedEta, orientedEta*orientedEta, rcpOrientedEta*rcpOrientedEta, dummy); } @@ -191,7 +191,7 @@ struct SSmoothDielectricBxDF quotient_pdf_type quotient_and_pdf(params_t params) { const bool transmitted = isTransmissionPath(params.uNdotV, params.uNdotL); - + scalar_type dummy, rcpOrientedEta; const bool backside = math::getOrientedEtas(dummy, rcpOrientedEta, params.NdotV, eta); @@ -245,7 +245,7 @@ struct SSmoothDielectricBxDF } // usually `luminosityContributionHint` would be the Rec.709 luma coefficients (the Y row of the RGB to CIE XYZ matrix) - // its basically a set of weights that determine + // its basically a set of weights that determine // assert(1.0==luminosityContributionHint.r+luminosityContributionHint.g+luminosityContributionHint.b); // `remainderMetadata` is a variable which the generator function returns byproducts of sample generation that would otherwise have to be redundantly calculated `quotient_and_pdf` sample_type __generate_wo_clamps(vector3_type V, vector3_type T, vector3_type B, vector3_type N, scalar_type NdotV, scalar_type absNdotV, NBL_REF_ARG(vector3_type) u, spectral_type eta2, spectral_type luminosityContributionHint, NBL_REF_ARG(spectral_type) remainderMetadata) @@ -259,7 +259,7 @@ struct SSmoothDielectricBxDF scalar_type rcpChoiceProb; const bool transmitted = math::partitionRandVariable(reflectionProb, u.z, rcpChoiceProb); remainderMetadata = (transmitted ? ((spectral_type)(1.0) - reflectance) : reflectance) * rcpChoiceProb; - + ray_dir_info_type L; L.direction = (transmitted ? (vector3_type)(0.0) : N * 2.0f * NdotV) - V; return sample_type::create(L, nbl::hlsl::dot(V, L.direction), T, B, N); @@ -352,7 +352,7 @@ struct SBeckmannDielectricBxDF scalar_type orientedEta, dummy; const bool backside = math::getOrientedEtas(orientedEta, dummy, params.VdotH, eta); const scalar_type orientedEta2 = orientedEta * orientedEta; - + const scalar_type VdotHLdotH = params.VdotH * params.LdotH; const bool transmitted = VdotHLdotH < 0.0; @@ -373,10 +373,10 @@ struct SBeckmannDielectricBxDF { const scalar_type localVdotH = nbl::hlsl::dot(localV,H); const scalar_type reflectance = fresnelDielectric_common(orientedEta2,nbl::hlsl::abs(localVdotH)); - + scalar_type rcpChoiceProb; bool transmitted = math::partitionRandVariable(reflectance, u.z, rcpChoiceProb); - + cache = anisocache_type::create(localV, H); const scalar_type VdotH = cache.VdotH; @@ -419,7 +419,7 @@ struct SBeckmannDielectricBxDF const bool transmitted = VdotHLdotH < 0.0; const scalar_type reflectance = fresnelDielectric_common(orientedEta2, nbl::hlsl::abs(params.VdotH)); - + scalar_type ndf, lambda; if (params.is_aniso) { @@ -443,7 +443,7 @@ struct SBeckmannDielectricBxDF smith::Beckmann beckmann_smith; lambda = beckmann_smith.Lambda(params.NdotV2, a2); } - + return smith::VNDF_pdf_wo_clamps >(ndf,lambda,params.NdotV,transmitted,params.VdotH,params.LdotH,VdotHLdotH,orientedEta,reflectance,onePlusLambda_V); } @@ -533,7 +533,7 @@ struct SGGXDielectricBxDF scalar_type orientedEta, dummy; const bool backside = math::getOrientedEtas(orientedEta, dummy, params.VdotH, eta); const scalar_type orientedEta2 = orientedEta * orientedEta; - + const scalar_type VdotHLdotH = params.VdotH * params.LdotH; const bool transmitted = VdotHLdotH < 0.0; @@ -560,10 +560,10 @@ struct SGGXDielectricBxDF { const scalar_type localVdotH = nbl::hlsl::dot(localV,H); const scalar_type reflectance = fresnelDielectric_common(orientedEta2,nbl::hlsl::abs(localVdotH)); - + scalar_type rcpChoiceProb; bool transmitted = math::partitionRandVariable(reflectance, u.z, rcpChoiceProb); - + cache = anisocache_type::create(localV, H); const scalar_type VdotH = cache.VdotH; @@ -640,7 +640,7 @@ struct SGGXDielectricBxDF { const scalar_type ax2 = A.x*A.x; const scalar_type ay2 = A.y*A.y; - + scalar_type _pdf = pdf(params); smith::GGX ggx_smith; diff --git a/include/nbl/builtin/hlsl/sampling/bilinear.hlsl b/include/nbl/builtin/hlsl/sampling/bilinear.hlsl index 3542e2dfef..42a923f650 100644 --- a/include/nbl/builtin/hlsl/sampling/bilinear.hlsl +++ b/include/nbl/builtin/hlsl/sampling/bilinear.hlsl @@ -31,8 +31,9 @@ struct Bilinear return retval; } - vector2_type generate(NBL_REF_ARG(scalar_type) rcpPdf, NBL_CONST_REF_ARG(vector2_type) u) + vector2_type generate(NBL_REF_ARG(scalar_type) rcpPdf, NBL_CONST_REF_ARG(vector2_type) _u) { + vector2_type u = _u; const vector2_type twiceAreasUnderXCurve = vector2_type(bilinearCoeffs[0] + bilinearCoeffs[1], bilinearCoeffs[2] + bilinearCoeffs[3]); Linear lineary = Linear::create(twiceAreasUnderXCurve); u.y = lineary.generate(u.y); diff --git a/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl b/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl index 60865e7c8e..dfc7dd6bcb 100644 --- a/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl +++ b/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl @@ -16,7 +16,7 @@ vector concentricMapping(vector _u) vector u = 2.0f * _u - 1.0f; vector p; - if (u == (vector)(0.0)) + if (nbl::hlsl::all >(u == (vector)(0.0))) p = (vector)(0.0); else { diff --git a/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl b/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl index cfc96dc9cb..f2f29ed12b 100644 --- a/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl +++ b/include/nbl/builtin/hlsl/sampling/projected_spherical_triangle.hlsl @@ -36,22 +36,23 @@ struct ProjectedSphericalTriangle vector4_type computeBilinearPatch(NBL_CONST_REF_ARG(vector3_type) receiverNormal, bool isBSDF) { const scalar_type minimumProjSolidAngle = 0.0; - + matrix m = matrix(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) + 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 bilinear = Bilinear::create(patch); u = bilinear.generate(rcpPdf, u); // now warp the points onto a spherical triangle - const vector3_type L = tri.generate(solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, u); + const vector3_type L = sphtri.generate(solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, u); rcpPdf *= solidAngle; return L; @@ -68,7 +69,7 @@ struct ProjectedSphericalTriangle 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 = tri.generateInverse(pdf, solidAngle, cos_vertices, sin_vertices, cos_a, cos_c, csc_b, csc_c, L); + 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 bilinear = Bilinear::create(patch); @@ -78,7 +79,7 @@ struct ProjectedSphericalTriangle 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 = tri.generateInverse(pdf, L); + const vector2_type u = sphtri.generateInverse(pdf, L); vector4_type patch = computeBilinearPatch(receiverNormal, receiverWasBSDF); Bilinear bilinear = Bilinear::create(patch); @@ -86,6 +87,7 @@ struct ProjectedSphericalTriangle } shapes::SphericalTriangle tri; + sampling::SphericalTriangle sphtri; }; } diff --git a/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl b/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl index c42bf8e464..cca3f21dd9 100644 --- a/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl +++ b/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl @@ -35,7 +35,7 @@ struct SphericalRectangle vector2_type generate(NBL_CONST_REF_ARG(vector2_type) rectangleExtents, NBL_CONST_REF_ARG(vector2_type) uv, NBL_REF_ARG(scalar_type) S) { const vector4_type denorm_n_z = vector4_type(-rect.r0.y, rect.r0.x + rectangleExtents.x, rect.r0.y + rectangleExtents.y, -rect.r0.x); - const vector4_type n_z = denorm_n_z / nbl::hlsl::sqrt(vector4_type(rect.r0.z * rect.r0.z) + denorm_n_z * denorm_n_z); + const vector4_type n_z = denorm_n_z / nbl::hlsl::sqrt((vector4_type)(rect.r0.z * rect.r0.z) + denorm_n_z * denorm_n_z); const vector4_type cosGamma = vector4_type( -n_z[0] * n_z[1], -n_z[1] * n_z[2], diff --git a/include/nbl/builtin/hlsl/shapes/rectangle.hlsl b/include/nbl/builtin/hlsl/shapes/rectangle.hlsl index 47d3927f31..f1a1e37575 100644 --- a/include/nbl/builtin/hlsl/shapes/rectangle.hlsl +++ b/include/nbl/builtin/hlsl/shapes/rectangle.hlsl @@ -43,7 +43,7 @@ struct SphericalRectangle { const vector4_type denorm_n_z = vector4_type(-r0.y, r0.x + rectangleExtents.x, r0.y + rectangleExtents.y, -r0.x); const vector4_type n_z = denorm_n_z / nbl::hlsl::sqrt((vector4_type)(r0.z * r0.z) + denorm_n_z * denorm_n_z); - const vector4_type cosGamma = vec4( + const vector4_type cosGamma = vector4_type( -n_z[0] * n_z[1], -n_z[1] * n_z[2], -n_z[2] * n_z[3], diff --git a/include/nbl/builtin/hlsl/shapes/triangle.hlsl b/include/nbl/builtin/hlsl/shapes/triangle.hlsl index d904ed7246..67fdfa0476 100644 --- a/include/nbl/builtin/hlsl/shapes/triangle.hlsl +++ b/include/nbl/builtin/hlsl/shapes/triangle.hlsl @@ -81,7 +81,7 @@ struct SphericalTriangle cos_vertices = nbl::hlsl::clamp((cos_sides - cos_sides.yzx * cos_sides.zxy) * csc_sides.yzx * csc_sides.zxy, (vector3_type)(-1.f), (vector3_type)1.f); matrix awayFromEdgePlane = matrix(awayFromEdgePlane0, awayFromEdgePlane1, awayFromEdgePlane2); - const vector3_type externalProducts = nbl::hlsl::abs(/* transposed already */awayFromEdgePlane * receiverNormal); + const vector3_type externalProducts = nbl::hlsl::abs(nbl::hlsl::mul(/* transposed already */awayFromEdgePlane, receiverNormal)); const vector3_type pyramidAngles = acos(cos_sides); return nbl::hlsl::dot(pyramidAngles, externalProducts) / (2.f * numbers::pi); From 85e955f3ceb7bc7a74647c3c06eee283603028aa Mon Sep 17 00:00:00 2001 From: keptsecret Date: Thu, 27 Feb 2025 10:38:37 +0700 Subject: [PATCH 13/23] fix wrong template usage --- include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl b/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl index dfc7dd6bcb..437f9fe963 100644 --- a/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl +++ b/include/nbl/builtin/hlsl/sampling/concentric_mapping.hlsl @@ -16,7 +16,7 @@ vector concentricMapping(vector _u) vector u = 2.0f * _u - 1.0f; vector p; - if (nbl::hlsl::all >(u == (vector)(0.0))) + if (nbl::hlsl::all >(u == (vector)(0.0))) p = (vector)(0.0); else { From 1c773d9bb78b3124ff0ba727c15b0818794f0502 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Tue, 4 Mar 2025 17:03:09 +0700 Subject: [PATCH 14/23] fix typo --- include/nbl/builtin/hlsl/bxdf/common.hlsl | 1 - 1 file changed, 1 deletion(-) diff --git a/include/nbl/builtin/hlsl/bxdf/common.hlsl b/include/nbl/builtin/hlsl/bxdf/common.hlsl index 66592d6319..1ddff69d72 100644 --- a/include/nbl/builtin/hlsl/bxdf/common.hlsl +++ b/include/nbl/builtin/hlsl/bxdf/common.hlsl @@ -694,7 +694,6 @@ struct SAnisotropicMicrofacetCache const scalar_type eta ) { - isocache_type iso = (isocache_type)retval; vector3_type H; const bool valid = isocache_type::compute(retval.iso_cache,interaction,_sample,eta,H); if (valid) From e8d2ed8cc0ebf0e76ee560aabecf8fe44eb3fbd4 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 14 Mar 2025 17:02:10 +0700 Subject: [PATCH 15/23] fixed some func usage to nbl ver --- .../hlsl/sampling/spherical_triangle.hlsl | 2 +- include/nbl/builtin/hlsl/shapes/triangle.hlsl | 35 +++++++++++-------- 2 files changed, 21 insertions(+), 16 deletions(-) diff --git a/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl b/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl index 1d4fda454d..7828fc14ea 100644 --- a/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl +++ b/include/nbl/builtin/hlsl/sampling/spherical_triangle.hlsl @@ -107,7 +107,7 @@ struct SphericalTriangle const scalar_type u = subTriSolidAngleRatio > numeric_limits::min ? subTriSolidAngleRatio : 0.0; const scalar_type cosBC_s = (cos_vertices[0] + cosB_ * cosC_) / (sinB_ * sinC_); - const scalar_type v = (1.0 - cosAngleAlongBC_s) / (1.0 - (cosBC_s < asfloat(0x3f7fffff) ? cosBC_s : cos_c)); + const scalar_type v = (1.0 - cosAngleAlongBC_s) / (1.0 - (cosBC_s < bit_cast(0x3f7fffff) ? cosBC_s : cos_c)); return vector2_type(u,v); } diff --git a/include/nbl/builtin/hlsl/shapes/triangle.hlsl b/include/nbl/builtin/hlsl/shapes/triangle.hlsl index 67fdfa0476..d3f5a90215 100644 --- a/include/nbl/builtin/hlsl/shapes/triangle.hlsl +++ b/include/nbl/builtin/hlsl/shapes/triangle.hlsl @@ -5,6 +5,7 @@ #ifndef _NBL_BUILTIN_HLSL_SHAPES_TRIANGLE_INCLUDED_ #define _NBL_BUILTIN_HLSL_SHAPES_TRIANGLE_INCLUDED_ +#include #include #include #include @@ -33,9 +34,13 @@ struct SphericalTriangle bool pyramidAngles(NBL_REF_ARG(vector3_type) cos_sides, NBL_REF_ARG(vector3_type) csc_sides) { - cos_sides = vector3_type(nbl::hlsl::dot(vertex1, vertex2), nbl::hlsl::dot(vertex2, vertex0), nbl::hlsl::dot(vertex0, vertex1)); - csc_sides = 1.0 / nbl::hlsl::sqrt((vector3_type)(1.f) - cos_sides * cos_sides); - return nbl::hlsl::any(csc_sides >= (vector3_type)(numeric_limits::max)); + cos_sides = vector3_type(hlsl::dot(vertex1, vertex2), hlsl::dot(vertex2, vertex0), hlsl::dot(vertex0, vertex1)); + csc_sides = (vector3_type)(1.f) - cos_sides * cos_sides; + csc_sides.x = hlsl::rsqrt(csc_sides.x); + csc_sides.y = hlsl::rsqrt(csc_sides.y); + csc_sides.z = hlsl::rsqrt(csc_sides.z); + + return hlsl::any >(csc_sides >= (vector3_type)(numeric_limits::max)); } scalar_type solidAngleOfTriangle(NBL_REF_ARG(vector3_type) cos_vertices, NBL_REF_ARG(vector3_type) sin_vertices, NBL_REF_ARG(scalar_type) cos_a, NBL_REF_ARG(scalar_type) cos_c, NBL_REF_ARG(scalar_type) csc_b, NBL_REF_ARG(scalar_type) csc_c) @@ -51,8 +56,8 @@ struct SphericalTriangle csc_c = csc_sides[2]; // Both vertices and angles at the vertices are denoted by the same upper case letters A, B, and C. The angles A, B, C of the triangle are equal to the angles between the planes that intersect the surface of the sphere or, equivalently, the angles between the tangent vectors of the great circle arcs where they meet at the vertices. Angles are in radians. The angles of proper spherical triangles are (by convention) less than PI - cos_vertices = clamp((cos_sides - cos_sides.yzx * cos_sides.zxy) * csc_sides.yzx * csc_sides.zxy, (vector3_type)(-1.f), (vector3_type)1.f); // using Spherical Law of Cosines (TODO: do we need to clamp anymore? since the pyramid angles method introduction?) - sin_vertices = sqrt((vector3_type)1.f - cos_vertices * cos_vertices); + cos_vertices = hlsl::clamp((cos_sides - cos_sides.yzx * cos_sides.zxy) * csc_sides.yzx * csc_sides.zxy, (vector3_type)(-1.f), (vector3_type)1.f); // using Spherical Law of Cosines (TODO: do we need to clamp anymore? since the pyramid angles method introduction?) + sin_vertices = hlsl::sqrt((vector3_type)1.f - cos_vertices * cos_vertices); return math::getArccosSumofABC_minus_PI(cos_vertices[0], cos_vertices[1], cos_vertices[2], sin_vertices[0], sin_vertices[1], sin_vertices[2]); } @@ -69,22 +74,22 @@ struct SphericalTriangle if (pyramidAngles(cos_sides, csc_sides)) return 0.f; - vector3_type awayFromEdgePlane0 = nbl::hlsl::cross(vertex1, vertex2) * csc_sides[0]; - vector3_type awayFromEdgePlane1 = nbl::hlsl::cross(vertex2, vertex0) * csc_sides[1]; - vector3_type awayFromEdgePlane2 = nbl::hlsl::cross(vertex0, vertex1) * csc_sides[2]; + vector3_type awayFromEdgePlane0 = hlsl::cross(vertex1, vertex2) * csc_sides[0]; + vector3_type awayFromEdgePlane1 = hlsl::cross(vertex2, vertex0) * csc_sides[1]; + vector3_type awayFromEdgePlane2 = hlsl::cross(vertex0, vertex1) * csc_sides[2]; // useless here but could be useful somewhere else - cos_vertices[0] = nbl::hlsl::dot(awayFromEdgePlane1, awayFromEdgePlane2); - cos_vertices[1] = nbl::hlsl::dot(awayFromEdgePlane2, awayFromEdgePlane0); - cos_vertices[2] = nbl::hlsl::dot(awayFromEdgePlane0, awayFromEdgePlane1); + cos_vertices[0] = hlsl::dot(awayFromEdgePlane1, awayFromEdgePlane2); + cos_vertices[1] = hlsl::dot(awayFromEdgePlane2, awayFromEdgePlane0); + cos_vertices[2] = hlsl::dot(awayFromEdgePlane0, awayFromEdgePlane1); // TODO: above dot products are in the wrong order, either work out which is which, or try all 6 permutations till it works - cos_vertices = nbl::hlsl::clamp((cos_sides - cos_sides.yzx * cos_sides.zxy) * csc_sides.yzx * csc_sides.zxy, (vector3_type)(-1.f), (vector3_type)1.f); + cos_vertices = hlsl::clamp((cos_sides - cos_sides.yzx * cos_sides.zxy) * csc_sides.yzx * csc_sides.zxy, (vector3_type)(-1.f), (vector3_type)1.f); matrix awayFromEdgePlane = matrix(awayFromEdgePlane0, awayFromEdgePlane1, awayFromEdgePlane2); - const vector3_type externalProducts = nbl::hlsl::abs(nbl::hlsl::mul(/* transposed already */awayFromEdgePlane, receiverNormal)); + const vector3_type externalProducts = hlsl::abs(hlsl::mul(/* transposed already */awayFromEdgePlane, receiverNormal)); - const vector3_type pyramidAngles = acos(cos_sides); - return nbl::hlsl::dot(pyramidAngles, externalProducts) / (2.f * numbers::pi); + const vector3_type pyramidAngles = acos(cos_sides); + return hlsl::dot(pyramidAngles, externalProducts) / (2.f * numbers::pi); } vector3_type vertex0; From c47f4469cbf529b1f2b370817c50416aa194ead3 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 17 Mar 2025 13:57:25 +0700 Subject: [PATCH 16/23] specify template args --- .../hlsl/sampling/spherical_rectangle.hlsl | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl b/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl index cca3f21dd9..663cd5e3d1 100644 --- a/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl +++ b/include/nbl/builtin/hlsl/sampling/spherical_rectangle.hlsl @@ -35,7 +35,7 @@ struct SphericalRectangle vector2_type generate(NBL_CONST_REF_ARG(vector2_type) rectangleExtents, NBL_CONST_REF_ARG(vector2_type) uv, NBL_REF_ARG(scalar_type) S) { const vector4_type denorm_n_z = vector4_type(-rect.r0.y, rect.r0.x + rectangleExtents.x, rect.r0.y + rectangleExtents.y, -rect.r0.x); - const vector4_type n_z = denorm_n_z / nbl::hlsl::sqrt((vector4_type)(rect.r0.z * rect.r0.z) + denorm_n_z * denorm_n_z); + const vector4_type n_z = denorm_n_z / hlsl::sqrt((vector4_type)(rect.r0.z * rect.r0.z) + denorm_n_z * denorm_n_z); const vector4_type cosGamma = vector4_type( -n_z[0] * n_z[1], -n_z[1] * n_z[2], @@ -54,24 +54,24 @@ struct SphericalRectangle const scalar_type CLAMP_EPS = 1e-5f; // flip z axsis if rect.r0.z > 0 - const uint32_t zFlipMask = (asuint(rect.r0.z) ^ 0x80000000u) & 0x80000000u; - rect.r0.z = asfloat(asuint(rect.r0.z) ^ zFlipMask); + const uint32_t zFlipMask = (bit_cast(rect.r0.z) ^ 0x80000000u) & 0x80000000u; + rect.r0.z = bit_cast(bit_cast(rect.r0.z) ^ zFlipMask); vector3_type r1 = rect.r0 + vector3_type(rectangleExtents.x, rectangleExtents.y, 0); const scalar_type au = uv.x * S + k; - const scalar_type fu = (nbl::hlsl::cos(au) * b0 - b1) / nbl::hlsl::sin(au); - const scalar_type cu_2 = nbl::hlsl::max(fu * fu + b0 * b0, 1.f); // forces `cu` to be in [-1,1] - const scalar_type cu = asfloat(asuint(1.0 / nbl::hlsl::sqrt(cu_2)) ^ (asuint(fu) & 0x80000000u)); + const scalar_type fu = (hlsl::cos(au) * b0 - b1) / hlsl::sin(au); + const scalar_type cu_2 = hlsl::max(fu * fu + b0 * b0, 1.f); // forces `cu` to be in [-1,1] + const scalar_type cu = bit_cast(bit_cast(1.0 / hlsl::sqrt(cu_2)) ^ (bit_cast(fu) & 0x80000000u)); - scalar_type xu = -(cu * rect.r0.z) * 1.0 / nbl::hlsl::sqrt(1 - cu * cu); - xu = nbl::hlsl::clamp(xu, rect.r0.x, r1.x); // avoid Infs + scalar_type xu = -(cu * rect.r0.z) * 1.0 / hlsl::sqrt(1 - cu * cu); + xu = hlsl::clamp(xu, rect.r0.x, r1.x); // avoid Infs const scalar_type d_2 = xu * xu + rect.r0.z * rect.r0.z; - const scalar_type d = nbl::hlsl::sqrt(d_2); + const scalar_type d = hlsl::sqrt(d_2); - const scalar_type h0 = rect.r0.y / nbl::hlsl::sqrt(d_2 + rect.r0.y * rect.r0.y); - const scalar_type h1 = r1.y / nbl::hlsl::sqrt(d_2 + r1.y * r1.y); + const scalar_type h0 = rect.r0.y / hlsl::sqrt(d_2 + rect.r0.y * rect.r0.y); + const scalar_type h1 = r1.y / hlsl::sqrt(d_2 + r1.y * r1.y); const scalar_type hv = h0 + uv.y * (h1 - h0), hv2 = hv * hv; - const scalar_type yv = (hv2 < 1 - CLAMP_EPS) ? (hv * d) / nbl::hlsl::sqrt(1 - hv2) : r1.y; + const scalar_type yv = (hv2 < 1 - CLAMP_EPS) ? (hv * d) / hlsl::sqrt(1 - hv2) : r1.y; return vector2_type((xu - rect.r0.x) / rectangleExtents.x, (yv - rect.r0.y) / rectangleExtents.y); } From 1137b6b767142ef44e2bad80032e0053515a0051 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 17 Mar 2025 14:31:39 +0700 Subject: [PATCH 17/23] update to latest example --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index a2c84c2513..b5194ef176 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit a2c84c2513510f42cd245a015c6ba7ddd0d6eeaa +Subproject commit b5194ef1768587aef72be4fdc044b5b881160609 From 7e8dd8143795536d2c82e01d1d24db5bcf2a4aeb Mon Sep 17 00:00:00 2001 From: keptsecret Date: Wed, 19 Mar 2025 16:16:31 +0700 Subject: [PATCH 18/23] latest example --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index a2c84c2513..ca8f2ec8fa 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit a2c84c2513510f42cd245a015c6ba7ddd0d6eeaa +Subproject commit ca8f2ec8fa84a2bd1bfeb4348263f82d14026bca From b1546383f2f44e4bcb84456aee990a278672e74b Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 21 Mar 2025 16:49:40 +0700 Subject: [PATCH 19/23] fix use of static const in func --- examples_tests | 2 +- include/nbl/builtin/hlsl/math/functions.hlsl | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/examples_tests b/examples_tests index ca8f2ec8fa..e95f09d5d2 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit ca8f2ec8fa84a2bd1bfeb4348263f82d14026bca +Subproject commit e95f09d5d20181c4107064cec08bddc689a7f399 diff --git a/include/nbl/builtin/hlsl/math/functions.hlsl b/include/nbl/builtin/hlsl/math/functions.hlsl index f7a84005e8..f47efff877 100644 --- a/include/nbl/builtin/hlsl/math/functions.hlsl +++ b/include/nbl/builtin/hlsl/math/functions.hlsl @@ -122,11 +122,7 @@ void frisvad(NBL_CONST_REF_ARG(T) normal, NBL_REF_ARG(T) tangent, NBL_REF_ARG(T) bool partitionRandVariable(float leftProb, NBL_REF_ARG(float) xi, NBL_REF_ARG(float) rcpChoiceProb) { -#ifdef __HLSL_VERSION - NBL_CONSTEXPR float NEXT_ULP_AFTER_UNITY = asfloat(0x3f800001u); -#else - NBL_CONSTEXPR float32_t NEXT_ULP_AFTER_UNITY = bit_cast(0x3f800001u); -#endif + const float32_t NEXT_ULP_AFTER_UNITY = bit_cast(0x3f800001u); const bool pickRight = xi >= leftProb * NEXT_ULP_AFTER_UNITY; // This is all 100% correct taking into account the above NEXT_ULP_AFTER_UNITY From 7892563055f9bc95c14b9704bd4b24c5000eda96 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 24 Mar 2025 14:43:43 +0700 Subject: [PATCH 20/23] added more morton order stuff --- examples_tests | 2 +- include/nbl/builtin/glsl/utils/morton.glsl | 17 ++++++ include/nbl/builtin/hlsl/math/morton.hlsl | 68 ++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 include/nbl/builtin/hlsl/math/morton.hlsl diff --git a/examples_tests b/examples_tests index e95f09d5d2..3cdfb4baf2 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit e95f09d5d20181c4107064cec08bddc689a7f399 +Subproject commit 3cdfb4baf2df319643620a8189c277dec20cb163 diff --git a/include/nbl/builtin/glsl/utils/morton.glsl b/include/nbl/builtin/glsl/utils/morton.glsl index de3be8b9c7..fd07a9cad8 100644 --- a/include/nbl/builtin/glsl/utils/morton.glsl +++ b/include/nbl/builtin/glsl/utils/morton.glsl @@ -22,6 +22,18 @@ uint nbl_glsl_morton_decode2d8bComponent(in uint x) return x; } +uint nbl_glsl_morton_decode2d32bComponent(in uint 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; +} + + uvec2 nbl_glsl_morton_decode2d4b(in uint x) { 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) return uvec2(nbl_glsl_morton_decode2d8bComponent(x), nbl_glsl_morton_decode2d8bComponent(x >> 1u)); } +uvec2 nbl_glsl_morton_decode2d32b(in uint x) +{ + return uvec2(nbl_glsl_morton_decode2d32bComponent(x), nbl_glsl_morton_decode2d32bComponent(x >> 1u)); +} + #endif \ No newline at end of file diff --git a/include/nbl/builtin/hlsl/math/morton.hlsl b/include/nbl/builtin/hlsl/math/morton.hlsl new file mode 100644 index 0000000000..4a6cb5dfd3 --- /dev/null +++ b/include/nbl/builtin/hlsl/math/morton.hlsl @@ -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 +struct MortonComponent; + +template +struct MortonComponent +{ + 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 +struct MortonComponent +{ + 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 +struct Morton +{ + using vector2_type = vector; + using component_type = impl::MortonComponent; + + static vector2_type decode2d(T x) + { + return vector2_type(component_type::decode2d(x), component_type::decode2d(x >> 1u)); + } +}; + +} +} +} + +#endif From b21b789991cb544c9d95ce4b28dc22e28c68778b Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 28 Mar 2025 14:40:47 +0700 Subject: [PATCH 21/23] latest example --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 3cdfb4baf2..1535561525 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 3cdfb4baf2df319643620a8189c277dec20cb163 +Subproject commit 1535561525c1df59d227969692ae7405b507962b From 26adf951ee2e83ca23eeb8700543bdf37f8261cd Mon Sep 17 00:00:00 2001 From: keptsecret Date: Fri, 27 Jun 2025 10:19:00 +0700 Subject: [PATCH 22/23] latest example --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index a6de5908a2..52c1aa54cf 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit a6de5908a269d0f6853e0c1e94dec8fcdbe6540e +Subproject commit 52c1aa54cf859b63a8ff6df648f743003e5e13fe From 36910c676e1bc7a26802a5b8d7f84227b208a803 Mon Sep 17 00:00:00 2001 From: keptsecret Date: Mon, 30 Jun 2025 09:58:25 +0700 Subject: [PATCH 23/23] latest example fixes --- examples_tests | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples_tests b/examples_tests index 52c1aa54cf..8b31859520 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 52c1aa54cf859b63a8ff6df648f743003e5e13fe +Subproject commit 8b31859520069831b246d13270b43b97aea83141