3
3
// For conditions of distribution and use, see copyright notice in nabla.h
4
4
#ifndef _NBL_BUILTIN_HLSL_SURFACE_TRANSFORM_INCLUDED_
5
5
#define _NBL_BUILTIN_HLSL_SURFACE_TRANSFORM_INCLUDED_
6
+ #include < nbl/builtin/hlsl/limits.hlsl>
6
7
7
8
namespace nbl
8
9
{
@@ -24,6 +25,70 @@ enum class FLAG_BITS : uint16_t
24
25
HORIZONTAL_MIRROR_ROTATE_270_BIT = 0x0080 ,
25
26
INHERIT_BIT = 0x0100 ,
26
27
ALL_BITS = 0x01FF
28
+ };
29
+
30
+ // define everything else in terms of this
31
+ float32_t2x2 transformMatrix (const FLAG_BITS transform)
32
+ {
33
+ switch (transform)
34
+ {
35
+ case FLAG_BITS::IDENTITY_BIT:
36
+ return float32_t2x2 ( 1 .f , 0 .f ,
37
+ 0 .f , 1 .f );
38
+ case FLAG_BITS::ROTATE_90_BIT:
39
+ return float32_t2x2 ( 0 .f , 1 .f ,
40
+ -1 .f , 0 .f );
41
+ case FLAG_BITS::ROTATE_180_BIT:
42
+ return float32_t2x2 (-1 .f , 0 .f ,
43
+ 0 .f ,-1 .f );
44
+ case FLAG_BITS::ROTATE_270_BIT:
45
+ return float32_t2x2 ( 0 .f ,-1 .f ,
46
+ 1 .f , 0 .f );
47
+ case FLAG_BITS::HORIZONTAL_MIRROR_BIT:
48
+ return float32_t2x2 (-1 .f , 0 .f ,
49
+ 0 .f , 1 .f );
50
+ case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_90_BIT:
51
+ return float32_t2x2 ( 0 .f , 1 .f ,
52
+ 1 .f , 0 .f );
53
+ case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_180_BIT:
54
+ return float32_t2x2 ( 1 .f , 0 .f ,
55
+ 0 .f ,-1 .f );
56
+ case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_270_BIT:
57
+ return float32_t2x2 ( 0 .f ,-1 .f ,
58
+ -1 .f , 0 .f );
59
+ default :
60
+ break ;
61
+ }
62
+ const float _nan = numeric_limits<float >::signaling_NaN;
63
+ return float32_t2x2 (_nan,_nan,_nan,_nan);
64
+ }
65
+
66
+ // ! [width,height] might switch to [height, width] in orientations such as 90°CW
67
+ // ! Usecase: Find out how big the viewport has to be after or before a tranform is applied
68
+ uint16_t2 transformedExtents (const FLAG_BITS transform, const uint16_t2 screenSize)
69
+ {
70
+ switch (transform)
71
+ {
72
+ case FLAG_BITS::IDENTITY_BIT:
73
+ case FLAG_BITS::HORIZONTAL_MIRROR_BIT:
74
+ case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_180_BIT:
75
+ case FLAG_BITS::ROTATE_180_BIT:
76
+ return screenSize;
77
+ case FLAG_BITS::ROTATE_90_BIT:
78
+ case FLAG_BITS::ROTATE_270_BIT:
79
+ case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_90_BIT:
80
+ case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_270_BIT:
81
+ return screenSize.yx ;
82
+ default :
83
+ break ;
84
+ }
85
+ return uint16_t2 (0 );
86
+ }
87
+
88
+ float transformedAspectRatio (const FLAG_BITS transform, const uint16_t2 screenSize)
89
+ {
90
+ const uint16_t2 newExtents = transformedExtents (transform,screenSize);
91
+ return float (newExtents[1 ])/float (newExtents[0 ]);
27
92
}
28
93
29
94
// ! Use this function to apply the INVERSE of swapchain tranformation to the screenspace coordinate `coord`
@@ -35,6 +100,7 @@ enum class FLAG_BITS : uint16_t
35
100
// ! - Be aware that almost always you'd want to do a single transform in your rendering pipeline.
36
101
uint16_t2 applyInverseToScreenSpaceCoordinate (const FLAG_BITS transform, const uint16_t2 coord, const uint16_t2 screenSize)
37
102
{
103
+ // TODO: use inverse(transformMatrix(transform)) somehow
38
104
const uint16_t2 lastTexel = screenSize - uint16_t2 (1 ,1 );
39
105
switch (transform)
40
106
{
@@ -66,8 +132,9 @@ uint16_t2 applyInverseToScreenSpaceCoordinate(const FLAG_BITS transform, const u
66
132
// ! Warning: Be aware that almost always you'd want to do a single transform in your rendering pipeline.
67
133
uint16_t2 applyToScreenSpaceCoordinate (const FLAG_BITS transform, const uint16_t2 coord, const uint16_t2 screenSize)
68
134
{
69
- const uint16_t2 lastTexel = screenSize - uint16_t2 (1 );
70
- switch (swapchainTransform)
135
+ // TODO: use transformMatrix(transform) somehow
136
+ const uint16_t2 lastTexel = screenSize - uint16_t2 (1 , 1 );
137
+ switch (transform)
71
138
{
72
139
case FLAG_BITS::IDENTITY_BIT:
73
140
return coord;
@@ -91,56 +158,13 @@ uint16_t2 applyToScreenSpaceCoordinate(const FLAG_BITS transform, const uint16_t
91
158
return uint16_t2 (0 );
92
159
}
93
160
94
- // ! [width,height] might switch to [height, width] in orientations such as 90°CW
95
- // ! Usecase: Find out how big the viewport has to be after or before a tranform is applied
96
- uint16_t2 transformedExtents (const FLAG_BITS transform, const uint16_t2 screenSize)
97
- {
98
- switch (swapchainTransform)
99
- {
100
- case FLAG_BITS::IDENTITY_BIT:
101
- case FLAG_BITS::HORIZONTAL_MIRROR_BIT:
102
- case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_180_BIT:
103
- case FLAG_BITS::ROTATE_180_BIT:
104
- return screenSize;
105
- case FLAG_BITS::ROTATE_90_BIT:
106
- case FLAG_BITS::ROTATE_270_BIT:
107
- case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_90_BIT:
108
- case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_270_BIT:
109
- return screenSize.yx ;
110
- default :
111
- break ;
112
- }
113
- return uint16_t2 (0 );
114
- }
115
-
116
161
// ! Same as `applyToScreenSpaceCoordinate` but const NDC space
117
162
// ! If rendering to the swapchain, you may use this function to transform the NDC coordinates directly
118
163
// ! to be fed into gl_Position in vertex shading
119
164
// ! Warning: Be aware that almost always you'd want to do a single transform in your rendering pipeline.
120
165
float32_t2 applyToNDC (const FLAG_BITS transform, const float32_t2 ndc)
121
166
{
122
- switch (swapchainTransform)
123
- {
124
- case FLAG_BITS::IDENTITY_BIT:
125
- return ndc;
126
- case FLAG_BITS::ROTATE_90_BIT:
127
- return float32_t2 (-ndc.y ,ndc.x );
128
- case FLAG_BITS::ROTATE_180_BIT:
129
- return -ndc;
130
- case FLAG_BITS::ROTATE_270_BIT:
131
- return float32_t2 (ndc.y ,-ndc.x );
132
- case FLAG_BITS::HORIZONTAL_MIRROR_BIT:
133
- return float32_t2 (-ndc.x ,ndc.y );
134
- case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_90_BIT:
135
- return ndc.yx ;
136
- case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_180_BIT:
137
- return float32_t2 (ndc.x ,-ndc.y );
138
- case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_270_BIT:
139
- return -ndc.yx ;
140
- default :
141
- break ;
142
- }
143
- return float32_t2 (0 ,0 )/0 .f ;
167
+ return mul (transformMatrix (transform),ndc);
144
168
}
145
169
146
170
// TODO: This is untested
@@ -149,37 +173,8 @@ float32_t2 applyToNDC(const FLAG_BITS transform, const float32_t2 ndc)
149
173
template <typename TwoColumns>
150
174
TwoColumns applyToDerivatives (const FLAG_BITS transform, TwoColumns dDx_dDy)
151
175
{
152
- switch (swapchainTransform)
153
- {
154
- case FLAG_BITS::IDENTITY_BIT:
155
- return dDx_dDy;
156
- case FLAG_BITS::ROTATE_90_BIT:
157
- return mul (dDx_dDy,float32_t2x2 ( 0 .f ,-1 .f
158
- 1 .f , 0 .f ));
159
- case FLAG_BITS::ROTATE_180_BIT:
160
- return mul (dDx_dDy,float32_t2x2 (-1 .f , 0 .f
161
- 0 .f ,-1 .f ));
162
- case FLAG_BITS::ROTATE_270_BIT:
163
- return mul (dDx_dDy,float32_t2x2 ( 0 .f , 1 .f
164
- -1 .f , 0 .f ));
165
- case FLAG_BITS::HORIZONTAL_MIRROR_BIT:
166
- return mul (dDx_dDy,float32_t2x2 (-1 .f , 0 .f
167
- 0 .f , 1 .f ));
168
- case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_90_BIT:
169
- return mul (dDx_dDy,float32_t2x2 ( 0 .f , 1 .f
170
- 1 .f , 0 .f ));
171
- case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_180_BIT:
172
- return mul (dDx_dDy,float32_t2x2 ( 1 .f , 0 .f
173
- 0 .f ,-1 .f ));
174
- case FLAG_BITS::HORIZONTAL_MIRROR_ROTATE_270_BIT:
175
- return mul (dDx_dDy,float32_t2x2 ( 0 .f ,-1 .f
176
- -1 .f , 0 .f ));
177
- default :
178
- break ;
179
- }
180
- return dDx_dDy*(0 .f /0 .f );
176
+ return mul (inverse (transformMatrix (transform)),dDx_dDy);
181
177
}
182
- // TODO: could define the NDC in terms of inverse Derivative XForm
183
178
184
179
}
185
180
}
0 commit comments