Skip to content

Commit 01fd600

Browse files
Create common.hlsl
but don't implement the caches yet
1 parent 5aac44b commit 01fd600

File tree

1 file changed

+224
-0
lines changed

1 file changed

+224
-0
lines changed
Lines changed: 224 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,224 @@
1+
// Copyright (C) 2018-2022 - 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_COMMON_INCLUDED_
5+
#define _NBL_BUILTIN_HLSL_BXDF_COMMON_INCLUDED_
6+
7+
namespace nbl
8+
{
9+
namespace hlsl
10+
{
11+
namespace bxdf
12+
{
13+
14+
15+
namespace ray_dir_info
16+
{
17+
18+
// no ray-differentials, nothing
19+
struct Basic
20+
{
21+
float3 getDirection() {return direction;}
22+
23+
float3 direction;
24+
};
25+
// more to come!
26+
27+
}
28+
29+
30+
namespace surface_interactions
31+
{
32+
33+
template<class RayDirInfo>
34+
struct Isotropic
35+
{
36+
// WARNING: Changed since GLSL, now arguments need to be normalized!
37+
static Isotropic<RayDirInfo> create(const RayDirInfo normalizedV, const float3 normalizedN)
38+
{
39+
Isotropic<RayDirInfo> retval;
40+
retval.V = normalizedV;
41+
retval.N = normalizedN;
42+
43+
retval.NdotV = dot(retval.N,retval.V.getDirection());
44+
retval.NdotV_squared = retval.NdotV*retval.NdotV;
45+
46+
return retval;
47+
}
48+
49+
RayDirInfo V;
50+
float3 N;
51+
float NdotV;
52+
float NdotV2; // old NdotV_squared
53+
};
54+
55+
template<class RayDirInfo>
56+
struct Anisotropic : Isotropic<RayDirInfo>
57+
{
58+
// WARNING: Changed since GLSL, now arguments need to be normalized!
59+
static Anisotropic<RayDirInfo> create(
60+
const Isotropic<RayDirInfo> isotropic,
61+
const float3 normalizedT,
62+
const float normalizedB
63+
)
64+
{
65+
Anisotropic<RayDirInfo> retval;
66+
retval::Isotropic<RayDirInfo> = isotropic;
67+
retval.T = normalizedT;
68+
retval.B = normalizedB;
69+
70+
const float3 V = retval.getDirection();
71+
retval.TdotV = dot(V,retval.T);
72+
retval.BdotV = dot(V,retval.B);
73+
74+
return retval;
75+
}
76+
static Anisotropic<RayDirInfo> create(const Isotropic<RayDirInfo> isotropic, const float3 normalizedT)
77+
{
78+
return create(isotropic,normalizedT,cross(isotropic.N,normalizedT));
79+
}
80+
static Anisotropic<RayDirInfo> create(const Isotropic<RayDirInfo> isotropic)
81+
{
82+
float2x3 TB = nbl::hlsl::frisvad(isotropic.N);
83+
return create(isotropic,TB[0],TB[1]);
84+
}
85+
86+
float3 getTangentSpaceV() {return float3(Tdot,BdotV,Isotropic<RayDirInfo>::NdotV);}
87+
// WARNING: its the transpose of the old GLSL function return value!
88+
float3x3 getTangentFrame() {return float3x3(T,B,Isotropic<RayDirInfo>::N);}
89+
90+
float3 T;
91+
float3 B;
92+
float3 TdotV;
93+
float3 BdotV;
94+
};
95+
96+
}
97+
98+
99+
template<class RayDirInfo>
100+
struct LightSample
101+
{
102+
static LightSample<RayDirInfo> createTangentSpace(
103+
const float3 tangentSpaceV,
104+
const RayDirInfo tangentSpaceL,
105+
const float3x3 tangentFrame // WARNING: its the transpose of the old GLSL function return value!
106+
)
107+
{
108+
LightSample<RayDirInfo> retval;
109+
110+
retval.L = RayDirInfo::transform(tangentSpaceL,tangentFrame);
111+
retval.VdotL = dot(tangentSpaceV,tangentSpaceL);
112+
113+
retval.TdotL = tangentSpaceL.x;
114+
retval.BdotL = tangentSpaceL.y;
115+
retval.NdotL = tangentSpaceL.z;
116+
retval.NdotL2 = retval.NdotL*retval.NdotL;
117+
118+
return retval;
119+
}
120+
static LightSample<RayDirInfo> create(const RayDirInfo L, const float VdotL, const float3 N)
121+
{
122+
LightSample<RayDirInfo> retval;
123+
124+
retval.L = L;
125+
retval.VdotL = VdotL;
126+
127+
retval.TdotL = nbl::hlsl::numeric_limits<float>::nan();
128+
retval.BdotL = nbl::hlsl::numeric_limits<float>::nan();
129+
retval.NdotL = dot(N,L);
130+
retval.NdotL2 = retval.NdotL*retval.NdotL;
131+
132+
return retval;
133+
}
134+
static LightSample<RayDirInfo> create(const RayDirInfo L, const float VdotL, const float3 T, const float3 B, const float3 N)
135+
{
136+
LightSample<RayDirInfo> retval = create(L,VdotL,N);
137+
138+
retval.TdotL = dot(T,L);
139+
retval.BdotL = dot(B,L);
140+
141+
return retval;
142+
}
143+
// overloads for surface_interactions
144+
template<class ObserverRayDirInfo>
145+
static LightSample<RayDirInfo> create(const float3 L, const surface_interactions::Isotropic<ObserverRayDirInfo> interaction)
146+
{
147+
const float3 V = interaction.V.getDirection();
148+
const float VdotL = dot(V,L);
149+
return create(L,VdotL,interaction.N);
150+
}
151+
template<class ObserverRayDirInfo>
152+
static LightSample<RayDirInfo> create(const float3 L, const surface_interactions::Anisotropic<ObserverRayDirInfo> interaction)
153+
{
154+
const float3 V = interaction.V.getDirection();
155+
const float VdotL = dot(V,L);
156+
return create(L,VdotL,interaction.T,interaction.B,interaction.N);
157+
}
158+
//
159+
float3 getTangentSpaceL()
160+
{
161+
return float3(TdotL,BdotL,NdotL);
162+
}
163+
164+
RayDirInfo L;
165+
float VdotL;
166+
167+
float TdotL;
168+
float BdotL;
169+
float NdotL;
170+
float NdotL2;
171+
};
172+
173+
//
174+
struct IsotropicMicrofacetCache
175+
{
176+
// always valid because its specialized for the reflective case
177+
static IsotropicMicrofacetCache create(const float NdotV, const float NdotL, const float VdotL, out float LplusV_rcpLen)
178+
{
179+
LplusV_rcpLen = inversesqrt(2.0+2.0*VdotL);
180+
181+
IsotropicMicrofacetCache retval;
182+
183+
retval.VdotH = LplusV_rcpLen*VdotL+LplusV_rcpLen;
184+
retval.LdotH = retval.VdotH;
185+
retval.NdotH = (NdotL+NdotV)*LplusV_rcpLen;
186+
retval.NdotH2 = retval.NdotH*retval.NdotH;
187+
188+
return retval;
189+
}
190+
static IsotropicMicrofacetCache create(const float NdotV, const float NdotL, const float VdotL)
191+
{
192+
float dummy;
193+
return create(NdotV,NdotL,VdotL,dummy);
194+
}
195+
196+
bool isValidVNDFMicrofacet(const bool is_bsdf, const bool transmission, const float VdotL, const float eta, const float rcp_eta)
197+
{
198+
return NdotH >= 0.0 && !(is_bsdf && transmission && (VdotL > -min(eta,rcp_eta)));
199+
}
200+
201+
float VdotH;
202+
float LdotH;
203+
float NdotH;
204+
float NdotH2;
205+
};
206+
struct AnisotropicMicrofacetCache : IsotropicMicrofacetCache
207+
{
208+
float TdotH;
209+
float BdotH;
210+
};
211+
212+
213+
// finally fixed the semantic F-up, value/pdf = quotient not remainder
214+
template<typename SpectralBuckets>
215+
SpectralBuckets quotient_to_value(const SpectralBuckets quotient, const float pdf)
216+
{
217+
return quotient*pdf;
218+
}
219+
220+
}
221+
}
222+
}
223+
224+
#endif

0 commit comments

Comments
 (0)