@@ -128,6 +128,17 @@ class PBR_Renderer
128128 JOINTS_BUFFER_MODE_STRUCTURED,
129129 };
130130
131+ // / Vertex position packing mode.
132+ enum VERTEX_POS_PACK_MODE : Uint8
133+ {
134+ // / Vertex positions are not packed and are stored as float3.
135+ VERTEX_POS_PACK_MODE_NONE = 0 ,
136+
137+ // / Vertex positoins are packed into two 32-bit uints using
138+ // / 21 bits for normalized x, y, z coordinates, see PackVertxPos64().
139+ VERTEX_POS_PACK_MODE_64_BIT,
140+ };
141+
131142 // / Renderer create info
132143 struct CreateInfo
133144 {
@@ -205,6 +216,9 @@ class PBR_Renderer
205216 // / Whether vertex normals are packed into a single 32-bit uint, see PackVertexNormal().
206217 bool PackVertexNormals = false ;
207218
219+ // / Vertex position packing mode, see VERTEX_POS_PACK_MODE.
220+ VERTEX_POS_PACK_MODE VertexPosPackMode = VERTEX_POS_PACK_MODE_NONE;
221+
208222 // / PCF shadow kernel size.
209223 // / Allowed values are 2, 3, 5, 7.
210224 Uint32 PCFKernelSize = 3 ;
@@ -727,7 +741,15 @@ class PBR_Renderer
727741 // / Packs normal into a single 32-bit uint.
728742 // /
729743 // / \remarks The function assumes that the input vector is normalized.
730- static Uint32 PackVertexNormal (const float3& Normal);
744+ static inline Uint32 PackVertexNormal (const float3& Normal);
745+
746+ // / Packs vertex position into two 32-bit uints.
747+ // /
748+ // / \remarks Bias and Scale are used to map the vertex position to the [0, 1] range as follows:
749+ // / NormPos = (Pos + Bias) * Scale
750+ // / Typically, Bias is set to the negated minimum vertex position and Scale is set to
751+ // / one over the maximum vertex position minus the minimum vertex position.
752+ static inline void PackVertexPos64 (const float3& Pos, const float3& Bias, const float3& Scale, Uint32& U0, Uint32& U1);
731753
732754protected:
733755 ShaderMacroHelper DefineMacros (const PSOKey& Key) const ;
@@ -906,4 +928,25 @@ inline void PBR_Renderer::ProcessTexturAttribs(PBR_Renderer::PSO_FLAGS PSOFlags,
906928 }
907929}
908930
931+ inline Uint32 PBR_Renderer::PackVertexNormal (const float3& Normal)
932+ {
933+ Uint32 x = static_cast <Uint32>(clamp ((Normal.x + 1 .f ) * 32767 .f , 0 .f , 65535 .f ));
934+ Uint32 y = static_cast <Uint32>(clamp ((Normal.y + 1 .f ) * 16383 .f , 0 .f , 32767 .f ));
935+ Uint32 z = Normal.z >= 0 ? 0 : 1 ;
936+ return x | (y << 16 ) | (z << 31 );
937+ }
938+
939+ inline void PBR_Renderer::PackVertexPos64 (const float3& Pos, const float3& Bias, const float3& Scale, Uint32& U0, Uint32& U1)
940+ {
941+ // X Y Y Z
942+ // | 0 ... 20 | 21 ... 31| | 0 ... 9 | 10 ... 30 |
943+ // 21 11 10 21
944+ constexpr float3 U21Scale{static_cast <float >((1 << 21 ) - 1 )};
945+ const float3 NormPos = (Pos + Bias) * Scale;
946+ const uint3 U21Pos = clamp (NormPos * U21Scale, float3{0 }, U21Scale).Recast <uint>();
947+
948+ U0 = U21Pos.x | (U21Pos.y << 21u );
949+ U1 = (U21Pos.y >> 11u ) | (U21Pos.z << 10u );
950+ }
951+
909952} // namespace Diligent
0 commit comments