Skip to content

Commit b2af579

Browse files
committed
split out fresnel stuff, functions.hlsl fixes
1 parent aef1bb7 commit b2af579

File tree

2 files changed

+200
-233
lines changed

2 files changed

+200
-233
lines changed
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
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+
60+
61+
template <typename T NBL_FUNC_REQUIRES(vector_traits<T>::Dimensions == 3)
62+
T reflect(NBL_CONST_REF_ARG(T) I, NBL_CONST_REF_ARG(T) N, typename vector_traits<T>::scalar_type NdotI)
63+
{
64+
return N * 2.0f * NdotI - I;
65+
}
66+
67+
template <typename T NBL_FUNC_REQUIRES(vector_traits<T>::Dimensions == 3)
68+
T reflect(NBL_CONST_REF_ARG(T) I, NBL_CONST_REF_ARG(T) N)
69+
{
70+
typename vector_traits<T>::scalar_type NdotI = nbl::hlsl::dot<T>(N, I);
71+
return reflect<T>(I, N, NdotI);
72+
}
73+
74+
template<typename T NBL_PRIMARY_REQUIRES(vector_traits<T>::Dimensions == 3)
75+
struct refract
76+
{
77+
using this_t = refract;
78+
using scalar_type = typename vector_traits<T>::scalar_type;
79+
using vector_type = T;
80+
81+
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)
82+
{
83+
this_t retval;
84+
retval.I = I;
85+
retval.N = N;
86+
retval.backside = backside;
87+
retval.NdotI = NdotI;
88+
retval.NdotI2 = NdotI2;
89+
retval.rcpOrientedEta = rcpOrientedEta;
90+
retval.rcpOrientedEta2 = rcpOrientedEta2;
91+
return retval;
92+
}
93+
94+
static this_t create(NBL_CONST_REF_ARG(vector_type) I, NBL_CONST_REF_ARG(vector_type) N, scalar_type NdotI, scalar_type eta)
95+
{
96+
this_t retval;
97+
retval.I = I;
98+
retval.N = N;
99+
T orientedEta;
100+
retval.backside = bxdf::getOrientedEtas<scalar_type>(orientedEta, retval.rcpOrientedEta, NdotI, eta);
101+
retval.NdotI = NdotI;
102+
retval.NdotI2 = NdotI * NdotI;
103+
retval.rcpOrientedEta2 = retval.rcpOrientedEta * retval.rcpOrientedEta;
104+
return retval;
105+
}
106+
107+
static this_t create(NBL_CONST_REF_ARG(vector_type) I, NBL_CONST_REF_ARG(vector_type) N, scalar_type eta)
108+
{
109+
this_t retval;
110+
retval.I = I;
111+
retval.N = N;
112+
retval.NdotI = nbl::hlsl::dot<vector_type>(N, I);
113+
scalar_type orientedEta;
114+
retval.backside = bxdf::getOrientedEtas<scalar_type>(orientedEta, retval.rcpOrientedEta, retval.NdotI, eta);
115+
retval.NdotI2 = retval.NdotI * retval.NdotI;
116+
retval.rcpOrientedEta2 = retval.rcpOrientedEta * retval.rcpOrientedEta;
117+
return retval;
118+
}
119+
120+
static scalar_type computeNdotT(bool backside, scalar_type NdotI2, scalar_type rcpOrientedEta2)
121+
{
122+
scalar_type NdotT2 = rcpOrientedEta2 * NdotI2 + 1.0 - rcpOrientedEta2;
123+
scalar_type absNdotT = nbl::hlsl::sqrt<scalar_type>(NdotT2);
124+
return backside ? absNdotT : -(absNdotT);
125+
}
126+
127+
vector_type doRefract()
128+
{
129+
return N * (NdotI * rcpOrientedEta + computeNdotT(backside, NdotI2, rcpOrientedEta2)) - rcpOrientedEta * I;
130+
}
131+
132+
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)
133+
{
134+
return _N * (_NdotI * (_refract ? _rcpOrientedEta : 1.0f) + _NdotTorR) - _I * (_refract ? _rcpOrientedEta : 1.0f);
135+
}
136+
137+
vector_type doReflectRefract(bool r)
138+
{
139+
const T NdotTorR = r ? computeNdotT(backside, NdotI2, rcpOrientedEta2) : NdotI;
140+
return doReflectRefract(r, I, N, NdotI, NdotTorR, rcpOrientedEta);
141+
}
142+
143+
vector_type I;
144+
vector_type N;
145+
bool backside;
146+
T NdotI;
147+
T NdotI2;
148+
T rcpOrientedEta;
149+
T rcpOrientedEta2;
150+
};
151+
152+
}
153+
}
154+
155+
#endif

0 commit comments

Comments
 (0)