A game about forced loneliness, made by TACStudios
at master 280 lines 11 kB view raw
1using System; 2 3namespace UnityEngine.Rendering 4{ 5 /// <summary> 6 /// Structure holding Spherical Harmonic L1 coefficient. 7 /// </summary> 8 [Serializable] 9 public struct SphericalHarmonicsL1 10 { 11 /// <summary> 12 /// Red channel of each of the three L1 SH coefficient. 13 /// </summary> 14 public Vector4 shAr; 15 /// <summary> 16 /// Green channel of each of the three L1 SH coefficient. 17 /// </summary> 18 public Vector4 shAg; 19 /// <summary> 20 /// Blue channel of each of the three L1 SH coefficient. 21 /// </summary> 22 public Vector4 shAb; 23 24 /// <summary> 25 /// A set of L1 coefficients initialized to zero. 26 /// </summary> 27 public static readonly SphericalHarmonicsL1 zero = new SphericalHarmonicsL1 28 { 29 shAr = Vector4.zero, 30 shAg = Vector4.zero, 31 shAb = Vector4.zero 32 }; 33 34 // These operators are implemented so that SphericalHarmonicsL1 matches API of SphericalHarmonicsL2. 35 36 /// <summary> 37 /// Sum two SphericalHarmonicsL1. 38 /// </summary> 39 /// <param name="lhs">First SphericalHarmonicsL1.</param> 40 /// <param name="rhs">Second SphericalHarmonicsL1.</param> 41 /// <returns>The resulting SphericalHarmonicsL1.</returns> 42 public static SphericalHarmonicsL1 operator +(SphericalHarmonicsL1 lhs, SphericalHarmonicsL1 rhs) => new SphericalHarmonicsL1() 43 { 44 shAr = lhs.shAr + rhs.shAr, 45 shAg = lhs.shAg + rhs.shAg, 46 shAb = lhs.shAb + rhs.shAb 47 }; 48 49 /// <summary> 50 /// Subtract two SphericalHarmonicsL1. 51 /// </summary> 52 /// <param name="lhs">First SphericalHarmonicsL1.</param> 53 /// <param name="rhs">Second SphericalHarmonicsL1.</param> 54 /// <returns>The resulting SphericalHarmonicsL1.</returns> 55 public static SphericalHarmonicsL1 operator -(SphericalHarmonicsL1 lhs, SphericalHarmonicsL1 rhs) => new SphericalHarmonicsL1() 56 { 57 shAr = lhs.shAr - rhs.shAr, 58 shAg = lhs.shAg - rhs.shAg, 59 shAb = lhs.shAb - rhs.shAb 60 }; 61 62 /// <summary> 63 /// Multiply two SphericalHarmonicsL1. 64 /// </summary> 65 /// <param name="lhs">First SphericalHarmonicsL1.</param> 66 /// <param name="rhs">Second SphericalHarmonicsL1.</param> 67 /// <returns>The resulting SphericalHarmonicsL1.</returns> 68 public static SphericalHarmonicsL1 operator *(SphericalHarmonicsL1 lhs, float rhs) => new SphericalHarmonicsL1() 69 { 70 shAr = lhs.shAr * rhs, 71 shAg = lhs.shAg * rhs, 72 shAb = lhs.shAb * rhs 73 }; 74 75 /// <summary> 76 /// Divide two SphericalHarmonicsL1. 77 /// </summary> 78 /// <param name="lhs">First SphericalHarmonicsL1.</param> 79 /// <param name="rhs">Second SphericalHarmonicsL1.</param> 80 /// <returns>The resulting SphericalHarmonicsL1.</returns> 81 public static SphericalHarmonicsL1 operator /(SphericalHarmonicsL1 lhs, float rhs) => new SphericalHarmonicsL1() 82 { 83 shAr = lhs.shAr / rhs, 84 shAg = lhs.shAg / rhs, 85 shAb = lhs.shAb / rhs 86 }; 87 88 /// <summary> 89 /// Compare two SphericalHarmonicsL1. 90 /// </summary> 91 /// <param name="lhs">First SphericalHarmonicsL1.</param> 92 /// <param name="rhs">Second SphericalHarmonicsL1.</param> 93 /// <returns>Whether the SphericalHarmonicsL1 match.</returns> 94 public static bool operator ==(SphericalHarmonicsL1 lhs, SphericalHarmonicsL1 rhs) 95 { 96 return lhs.shAr == rhs.shAr 97 && lhs.shAg == rhs.shAg 98 && lhs.shAb == rhs.shAb; 99 } 100 101 /// <summary> 102 /// Check two SphericalHarmonicsL1 inequality. 103 /// </summary> 104 /// <param name="lhs">First SphericalHarmonicsL1.</param> 105 /// <param name="rhs">Second SphericalHarmonicsL1.</param> 106 /// <returns>Whether the SphericalHarmonicsL1 are different.</returns> 107 public static bool operator !=(SphericalHarmonicsL1 lhs, SphericalHarmonicsL1 rhs) 108 { 109 return !(lhs == rhs); 110 } 111 112 /// <summary> 113 /// Compare this SphericalHarmonicsL1 with an object. 114 /// </summary> 115 /// <param name="other">The object to compare with.</param> 116 /// <returns>Whether the SphericalHarmonicsL1 is equal to the object passed.</returns> 117 public override bool Equals(object other) 118 { 119 if (!(other is SphericalHarmonicsL1)) return false; 120 return this == (SphericalHarmonicsL1)other; 121 } 122 123 /// <summary> 124 /// Produces an hash code of the SphericalHarmonicsL1. 125 /// </summary> 126 /// <returns>The hash code for this SphericalHarmonicsL1.</returns> 127 public override int GetHashCode() 128 { 129 return ((17 * 23 + shAr.GetHashCode()) * 23 + shAg.GetHashCode()) * 23 + shAb.GetHashCode(); 130 } 131 } 132 133 /// <summary> 134 /// A collection of utility functions used to access and set SphericalHarmonicsL2 in a more verbose way. 135 /// </summary> 136 public class SphericalHarmonicsL2Utils 137 { 138 /// <summary> 139 /// Returns the L1 coefficients organized in such a way that are swizzled per channel rather than per coefficient. 140 /// </summary> 141 /// <param name ="sh"> The SphericalHarmonicsL2 data structure to use to query the information.</param> 142 /// <param name ="L1_R">The red channel of all coefficient for the L1 band.</param> 143 /// <param name ="L1_G">The green channel of all coefficient for the L1 band.</param> 144 /// <param name ="L1_B">The blue channel of all coefficient for the L1 band.</param> 145 public static void GetL1(SphericalHarmonicsL2 sh, out Vector3 L1_R, out Vector3 L1_G, out Vector3 L1_B) 146 { 147 L1_R = new Vector3(sh[0, 1], 148 sh[0, 2], 149 sh[0, 3]); 150 151 L1_G = new Vector3(sh[1, 1], 152 sh[1, 2], 153 sh[1, 3]); 154 155 L1_B = new Vector3(sh[2, 1], 156 sh[2, 2], 157 sh[2, 3]); 158 } 159 160 /// <summary> 161 /// Returns all the L2 coefficients. 162 /// </summary> 163 /// <param name ="sh"> The SphericalHarmonicsL2 data structure to use to query the information.</param> 164 /// <param name ="L2_0">The first coefficient for the L2 band.</param> 165 /// <param name ="L2_1">The second coefficient for the L2 band.</param> 166 /// <param name ="L2_2">The third coefficient for the L2 band.</param> 167 /// <param name ="L2_3">The fourth coefficient for the L2 band.</param> 168 /// <param name ="L2_4">The fifth coefficient for the L2 band.</param> 169 public static void GetL2(SphericalHarmonicsL2 sh, out Vector3 L2_0, out Vector3 L2_1, out Vector3 L2_2, out Vector3 L2_3, out Vector3 L2_4) 170 { 171 L2_0 = new Vector3(sh[0, 4], 172 sh[1, 4], 173 sh[2, 4]); 174 175 L2_1 = new Vector3(sh[0, 5], 176 sh[1, 5], 177 sh[2, 5]); 178 179 L2_2 = new Vector3(sh[0, 6], 180 sh[1, 6], 181 sh[2, 6]); 182 183 L2_3 = new Vector3(sh[0, 7], 184 sh[1, 7], 185 sh[2, 7]); 186 187 L2_4 = new Vector3(sh[0, 8], 188 sh[1, 8], 189 sh[2, 8]); 190 } 191 192 /// <summary> 193 /// Set L0 coefficient. 194 /// </summary> 195 /// <param name ="sh">The SphericalHarmonicsL2 data structure to store information on.</param> 196 /// <param name ="L0">The L0 coefficient to set.</param> 197 public static void SetL0(ref SphericalHarmonicsL2 sh, Vector3 L0) 198 { 199 sh[0, 0] = L0.x; 200 sh[1, 0] = L0.y; 201 sh[2, 0] = L0.z; 202 } 203 204 /// <summary> 205 /// Set the red channel for each of the L1 coefficients. 206 /// </summary> 207 /// <param name ="sh">The SphericalHarmonicsL2 data structure to store information on.</param> 208 /// <param name ="L1_R">The red channels for each L1 coefficient.</param> 209 public static void SetL1R(ref SphericalHarmonicsL2 sh, Vector3 L1_R) 210 { 211 sh[0, 1] = L1_R.x; 212 sh[0, 2] = L1_R.y; 213 sh[0, 3] = L1_R.z; 214 } 215 216 /// <summary> 217 /// Set the green channel for each of the L1 coefficients. 218 /// </summary> 219 /// <param name ="sh">The SphericalHarmonicsL2 data structure to store information on.</param> 220 /// <param name ="L1_G">The green channels for each L1 coefficient.</param> 221 public static void SetL1G(ref SphericalHarmonicsL2 sh, Vector3 L1_G) 222 { 223 sh[1, 1] = L1_G.x; 224 sh[1, 2] = L1_G.y; 225 sh[1, 3] = L1_G.z; 226 } 227 228 /// <summary> 229 /// Set the blue channel for each of the L1 coefficients. 230 /// </summary> 231 /// <param name ="sh">The SphericalHarmonicsL2 data structure to store information on.</param> 232 /// <param name ="L1_B">The blue channels for each L1 coefficient.</param> 233 public static void SetL1B(ref SphericalHarmonicsL2 sh, Vector3 L1_B) 234 { 235 sh[2, 1] = L1_B.x; 236 sh[2, 2] = L1_B.y; 237 sh[2, 3] = L1_B.z; 238 } 239 240 /// <summary> 241 /// Set all L1 coefficients per channel. 242 /// </summary> 243 /// <param name ="sh">The SphericalHarmonicsL2 data structure to store information on.</param> 244 /// <param name ="L1_R">The red channels for each L1 coefficient.</param> 245 /// <param name ="L1_G">The green channels for each L1 coefficient.</param> 246 /// <param name ="L1_B">The blue channels for each L1 coefficient.</param> 247 public static void SetL1(ref SphericalHarmonicsL2 sh, Vector3 L1_R, Vector3 L1_G, Vector3 L1_B) 248 { 249 SetL1R(ref sh, L1_R); 250 SetL1G(ref sh, L1_G); 251 SetL1B(ref sh, L1_B); 252 } 253 254 /// <summary> 255 /// Set a spherical harmonics coefficient. 256 /// </summary> 257 /// <param name ="sh">The SphericalHarmonicsL2 data structure to store information on.</param> 258 /// <param name ="index">The index of the coefficient that is set (must be less than 9).</param> 259 /// <param name ="coefficient">The values of the coefficient is set.</param> 260 public static void SetCoefficient(ref SphericalHarmonicsL2 sh, int index, Vector3 coefficient) 261 { 262 Debug.Assert(index < 9); 263 sh[0, index] = coefficient.x; 264 sh[1, index] = coefficient.y; 265 sh[2, index] = coefficient.z; 266 } 267 268 /// <summary> 269 /// Get a spherical harmonics coefficient. 270 /// </summary> 271 /// <param name ="sh">The SphericalHarmonicsL2 data structure to get information from.</param> 272 /// <param name ="index">The index of the coefficient that is requested (must be less than 9).</param> 273 /// <returns>The value of the requested coefficient.</returns> 274 public static Vector3 GetCoefficient(SphericalHarmonicsL2 sh, int index) 275 { 276 Debug.Assert(index < 9); 277 return new Vector3(sh[0, index], sh[1, index], sh[2, index]); 278 } 279 } 280}