A game about forced loneliness, made by TACStudios
1#ifndef DECODE_SH 2# define DECODE_SH 3 4// TODO: We're working on irradiance instead of radiance coefficients 5// Add safety margin 2 to avoid out-of-bounds values 6#define APV_L1_ENCODING_SCALE 2.0 // Should be: 3/(2*sqrt(3)) * 2, but rounding to 2 to issues we are observing. 7#define APV_L2_ENCODING_SCALE 3.5777088 // 4/sqrt(5) * 2 8 9float3 DecodeSH(float l0, float3 l1) 10{ 11 return (l1 - 0.5f) * (2.0f * APV_L1_ENCODING_SCALE * l0); 12} 13 14void DecodeSH_L2(inout float3 l0, inout float4 l2_R, inout float4 l2_G, inout float4 l2_B, inout float3 l2_C) 15{ 16 l2_R = (l2_R - 0.5f) * (APV_L2_ENCODING_SCALE * l0.r); 17 l2_G = (l2_G - 0.5f) * (APV_L2_ENCODING_SCALE * l0.g); 18 l2_B = (l2_B - 0.5f) * (APV_L2_ENCODING_SCALE * l0.b); 19 l2_C = (l2_C - 0.5f) * APV_L2_ENCODING_SCALE; 20 21 l2_C.rgb *= l0; 22 23 // Account for how L2 is encoded. 24 l0.r -= l2_R.z; 25 l0.g -= l2_G.z; 26 l0.b -= l2_B.z; 27 l2_R.z *= 3.0f; 28 l2_G.z *= 3.0f; 29 l2_B.z *= 3.0f; 30} 31 32void DecodeSH_L2(inout float3 l0, inout float4 l2_R, inout float4 l2_G, inout float4 l2_B, inout float4 l2_C) 33{ 34 float3 outL2_C = l2_C.xyz; 35 DecodeSH_L2(l0, l2_R, l2_G, l2_B, outL2_C); 36 l2_C = float4(outL2_C.xyz, 0); 37} 38 39half3 DecodeSH(half l0, half3 l1) 40{ 41 return (l1 - 0.5) * (2.0 * APV_L1_ENCODING_SCALE * l0); 42} 43 44void DecodeSH_L2(inout half3 l0, inout half4 l2_R, inout half4 l2_G, inout half4 l2_B, inout half3 l2_C) 45{ 46 l2_R = (l2_R - 0.5) * (APV_L2_ENCODING_SCALE * l0.r); 47 l2_G = (l2_G - 0.5) * (APV_L2_ENCODING_SCALE * l0.g); 48 l2_B = (l2_B - 0.5) * (APV_L2_ENCODING_SCALE * l0.b); 49 l2_C = (l2_C - 0.5) * APV_L2_ENCODING_SCALE; 50 51 l2_C.rgb *= l0; 52 53 // Account for how L2 is encoded. 54 l0.r -= l2_R.z; 55 l0.g -= l2_G.z; 56 l0.b -= l2_B.z; 57 l2_R.z *= 3.0; 58 l2_G.z *= 3.0; 59 l2_B.z *= 3.0; 60} 61 62void DecodeSH_L2(inout half3 l0, inout half4 l2_R, inout half4 l2_G, inout half4 l2_B, inout half4 l2_C) 63{ 64 half3 outL2_C = l2_C.xyz; 65 DecodeSH_L2(l0, l2_R, l2_G, l2_B, outL2_C); 66 l2_C = half4(outL2_C.xyz, 0); 67} 68 69float3 EncodeSH(float l0, float3 l1) 70{ 71 return l0 == 0.0f ? 0.5f : l1 * rcp(l0) / (2.0f * APV_L1_ENCODING_SCALE) + 0.5f; 72} 73 74#if !HALF_IS_FLOAT 75half3 EncodeSH(half l0, half3 l1) 76{ 77 return l0 == 0.0 ? 0.5 : l1 * rcp(l0) / (2.0 * APV_L1_ENCODING_SCALE) + 0.5; 78} 79#endif 80 81void EncodeSH_L2(inout float3 l0, inout float4 l2_R, inout float4 l2_G, inout float4 l2_B, inout float3 l2_C) 82{ 83 // Account for how L2 is encoded. 84 l2_R.z /= 3.0f; 85 l2_G.z /= 3.0f; 86 l2_B.z /= 3.0f; 87 l0.r += l2_R.z; 88 l0.g += l2_G.z; 89 l0.b += l2_B.z; 90 91 float3 rcpl0 = rcp(l0); 92 rcpl0 = float3(l0.x == 0.0f ? 0.0f : rcpl0.x, l0.y == 0.0f ? 0.0f : rcpl0.y, l0.z == 0.0f ? 0.0f : rcpl0.z); 93 94 l2_R = 0.5f + l2_R * rcp(APV_L2_ENCODING_SCALE) * rcpl0.r; 95 l2_G = 0.5f + l2_G * rcp(APV_L2_ENCODING_SCALE) * rcpl0.g; 96 l2_B = 0.5f + l2_B * rcp(APV_L2_ENCODING_SCALE) * rcpl0.b; 97 l2_C = 0.5f + l2_C * rcp(APV_L2_ENCODING_SCALE) * rcpl0; 98} 99 100#endif // DECODE_SH