mixin SHCommon { code { #define SH_NUM_COEFFS SH_ORDER * SH_ORDER struct SHVector { float v[SH_NUM_COEFFS]; }; struct SHVectorRGB { SHVector R; SHVector G; SHVector B; }; void SHZero(inout SHVector v) { [unroll] for(int i = 0; i < SH_NUM_COEFFS; ++i) v.v[i] = 0; } void SHZero(inout SHVectorRGB v) { SHZero(v.R); SHZero(v.G); SHZero(v.B); } void SHMultiplyAdd(inout SHVector lhs, SHVector rhs, float c) { [unroll] for(int i = 0; i < SH_NUM_COEFFS; ++i) lhs.v[i] += rhs.v[i] * c; } void SHMultiplyAdd(inout SHVectorRGB lhs, SHVectorRGB rhs, float c) { SHMultiplyAdd(lhs.R, rhs.R, c); SHMultiplyAdd(lhs.G, rhs.G, c); SHMultiplyAdd(lhs.B, rhs.B, c); } void SHAdd(inout SHVector lhs, SHVector rhs) { [unroll] for(int i = 0; i < SH_NUM_COEFFS; ++i) lhs.v[i] += rhs.v[i]; } void SHAdd(inout SHVectorRGB lhs, SHVectorRGB rhs) { SHAdd(lhs.R, rhs.R); SHAdd(lhs.G, rhs.G); SHAdd(lhs.B, rhs.B); } void SHMultiply(inout SHVector lhs, SHVector rhs) { [unroll] for(int i = 0; i < SH_NUM_COEFFS; ++i) lhs.v[i] *= rhs.v[i]; } void SHMultiply(inout SHVectorRGB lhs, SHVectorRGB rhs) { SHMultiply(lhs.R, rhs.R); SHMultiply(lhs.G, rhs.G); SHMultiply(lhs.B, rhs.B); } void SHMultiply(inout SHVector lhs, float rhs) { [unroll] for(int i = 0; i < SH_NUM_COEFFS; ++i) lhs.v[i] *= rhs; } void SHMultiply(inout SHVectorRGB lhs, float rhs) { SHMultiply(lhs.R, rhs); SHMultiply(lhs.G, rhs); SHMultiply(lhs.B, rhs); } #if SH_ORDER == 5 SHVector SHBasis(float3 dir) { float x = dir.x; float y = dir.y; float z = dir.z; float x2 = x*x; float y2 = y*y; float z2 = z*z; float z3 = z2 * z; float x4 = x2 * x2; float y4 = y2 * y2; float z4 = z2 * z2; SHVector o; o.v[0] = 0.282095f; o.v[1] = -0.488603f * y; o.v[2] = 0.488603f * z; o.v[3] = -0.488603f * x; o.v[4] = 1.092548f * x * y; o.v[5] = -1.092548f * y * z; o.v[6] = 0.315392f * (3.0f * z2 - 1.0f); o.v[7] = -1.092548f * x * z; o.v[8] = 0.546274f * (x2 - y2); o.v[9] = -0.590043f * y * (3.0f * x2 - y2); o.v[10] = 2.890611f * y * x * z; o.v[11] = -0.646360f * y * (-1.0f + 5.0f * z2); o.v[12] = 0.373176f *(5.0f * z3 - 3.0f * z); o.v[13] = -0.457045f * x * (-1.0f + 5.0f * z2); o.v[14] = 1.445306f *(x2 - y2) * z; o.v[15] = -0.590043f * x * (x2 - 3.0f * y2); o.v[16] = 2.503340f * x * y * (x2 - y2); o.v[17] = -1.770130f * y * z * (3.0f * x2 - y2); o.v[18] = 0.946175f * y * x * (-1.0f + 7.0f * z2); o.v[19] = -0.669046f * y * z * (-3.0f + 7.0f * z2); o.v[20] = (105.0f * z4 - 90.0f * z2 + 9.0f) / 28.359261f; o.v[21] = -0.669046f * x * z * (-3.0f + 7.0f * z2); o.v[22] = 0.473087f * (x2 - y2) * (-1.0f + 7.0f * z2); o.v[23] = -1.770130f * x * z * (x2 - 3.0f * y2); o.v[24] = 0.625836f * (x4 - 6.0f * y2 * x2 + y4); return o; } #elif SH_ORDER == 3 SHVector SHBasis(float3 dir) { float x = dir.x; float y = dir.y; float z = dir.z; float x2 = x*x; float y2 = y*y; float z2 = z*z; SHVector o; o.v[0] = 0.282095f; o.v[1] = -0.488603f * y; o.v[2] = 0.488603f * z; o.v[3] = -0.488603f * x; o.v[4] = 1.092548f * x * y; o.v[5] = -1.092548f * y * z; o.v[6] = 0.315392f * (3.0f * z2 - 1.0f); o.v[7] = -1.092548f * x * z; o.v[8] = 0.546274f * (x2 - y2); return o; } #endif }; };