Skip to content

Commit 28ba56f

Browse files
Merge pull request #803 from Devsh-Graphics-Programming/maths_for_bxdfs_hlsl
Maths for HLSL BxDFs (template cmath, tgmath)
2 parents a3d3675 + ff66405 commit 28ba56f

File tree

5 files changed

+344
-268
lines changed

5 files changed

+344
-268
lines changed
Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
// Copyright (C) 2018-2023 - DevSH Graphics Programming Sp. z O.O.
2+
// This file is part of the "Nabla Engine".
3+
// For conditions of distribution and use, see copyright notice in nabla.h
4+
#ifndef _NBL_BUILTIN_HLSL_BXDF_FRESNEL_INCLUDED_
5+
#define _NBL_BUILTIN_HLSL_BXDF_FRESNEL_INCLUDED_
6+
7+
#include "nbl/builtin/hlsl/cpp_compat.hlsl"
8+
#include "nbl/builtin/hlsl/numbers.hlsl"
9+
#include "nbl/builtin/hlsl/vector_utils/vector_traits.hlsl"
10+
#include "nbl/builtin/hlsl/spirv_intrinsics/core.hlsl"
11+
12+
namespace nbl
13+
{
14+
namespace hlsl
15+
{
16+
17+
namespace bxdf
18+
{
19+
20+
namespace impl
21+
{
22+
template<typename T>
23+
struct orientedEtas;
24+
25+
template<>
26+
struct orientedEtas<float>
27+
{
28+
static bool __call(NBL_REF_ARG(float) orientedEta, NBL_REF_ARG(float) rcpOrientedEta, float NdotI, float eta)
29+
{
30+
const bool backside = NdotI < 0.0;
31+
const float rcpEta = 1.0 / eta;
32+
orientedEta = backside ? rcpEta : eta;
33+
rcpOrientedEta = backside ? eta : rcpEta;
34+
return backside;
35+
}
36+
};
37+
38+
template<>
39+
struct orientedEtas<float32_t3>
40+
{
41+
static bool __call(NBL_REF_ARG(float32_t3) orientedEta, NBL_REF_ARG(float32_t3) rcpOrientedEta, float NdotI, float32_t3 eta)
42+
{
43+
const bool backside = NdotI < 0.0;
44+
const float32_t3 rcpEta = (float32_t3)1.0 / eta;
45+
orientedEta = backside ? rcpEta:eta;
46+
rcpOrientedEta = backside ? eta:rcpEta;
47+
return backside;
48+
}
49+
};
50+
}
51+
52+
template<typename T NBL_FUNC_REQUIRES(is_scalar_v<T> || is_vector_v<T>)
53+
bool getOrientedEtas(NBL_REF_ARG(T) orientedEta, NBL_REF_ARG(T) rcpOrientedEta, scalar_type_t<T> NdotI, T eta)
54+
{
55+
return impl::orientedEtas<T>::__call(orientedEta, rcpOrientedEta, NdotI, eta);
56+
}
57+
58+
59+
template <typename T NBL_FUNC_REQUIRES(concepts::Vectorial<T>)
60+
T reflect(T I, T N, typename vector_traits<T>::scalar_type NdotI)
61+
{
62+
return N * 2.0f * NdotI - I;
63+
}
64+
65+
template<typename T NBL_PRIMARY_REQUIRES(vector_traits<T>::Dimension == 3)
66+
struct refract
67+
{
68+
using this_t = refract<T>;
69+
using vector_type = T;
70+
using scalar_type = typename vector_traits<T>::scalar_type;
71+
72+
static this_t create(NBL_CONST_REF_ARG(vector_type) I, NBL_CONST_REF_ARG(vector_type) N, bool backside, scalar_type NdotI, scalar_type NdotI2, scalar_type rcpOrientedEta, scalar_type rcpOrientedEta2)
73+
{
74+
this_t retval;
75+
retval.I = I;
76+
retval.N = N;
77+
retval.backside = backside;
78+
retval.NdotI = NdotI;
79+
retval.NdotI2 = NdotI2;
80+
retval.rcpOrientedEta = rcpOrientedEta;
81+
retval.rcpOrientedEta2 = rcpOrientedEta2;
82+
return retval;
83+
}
84+
85+
static this_t create(NBL_CONST_REF_ARG(vector_type) I, NBL_CONST_REF_ARG(vector_type) N, scalar_type NdotI, scalar_type eta)
86+
{
87+
this_t retval;
88+
retval.I = I;
89+
retval.N = N;
90+
scalar_type orientedEta;
91+
retval.backside = getOrientedEtas<scalar_type>(orientedEta, retval.rcpOrientedEta, NdotI, eta);
92+
retval.NdotI = NdotI;
93+
retval.NdotI2 = NdotI * NdotI;
94+
retval.rcpOrientedEta2 = retval.rcpOrientedEta * retval.rcpOrientedEta;
95+
return retval;
96+
}
97+
98+
static this_t create(NBL_CONST_REF_ARG(vector_type) I, NBL_CONST_REF_ARG(vector_type) N, scalar_type eta)
99+
{
100+
this_t retval;
101+
retval.I = I;
102+
retval.N = N;
103+
retval.NdotI = dot<vector_type>(N, I);
104+
scalar_type orientedEta;
105+
retval.backside = getOrientedEtas<scalar_type>(orientedEta, retval.rcpOrientedEta, retval.NdotI, eta);
106+
retval.NdotI2 = retval.NdotI * retval.NdotI;
107+
retval.rcpOrientedEta2 = retval.rcpOrientedEta * retval.rcpOrientedEta;
108+
return retval;
109+
}
110+
111+
static scalar_type computeNdotT(bool backside, scalar_type NdotI2, scalar_type rcpOrientedEta2)
112+
{
113+
scalar_type NdotT2 = rcpOrientedEta2 * NdotI2 + 1.0 - rcpOrientedEta2;
114+
scalar_type absNdotT = sqrt<scalar_type>(NdotT2);
115+
return backside ? absNdotT : -(absNdotT);
116+
}
117+
118+
vector_type doRefract()
119+
{
120+
return N * (NdotI * rcpOrientedEta + computeNdotT(backside, NdotI2, rcpOrientedEta2)) - rcpOrientedEta * I;
121+
}
122+
123+
static vector_type doReflectRefract(bool _refract, NBL_CONST_REF_ARG(vector_type) _I, NBL_CONST_REF_ARG(vector_type) _N, scalar_type _NdotI, scalar_type _NdotTorR, scalar_type _rcpOrientedEta)
124+
{
125+
return _N * (_NdotI * (_refract ? _rcpOrientedEta : 1.0f) + _NdotTorR) - _I * (_refract ? _rcpOrientedEta : 1.0f);
126+
}
127+
128+
vector_type doReflectRefract(bool r)
129+
{
130+
const T NdotTorR = r ? computeNdotT(backside, NdotI2, rcpOrientedEta2) : NdotI;
131+
return doReflectRefract(r, I, N, NdotI, NdotTorR, rcpOrientedEta);
132+
}
133+
134+
vector_type I;
135+
vector_type N;
136+
bool backside;
137+
scalar_type NdotI;
138+
scalar_type NdotI2;
139+
scalar_type rcpOrientedEta;
140+
scalar_type rcpOrientedEta2;
141+
};
142+
143+
}
144+
145+
}
146+
}
147+
148+
#endif

