diff --git a/MAGE/Shaders.vcxproj b/MAGE/Shaders.vcxproj index d76e90c5a..c089a2a66 100644 --- a/MAGE/Shaders.vcxproj +++ b/MAGE/Shaders.vcxproj @@ -2181,6 +2181,7 @@ + diff --git a/MAGE/Shaders.vcxproj.filters b/MAGE/Shaders.vcxproj.filters index fbd5d421f..f57db6a4f 100644 --- a/MAGE/Shaders.vcxproj.filters +++ b/MAGE/Shaders.vcxproj.filters @@ -549,6 +549,9 @@ Shader Files + + Shader Files + diff --git a/MAGE/Shaders/shaders/falsecolor/shading_normal_PS.hlsl b/MAGE/Shaders/shaders/falsecolor/shading_normal_PS.hlsl index 67d4fce10..dea28678e 100644 --- a/MAGE/Shaders/shaders/falsecolor/shading_normal_PS.hlsl +++ b/MAGE/Shaders/shaders/falsecolor/shading_normal_PS.hlsl @@ -27,5 +27,5 @@ float4 PS(PSInputPositionNormalTexture input) : SV_Target { const float3 n_world = GetNormal(input.p_world, input.n_world, input.tex_geometry); - return float4(EncodeNormal_XYZ(n_world), 1.0f); + return float4(EncodeUnitVector_XYZ(n_world), 1.0f); } \ No newline at end of file diff --git a/MAGE/Shaders/shaders/falsecolor/tsnm_shading_normal_PS.hlsl b/MAGE/Shaders/shaders/falsecolor/tsnm_shading_normal_PS.hlsl index 7a23747b8..6c2d6bf10 100644 --- a/MAGE/Shaders/shaders/falsecolor/tsnm_shading_normal_PS.hlsl +++ b/MAGE/Shaders/shaders/falsecolor/tsnm_shading_normal_PS.hlsl @@ -26,5 +26,5 @@ float4 PS(PSInputPositionNormalTexture input) : SV_Target { const float3 n_world = GetNormal(input.p_world, input.n_world, input.tex_geometry); - return float4(EncodeNormal_XYZ(n_world), 1.0f); + return float4(EncodeUnitVector_XYZ(n_world), 1.0f); } \ No newline at end of file diff --git a/MAGE/Shaders/shaders/normal.hlsli b/MAGE/Shaders/shaders/normal.hlsli index 0a6638726..1cda352aa 100644 --- a/MAGE/Shaders/shaders/normal.hlsli +++ b/MAGE/Shaders/shaders/normal.hlsli @@ -6,200 +6,36 @@ //----------------------------------------------------------------------------- // Defines | Default //----------------------------------------------------------------------------- -// NORMAL_DECODE_FUNCTION | DecodeNormal_Octahedron -// NORMAL_ENCODE_FUNCTION | EncodeNormal_Octahedron -// TSNM_DECODE_FUNCTION | DecodeNormal_XY -// TSNM_ENCODE_FUNCTION | EncodeNormal_XY +// NORMAL_DECODE_FUNCTION | DecodeUnitVector_Octahedron +// NORMAL_ENCODE_FUNCTION | EncodeUnitVector_Octahedron +// TSNM_DECODE_FUNCTION | DecodeUnitVector_XY +// TSNM_ENCODE_FUNCTION | EncodeUnitVector_XY //----------------------------------------------------------------------------- // Engine Includes //----------------------------------------------------------------------------- -#include "math.hlsli" +#include "unit_vector.hlsli" //----------------------------------------------------------------------------- // Engine Defines //----------------------------------------------------------------------------- #ifndef NORMAL_ENCODE_FUNCTION - #define NORMAL_ENCODE_FUNCTION EncodeNormal_Octahedron + #define NORMAL_ENCODE_FUNCTION EncodeUnitVector_Octahedron #endif // NORMAL_ENCODE_FUNCTION #ifndef NORMAL_DECODE_FUNCTION - #define NORMAL_DECODE_FUNCTION DecodeNormal_Octahedron + #define NORMAL_DECODE_FUNCTION DecodeUnitVector_Octahedron #endif // NORMAL_DECODE_FUNCTION #ifndef TSNM_ENCODE_FUNCTION - #define TSNM_ENCODE_FUNCTION EncodeNormal_XY + #define TSNM_ENCODE_FUNCTION EncodeUnitVector_XY #endif // TSNM_ENCODE_FUNCTION #ifndef TSNM_DECODE_FUNCTION - #define TSNM_DECODE_FUNCTION DecodeNormal_XY + #define TSNM_DECODE_FUNCTION DecodeUnitVector_XY #endif // TSNM_DECODE_FUNCTION -//----------------------------------------------------------------------------- -// Engine Declarations and Definitions: Normal Encoding/Decoding -//----------------------------------------------------------------------------- - -/** - Encodes the given normal from the [0,1] range to the [-1,1] range using a XYZ - encoding. - - @pre @a n is normalized. - @param[in] n - The normal in the [0,1] range to convert. - @return The encoded normal in the [-1,1] range. - */ -float3 EncodeNormal_XYZ(float3 n) { - return SNORMtoUNORM(n); -} - -/** - Decodes the given normal from the [0,1] range to the [-1,1] range using a XYZ - decoding. - - @param[in] n_unorm - The normal in the [0,1] range to convert. - @return The decoded normal in the [-1,1] range. - */ -float3 DecodeNormal_XYZ(float3 n_unorm) { - return UNORMtoSNORM(n_unorm); -} - -/** - Encodes the given normal from the [0,1] range to the [-1,1] range using a XY - encoding. - - @pre @a n is normalized. - @param[in] n - The normal in the [0,1] range to convert. - @return The encoded normal in the [-1,1] range. - */ -float2 EncodeNormal_XY(float3 n) { - return EncodeNormal_XYZ(n).xy; -} - -/** - Decodes the given normal from the [0,1] range to the [-1,1] range using a XY - decoding. - - The z component will be positive and will be calculated from the x and y - components. - - @param[in] n_unorm - The normal in the [0,1] range to convert. - @return The decoded normal in the [-1,1] range. - */ -float3 DecodeNormal_XY(float2 n_unorm) { - const float2 n_xy = UNORMtoSNORM(n_unorm); - const float n_z = sqrt(1.0f - dot(n_xy, n_xy)); - return float3(n_xy, n_z); -} - -/** - Encodes the given normal from the [0,1] range to the [-1,1] range using a - spherical encoding. - - @pre @a n is normalized. - @param[in] n - The normal in the [0,1] range to convert. - @return The encoded normal in the [-1,1] range. - */ -float2 EncodeNormal_Spherical(float3 n) { - const float phi = atan2(n.y, n.x); - const float cos_theta = n.z; - return SNORMtoUNORM(float2(phi * g_inv_pi, cos_theta)); -} - -/** - Decodes the given normal from the [0,1] range to the [-1,1] range using a - spherical decoding. - - @param[in] n_unorm - The normal in the [0,1] range to convert. - @return The decoded normal in the [-1,1] range. - */ -float3 DecodeNormal_Spherical(float2 n_unorm) { - const float2 n_snorm = UNORMtoSNORM(n_unorm); - - const float phi = n_snorm.x * g_pi; - float sin_phi; - float cos_phi; - sincos(phi, sin_phi, cos_phi); - - const float cos_theta = n_snorm.y; - const float sin_theta = CosToSin(cos_theta); - - return float3(cos_phi * sin_theta, - sin_phi * sin_theta, - cos_theta); -} - -/** - Encodes the given normal from the [0,1] range to the [-1,1] range using a - spheremap encoding. - - @pre @a n is normalized. - @param[in] n - The normal in the [0,1] range to convert. - @return The encoded normal in the [-1,1] range. - */ -float2 EncodeNormal_SphereMap(float3 n) { - const float2 n_snorm = normalize(n.xy) * sqrt(SNORMtoUNORM(-n.z)); - return SNORMtoUNORM(n_snorm); -} - -/** - Decodes the given normal from the [0,1] range to the [-1,1] range using a - spheremap decoding. - - @param[in] n_unorm - The normal in the [0,1] range to convert. - @return The encoded normal in the [-1,1] range. - */ -float3 DecodeNormal_SphereMap(float2 n_unorm) { - const float2 n_snorm = UNORMtoSNORM(n_unorm); - const float4 n0 = float4(n_snorm, 1.0f, -1.0f); - const float l = dot(n0.xyz, -n0.xyw); - return 2.0f * float3(n0.xy * sqrt(l), l - 0.5f); -} - -float2 OctahedronWrap(float2 v) { - return (1.0f - abs(v.yx)) * (0.0f <= v.xy ? 1.0f : -1.0f); -} - -/** - Encodes the given normal from the [0,1] range to the [-1,1] range using a - octahedron encoding. - - @pre @a n is normalized. - @param[in] n - The normal in the [0,1] range to convert. - @return The encoded normal in the [-1,1] range. - */ -float2 EncodeNormal_Octahedron(float3 n) { - const float3 abs_n = abs(n); - const float3 n0 = n / (abs_n.x + abs_n.y + abs_n.z); - const float2 n_snorm = (0.0f <= n0.z) ? n0.xy : OctahedronWrap(n0.xy); - return SNORMtoUNORM(n_snorm); -} - -/** - Decodes the given normal from the [0,1] range to the [-1,1] range using a - octahedron decoding. - - @param[in] n_unorm - The normal in the [0,1] range to convert. - @return The encoded normal in the [-1,1] range. - */ -float3 DecodeNormal_Octahedron(float2 n_unorm) { - const float2 n_snorm = UNORMtoSNORM(n_unorm); - const float3 n0 = float3(n_snorm.x, n_snorm.y, - 1.0f - abs(n_snorm.x) - abs(n_snorm.y)); - const float t = saturate(-n0.z); - const float2 c_xy = n0.xy + (0.0f <= n0.xy ? -t : t); - return normalize(float3(c_xy, n0.z)); -} - //----------------------------------------------------------------------------- // Engine Declarations and Definitions: Normal Mapping //----------------------------------------------------------------------------- diff --git a/MAGE/Shaders/shaders/unit_vector.hlsli b/MAGE/Shaders/shaders/unit_vector.hlsli new file mode 100644 index 000000000..dc4b4efea --- /dev/null +++ b/MAGE/Shaders/shaders/unit_vector.hlsli @@ -0,0 +1,173 @@ +#ifndef MAGE_HEADER_UNIT_VECTOR +#define MAGE_HEADER_UNIT_VECTOR + +//----------------------------------------------------------------------------- +// Engine Includes +//----------------------------------------------------------------------------- +#include "math.hlsli" + +//----------------------------------------------------------------------------- +// Engine Declarations and Definitions +//----------------------------------------------------------------------------- + +/** + Encodes the given unit vector from the [-1,1] range to the [0,1] range using a + XYZ encoding. + + @pre @a u is unit vectorized. + @param[in] u + The unit vector in the [0,1] range to convert. + @return The encoded unit vector in the [-1,1] range. + */ +float3 EncodeUnitVector_XYZ(float3 u) { + return SNORMtoUNORM(u); +} + +/** + Decodes the given unit vector from the [0,1] range to the [-1,1] range using a + XYZ decoding. + + @param[in] e_unorm + The encoded unit vector in the [0,1] range to convert. + @return The decoded unit vector in the [-1,1] range. + */ +float3 DecodeUnitVector_XYZ(float3 e_unorm) { + return UNORMtoSNORM(e_unorm); +} + +/** + Encodes the given unit vector from the [-1,1] range to the [0,1] range using a + XY encoding. + + @pre @a u is unit vectorized. + @param[in] u + The unit vector in the [0,1] range to convert. + @return The encoded unit vector in the [-1,1] range. + */ +float2 EncodeUnitVector_XY(float3 u) { + return EncodeUnitVector_XYZ(u).xy; +} + +/** + Decodes the given unit vector from the [0,1] range to the [-1,1] range using a + XY decoding. + + The z component will be positive and will be calculated from the x and y + components. + + @param[in] e_unorm + The encoded unit vector in the [0,1] range to convert. + @return The decoded unit vector in the [-1,1] range. + */ +float3 DecodeUnitVector_XY(float2 e_unorm) { + const float2 u_xy = UNORMtoSNORM(e_unorm); + const float u_z = sqrt(1.0f - dot(u_xy, u_xy)); + return float3(u_xy, u_z); +} + +/** + Encodes the given unit vector from the [-1,1] range to the [0,1] range using a + spherical encoding. + + @pre @a u is unit vectorized. + @param[in] u + The unit vector in the [0,1] range to convert. + @return The encoded unit vector in the [-1,1] range. + */ +float2 EncodeUnitVector_Spherical(float3 u) { + const float phi = atan2(u.y, u.x); + const float cos_theta = u.z; + return SNORMtoUNORM(float2(phi * g_inv_pi, cos_theta)); +} + +/** + Decodes the given unit vector from the [0,1] range to the [-1,1] range using a + spherical decoding. + + @param[in] e_unorm + The encoded unit vector in the [0,1] range to convert. + @return The decoded unit vector in the [-1,1] range. + */ +float3 DecodeUnitVector_Spherical(float2 e_unorm) { + const float2 e_snorm = UNORMtoSNORM(e_unorm); + + const float phi = e_snorm.x * g_pi; + float sin_phi; + float cos_phi; + sincos(phi, sin_phi, cos_phi); + + const float cos_theta = e_snorm.y; + const float sin_theta = CosToSin(cos_theta); + + return float3(cos_phi * sin_theta, + sin_phi * sin_theta, + cos_theta); +} + +/** + Encodes the given unit vector from the [-1,1] range to the [0,1] range using a + spheremap encoding. + + @pre @a u is unit vectorized. + @param[in] u + The unit vector in the [0,1] range to convert. + @return The encoded unit vector in the [-1,1] range. + */ +float2 EncodeUnitVector_SphereMap(float3 u) { + const float2 e_snorm = normalize(u.xy) * sqrt(SNORMtoUNORM(-u.z)); + return SNORMtoUNORM(e_snorm); +} + +/** + Decodes the given unit vector from the [0,1] range to the [-1,1] range using a + spheremap decoding. + + @param[in] e_unorm + The encoded unit vector in the [0,1] range to convert. + @return The decoded unit vector in the [-1,1] range. + */ +float3 DecodeUnitVector_SphereMap(float2 e_unorm) { + const float2 e_snorm = UNORMtoSNORM(e_unorm); + const float4 e0 = float4(e_snorm, 1.0f, -1.0f); + const float l = dot(e0.xyz, -e0.xyw); + return 2.0f * float3(e0.xy * sqrt(l), l - 0.5f); +} + +float2 OctahedronWrap(float2 v) { + return (1.0f - abs(v.yx)) * (0.0f <= v.xy ? 1.0f : -1.0f); +} + +/** + Encodes the given unit vector from the [-1,1] range to the [0,1] range using a + octahedron encoding. + + @pre @a u is unit vectorized. + @param[in] u + The unit vector in the [0,1] range to convert. + @return The encoded unit vector in the [-1,1] range. + */ +float2 EncodeUnitVector_Octahedron(float3 u) { + const float3 abs_u = abs(u); + const float3 u0 = u / (abs_u.x + abs_u.y + abs_u.z); + const float2 e_snorm = (0.0f <= u0.z) ? u0.xy : OctahedronWrap(u0.xy); + return SNORMtoUNORM(e_snorm); +} + +/** + Decodes the given unit vector from the [0,1] range to the [-1,1] range using a + octahedron decoding. + + @param[in] e_unorm + The encoded unit vector in the [0,1] range to convert. + @return The decoded unit vector in the [-1,1] range. + */ +float3 DecodeUnitVector_Octahedron(float2 e_unorm) { + const float2 e_snorm = UNORMtoSNORM(e_unorm); + const float3 e0 = float3(e_snorm.x, e_snorm.y, + 1.0f - abs(e_snorm.x) - abs(e_snorm.y)); + const float t = saturate(-e0.z); + const float2 u_xy = e0.xy + (0.0f <= e0.xy ? -t : t); + return normalize(float3(u_xy, e0.z)); +} + +#endif // MAGE_HEADER_UNIT_VECTOR \ No newline at end of file diff --git a/MAGE/Shaders/shaders/voxelization/voxel.hlsli b/MAGE/Shaders/shaders/voxelization/voxel.hlsli index 0768b3e03..29408a2f6 100644 --- a/MAGE/Shaders/shaders/voxelization/voxel.hlsli +++ b/MAGE/Shaders/shaders/voxelization/voxel.hlsli @@ -24,12 +24,12 @@ float3 DecodeRadiance(uint encoded_L) { return LogLuvToRGB(UnpackR8G8B8A8(encoded_L)); } -uint EncodeNormal(float3 n) { - return PackR16G16(EncodeNormal_Octahedron(n)); +uint EncodeUnitVector(float3 n) { + return PackR16G16(NORMAL_ENCODE_FUNCTION(n)); } -float3 DecodeNormal(uint encoded_n) { - return DecodeNormal_Octahedron(UnpackR16G16(encoded_n)); +float3 DecodeUnitVector(uint encoded_n) { + return NORMAL_DECODE_FUNCTION(UnpackR16G16(encoded_n)); } #endif // MAGE_HEADER_VOXEL \ No newline at end of file diff --git a/MAGE/Shaders/shaders/voxelization/voxelization.hlsli b/MAGE/Shaders/shaders/voxelization/voxelization.hlsli index b9947f166..67490b187 100644 --- a/MAGE/Shaders/shaders/voxelization/voxelization.hlsli +++ b/MAGE/Shaders/shaders/voxelization/voxelization.hlsli @@ -75,7 +75,7 @@ void PS(PSInputPositionNormalTexture input) { // Encode the radiance and normal. const uint encoded_L = EncodeRadiance(L); - const uint endoced_n = EncodeNormal(n_world); + const uint endoced_n = EncodeUnitVector(n_world); // Store the encoded radiance and normal. InterlockedMax(voxel_grid[flat_index].encoded_L, encoded_L); InterlockedMax(voxel_grid[flat_index].encoded_n, endoced_n); //TODO