98 lines
4.4 KiB
HLSL
98 lines
4.4 KiB
HLSL
// we use this to prevent artifacts with half (16bit) moments
|
|
// this is only for power moments as trigonometric moments do not suffer as much from rounding errors (quote from the guys who actually did this technique)
|
|
// see https://momentsingraphics.de/I3D2018.html
|
|
|
|
// Definition of utility functions for quantization and dequantization of power moments stored in 16 bits per moment
|
|
|
|
// NOTE : It seems that ROVs are necessary for this to work, unfortunately this is out of scope for now
|
|
|
|
// 4 MOMENTS
|
|
void offsetMoments(inout float2 b_even, inout float2 b_odd, float sign)
|
|
{
|
|
b_odd += 0.5 * sign;
|
|
}
|
|
|
|
void quantizeMoments(out float2 b_even_q, out float2 b_odd_q, float2 b_even, float2 b_odd)
|
|
{
|
|
b_odd_q = mul(b_odd, float2x2(1.5f, sqrt(3.0f) * 0.5f, -2.0f, -sqrt(3.0f) * 2.0f / 9.0f));
|
|
b_even_q = mul(b_even, float2x2(4.0f, 0.5f, -4.0f, 0.5f));
|
|
}
|
|
|
|
void offsetAndDequantizeMoments(out float2 b_even, out float2 b_odd, float2 b_even_q, float2 b_odd_q)
|
|
{
|
|
offsetMoments(b_even_q, b_odd_q, -1.0);
|
|
b_odd = mul(b_odd_q, float2x2(-1.0f / 3.0f, -0.75f, sqrt(3.0f), 0.75f * sqrt(3.0f)));
|
|
b_even = mul(b_even_q, float2x2(0.125f, -0.125f, 1.0f, 1.0f));
|
|
}
|
|
|
|
// 6 MOMENTS
|
|
void offsetMoments(inout float3 b_even, inout float3 b_odd, float sign)
|
|
{
|
|
b_odd += 0.5 * sign;
|
|
b_even.z += 0.018888946f * sign;
|
|
}
|
|
|
|
void quantizeMoments(out float3 b_even_q, out float3 b_odd_q, float3 b_even, float3 b_odd)
|
|
{
|
|
const float3x3 QuantizationMatrixOdd = float3x3(
|
|
2.5f, -1.87499864450f, 1.26583039016f,
|
|
-10.0f, 4.20757543111f, -1.47644882902f,
|
|
8.0f, -1.83257678661f, 0.71061660238f);
|
|
const float3x3 QuantizationMatrixEven = float3x3(
|
|
4.0f, 9.0f, -0.57759806484f,
|
|
-4.0f, -24.0f, 4.61936647543f,
|
|
0.0f, 16.0f, -3.07953906655f);
|
|
b_odd_q = mul(b_odd, QuantizationMatrixOdd);
|
|
b_even_q = mul(b_even, QuantizationMatrixEven);
|
|
}
|
|
|
|
void offsetAndDequantizeMoments(out float3 b_even, out float3 b_odd, float3 b_even_q, float3 b_odd_q)
|
|
{
|
|
const float3x3 QuantizationMatrixOdd = float3x3(
|
|
-0.02877789192f, 0.09995235706f, 0.25893353755f,
|
|
0.47635550422f, 0.84532580931f, 0.90779616657f,
|
|
1.55242808973f, 1.05472570761f, 0.83327335647f);
|
|
const float3x3 QuantizationMatrixEven = float3x3(
|
|
0.00001253044f, -0.24998746956f, -0.37498825271f,
|
|
0.16668494186f, 0.16668494186f, 0.21876713299f,
|
|
0.86602540579f, 0.86602540579f, 0.81189881793f);
|
|
offsetMoments(b_even_q, b_odd_q, -1.0);
|
|
b_odd = mul(b_odd_q, QuantizationMatrixOdd);
|
|
b_even = mul(b_even_q, QuantizationMatrixEven);
|
|
}
|
|
|
|
// 8 MOMENTS
|
|
void offsetMoments(inout float4 b_even, inout float4 b_odd, float sign)
|
|
{
|
|
b_odd += 0.5 * sign;
|
|
b_even += float4(0.972481993925964, 1.0, 0.999179192513328, 0.991778293073131) * sign;
|
|
}
|
|
|
|
void quantizeMoments(out float4 b_even_q, out float4 b_odd_q, float4 b_even, float4 b_odd)
|
|
{
|
|
const float4x4 mat_odd = float4x4(3.48044635732474, -27.5760737514826, 55.1267384344761, -31.5311110403183,
|
|
1.26797185782836, -0.928755808743913, -2.07520453231032, 1.23598848322588,
|
|
-2.1671560004294, 6.17950199592966, -0.276515571579297, -4.23583042392097,
|
|
0.974332879165755, -0.443426830933027, -0.360491648368785, 0.310149466050223);
|
|
const float4x4 mat_even = float4x4(0.280504133158527, -0.757633844606942, 0.392179589334688, -0.887531871812237,
|
|
-2.01362265883247, 0.221551373038988, -1.06107954265125, 2.83887201588367,
|
|
-7.31010494985321, 13.9855979699139, -0.114305766176437, -7.4361899359832,
|
|
-15.8954215629556, 79.6186327084103, -127.457278992502, 63.7349456687829);
|
|
b_odd_q = mul(mat_odd, b_odd);
|
|
b_even_q = mul(mat_even, b_even);
|
|
}
|
|
|
|
void offsetAndDequantizeMoments(out float4 b_even, out float4 b_odd, float4 b_even_q, float4 b_odd_q)
|
|
{
|
|
const float4x4 mat_odd = float4x4(-0.00482399708502382, -0.423201508674231, 0.0348312382605129, 1.67179208266592,
|
|
-0.0233402218644408, -0.832829097046478, 0.0193406040499625, 1.21021509068975,
|
|
-0.010888537031885, -0.926393772997063, -0.11723394414779, 0.983723301818275,
|
|
-0.0308713357806732, -0.937989172670245, -0.218033377677099, 0.845991731322996);
|
|
const float4x4 mat_even = float4x4(-0.976220278891035, -0.456139260269401, -0.0504335521016742, 0.000838800390651085,
|
|
-1.04828341778299, -0.229726640510149, 0.0259608334616091, -0.00133632693205861,
|
|
-1.03115268628604, -0.077844420809897, 0.00443408851014257, -0.0103744938457406,
|
|
-0.996038443434636, 0.0175438624416783, -0.0361414253243963, -0.00317839994022725);
|
|
offsetMoments(b_even_q, b_odd_q, -1.0);
|
|
b_odd = mul(mat_odd, b_odd_q);
|
|
b_even = mul(mat_even, b_even_q);
|
|
} |