48 lines
1.5 KiB
HLSL
48 lines
1.5 KiB
HLSL
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
|
|
|
#ifndef __OCTAHEDRAL__
|
|
#define __OCTAHEDRAL__
|
|
|
|
// Implementation based on:
|
|
// "A Survey of Efficient Representations for Independent Unit Vectors", Journal of Computer Graphics Tools (JCGT), vol. 3, no. 2, 1-30, 2014
|
|
// Zina H. Cigolle, Sam Donow, Daniel Evangelakos, Michael Mara, Morgan McGuire, and Quirin Meyer
|
|
// http://jcgt.org/published/0003/02/01/
|
|
|
|
float GetSignNotZero(float v)
|
|
{
|
|
return v >= 0.0f ? 1.0f : -1.0f;
|
|
}
|
|
|
|
float2 GetSignNotZero(float2 v)
|
|
{
|
|
return float2(GetSignNotZero(v.x), GetSignNotZero(v.y));
|
|
}
|
|
|
|
// Calculates octahedral coordinates (in range [-1; 1]) for direction vector
|
|
float2 GetOctahedralCoords(float3 direction)
|
|
{
|
|
float2 uv = direction.xy * (1.0f / (abs(direction.x) + abs(direction.y) + abs(direction.z)));
|
|
if (direction.z < 0.0f)
|
|
uv = (1.0f - abs(uv.yx)) * GetSignNotZero(uv.xy);
|
|
return uv;
|
|
}
|
|
|
|
// Calculates octahedral coordinates (in range [-1; 1]) for 2D texture (assuming 1 pixel border around)
|
|
float2 GetOctahedralCoords(uint2 texCoords, uint resolution)
|
|
{
|
|
float2 uv = float2(texCoords.x % resolution, texCoords.y % resolution) + 0.5f;
|
|
uv.xy /= float(resolution);
|
|
return uv * 2.0f - 1.0f;
|
|
}
|
|
|
|
// Gets the direction vector from octahedral coordinates
|
|
float3 GetOctahedralDirection(float2 coords)
|
|
{
|
|
float3 direction = float3(coords.x, coords.y, 1.0f - abs(coords.x) - abs(coords.y));
|
|
if (direction.z < 0.0f)
|
|
direction.xy = (1.0f - abs(direction.yx)) * GetSignNotZero(direction.xy);
|
|
return normalize(direction);
|
|
}
|
|
|
|
#endif
|