include/nbl/builtin/hlsl/concepts/core.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ template<typename T>
4747
NBL_BOOL_CONCEPT UnsignedIntegralScalar = !nbl::hlsl::is_signed_v<T> && ::nbl::hlsl::is_integral_v<T> && nbl::hlsl::is_scalar_v<T>;
4848

4949
template<typename T>
50-
NBL_BOOL_CONCEPT FloatingPointScalar = nbl::hlsl::is_floating_point_v<T> && nbl::hlsl::is_scalar_v<T>;
50+
NBL_BOOL_CONCEPT FloatingPointScalar = (nbl::hlsl::is_floating_point_v<T> && nbl::hlsl::is_scalar_v<T>);
5151

5252
template<typename T>
5353
NBL_BOOL_CONCEPT BooleanScalar = concepts::Boolean<T> && nbl::hlsl::is_scalar_v<T>;

include/nbl/builtin/hlsl/ieee754.hlsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ NBL_CONSTEXPR_INLINE_FUNC FloatingPoint flipSign(FloatingPoint val, bool flip =
148148
using AsFloat = typename float_of_size<sizeof(FloatingPoint)>::type;
149149
using AsUint = typename unsigned_integer_of_size<sizeof(FloatingPoint)>::type;
150150
const AsUint asUint = ieee754::impl::bitCastToUintType(val);
151-
return bit_cast<FloatingPoint>(asUint ^ (flip ? ieee754::traits<AsFloat>::signMask : 0ull));
151+
return bit_cast<FloatingPoint>(asUint ^ (flip ? ieee754::traits<AsFloat>::signMask : AsUint(0ull)));
152152
}
153153

154154
}

0 commit comments

Comments
 (0)