A game about forced loneliness, made by TACStudios
at master 299 lines 13 kB view raw
1using System.Collections.Generic; 2using System.Runtime.CompilerServices; 3using Unity.Mathematics; 4 5using RuntimeResources = UnityEngine.Rendering.ProbeReferenceVolume.RuntimeResources; 6 7namespace UnityEngine.Rendering 8{ 9 static class ProbeVolumeConstantRuntimeResources 10 { 11 static ComputeBuffer m_SkySamplingDirectionsBuffer = null; 12 static ComputeBuffer m_AntiLeakDataBuffer = null; 13 14 [MethodImpl(MethodImplOptions.AggressiveInlining)] 15 internal static void GetRuntimeResources(ref RuntimeResources rr) 16 { 17 rr.SkyPrecomputedDirections = m_SkySamplingDirectionsBuffer; 18 rr.QualityLeakReductionData = m_AntiLeakDataBuffer; 19 } 20 21 internal static void Initialize() 22 { 23 if (m_SkySamplingDirectionsBuffer == null) 24 { 25 k_SkyDirections = GenerateSkyDirections(); 26 m_SkySamplingDirectionsBuffer = new ComputeBuffer(k_SkyDirections.Length, 3 * sizeof(float)); 27 m_SkySamplingDirectionsBuffer.SetData(k_SkyDirections); 28 } 29 30 if (m_AntiLeakDataBuffer == null) 31 { 32 m_AntiLeakDataBuffer = new ComputeBuffer(k_AntiLeakData.Length, sizeof(uint)); 33 m_AntiLeakDataBuffer.SetData(k_AntiLeakData); 34 } 35 } 36 37 public static Vector3[] GetSkySamplingDirections() 38 { 39 return k_SkyDirections; 40 } 41 42 internal static void Cleanup() 43 { 44 CoreUtils.SafeRelease(m_SkySamplingDirectionsBuffer); 45 m_SkySamplingDirectionsBuffer = null; 46 47 CoreUtils.SafeRelease(m_AntiLeakDataBuffer); 48 m_AntiLeakDataBuffer = null; 49 } 50 51 #region Sky Directions Buffer generator 52 const int NB_SKY_PRECOMPUTED_DIRECTIONS = 255; 53 static Vector3[] k_SkyDirections = new Vector3[NB_SKY_PRECOMPUTED_DIRECTIONS]; 54 55 static Vector3[] GenerateSkyDirections() 56 { 57 var skyDirections = new Vector3[NB_SKY_PRECOMPUTED_DIRECTIONS]; 58 59 float sqrtNBpoints = Mathf.Sqrt((float)(NB_SKY_PRECOMPUTED_DIRECTIONS)); 60 float phi = 0.0f; 61 float phiMax = 0.0f; 62 float thetaMax = 0.0f; 63 64 // Spiral based sampling on sphere 65 // See http://web.archive.org/web/20120331125729/http://www.math.niu.edu/~rusin/known-math/97/spherefaq 66 // http://www.math.vanderbilt.edu/saffeb/texts/161.pdf 67 for (int i=0; i < NB_SKY_PRECOMPUTED_DIRECTIONS; i++) 68 { 69 // theta from 0 to PI 70 // phi from 0 to 2PI 71 float h = -1.0f + (2.0f * i) / (NB_SKY_PRECOMPUTED_DIRECTIONS - 1.0f); 72 float theta = Mathf.Acos(h); 73 if (i == NB_SKY_PRECOMPUTED_DIRECTIONS - 1 || i==0) 74 phi = 0.0f; 75 else 76 phi = phi + 3.6f / sqrtNBpoints * 1.0f / (Mathf.Sqrt(1.0f-h*h)); 77 78 Vector3 pointOnSphere = new Vector3(Mathf.Sin(theta) * Mathf.Cos(phi), Mathf.Sin(theta) * Mathf.Sin(phi), Mathf.Cos(theta)); 79 80 pointOnSphere.Normalize(); 81 skyDirections[i] = pointOnSphere; 82 83 phiMax = Mathf.Max(phiMax, phi); 84 thetaMax = Mathf.Max(thetaMax, theta); 85 } 86 87 return skyDirections; 88 } 89 #endregion 90 91 #region AntiLeak Buffer generator 92 #if UNITY_EDITOR 93 static uint3 GetSampleOffset(uint i) 94 { 95 return new uint3(i, i >> 1, i >> 2) & 1; 96 } 97 static int GetProbeIndex(int x, int y, int z) 98 { 99 return x + y * 2 + z * 4; 100 } 101 102 static uint BuildFace(int axis, int idx) 103 { 104 uint mask = 0; 105 int[] coords = new int[3]; 106 coords[axis] = idx; 107 for (int i = 0; i < 2; i++) 108 { 109 coords[(axis + 1) % 3] = i; 110 for (int j = 0; j < 2; j++) 111 { 112 coords[(axis + 2) % 3] = j; 113 mask = mask | (uint)(1 << GetProbeIndex(coords[0], coords[1], coords[2])); 114 } 115 } 116 return mask; 117 } 118 119 static bool TryGetEdge(uint validityMask, uint samplingMask, out uint edge, out uint3 offset) 120 { 121 for (int i = 0; i < 8; i++) 122 { 123 if ((validityMask & (1 << i)) == 0) 124 continue; 125 126 uint3 p = GetSampleOffset((uint)i); 127 if (p.x == 0) 128 { 129 edge = (1u << i) | (1u << GetProbeIndex(1, (int)p.y, (int)p.z)); 130 if ((validityMask & edge) == edge && (samplingMask & edge) == 0) 131 { 132 offset = 2 * p; 133 offset.x = 1; 134 return true; 135 } 136 } 137 if (p.y == 0) 138 { 139 edge = (1u << i) | (1u << GetProbeIndex((int)p.x, 1, (int)p.z)); 140 if ((validityMask & edge) == edge && (samplingMask & edge) == 0) 141 { 142 offset = 2 * p; 143 offset.y = 1; 144 return true; 145 } 146 } 147 if (p.z == 0) 148 { 149 edge = (1u << i) | (1u << GetProbeIndex((int)p.x, (int)p.y, 1)); 150 if ((validityMask & edge) == edge && (samplingMask & edge) == 0) 151 { 152 offset = 2 * p; 153 offset.z = 1; 154 return true; 155 } 156 } 157 } 158 159 edge = 0; 160 offset = 0; 161 return false; 162 } 163 164 static List<uint3> ComputeMask(uint validityMask) 165 { 166 List<uint3> samples = new(); 167 168 // Cube sample 169 if (validityMask == 0 || validityMask == 255) 170 { 171 samples.Add(1); 172 return samples; 173 } 174 175 // track which probes are sampled 176 uint samplingMask = 0; 177 178 // Find face sample 179 for (int i = 0; i < 6; i++) 180 { 181 int axis = i / 2; 182 uint face = BuildFace(axis, i % 2); 183 if ((validityMask & face) == face) // all face is valid, sample it 184 { 185 uint3 offset = 0; 186 offset[axis] = (i % 2) == 0 ? 0u : 2u; 187 offset[(axis + 1) % 3] = 1; 188 offset[(axis + 2) % 3] = 1; 189 190 samples.Add(offset); 191 samplingMask = face; 192 break; 193 } 194 } 195 196 // Find edge samples 197 while (true) 198 { 199 if (!TryGetEdge(validityMask, samplingMask, out uint edge, out uint3 offset)) 200 break; 201 202 samples.Add(offset); 203 samplingMask |= edge; 204 } 205 206 // Find single probe samples 207 for (int i = 0; i < 8; i++) 208 { 209 if (((1 << i) & (validityMask & ~samplingMask)) == 0) 210 continue; 211 samples.Add(2 * GetSampleOffset((uint)i)); 212 samplingMask |= (uint)(1 << i); 213 } 214 215 return samples; 216 } 217 218 static uint PackSamplingDir(uint val) 219 { 220 // On a single axis there is up to 2 probes. A face or edge sample needs to sample in between the probes 221 // We encode 0 as sample first probe, 1 as sample between probe, 2 as sample second probe (2 bits) 222 // For faster decoding, we use a third bit that reduces ALU in shader 223 return /* 2 bits */ (val << 1) | /* 1 bit */ ((~val & 2) >> 1); 224 } 225 226 static uint InvalidSampleMask() 227 { 228 // This is a special code that results in no sampling in shader without any additional ALU 229 return 2 | (2 << 3) | (2 << 6); 230 } 231 232 static uint ComputeAntiLeakData(uint validityMask) 233 { 234 // This may generate more than 3 samples, but we limit to 3 235 var samples = ComputeMask(validityMask); 236 uint mask = 0; 237 238 for (int i = 0; i < 3; i++) 239 { 240 uint sampleMask; 241 if (i < samples.Count) 242 sampleMask = PackSamplingDir(samples[i].x) | (PackSamplingDir(samples[i].y) << 3) | (PackSamplingDir(samples[i].z) << 6); 243 else 244 sampleMask = InvalidSampleMask(); 245 246 // 32bits - 9bits per samples (up to 3 samples) 247 // Each sample encodes sampling on each axis (3axis * 3bits) 248 // See PackSamplingDir for axis encoding 249 mask |= sampleMask << (9 * i); 250 } 251 252 return mask; 253 } 254 255 //[UnityEditor.MenuItem("Edit/Rendering/Global Illumination/Generate AntiLeak Buffer")] 256 static uint[] BuildAntiLeakDataArray() 257 { 258 uint[] antileak = new uint[256]; 259 for (uint validityMask = 0; validityMask < 256; validityMask++) 260 antileak[validityMask] = ComputeAntiLeakData(validityMask); 261 262 string str = "static uint[] k_AntiLeakData = new uint[256] {\n"; 263 for (int i = 0; i < 16; i++) 264 { 265 str += " "; 266 for (int j = 0; j < 16; j++) 267 { 268 str += antileak[i * 16 + j] + (j == 15 ? ",\n" : ", "); 269 } 270 } 271 str += " };"; 272 Debug.Log(str); 273 274 return antileak; 275 } 276 #endif 277 278 // This is autogenerated using the MenuItem above -- do not edit by hand 279 static uint[] k_AntiLeakData = new uint[256] { 280 38347995, 38347849, 38347852, 38347851, 38347873, 38347865, 38322764, 38322763, 38347876, 38324297, 38347868, 38324299, 38347875, 38324313, 38322780, 38347867, 281 38348041, 38347977, 38408780, 38408779, 38408801, 38408793, 69517900, 69517899, 38408804, 38324425, 38408796, 69519435, 38408803, 69519449, 69517916, 38408795, 282 38348044, 38410313, 38347980, 38410315, 38410337, 38410329, 38322892, 70304331, 38410340, 70305865, 38410332, 70305867, 38410339, 70305881, 70304348, 38410331, 283 38348043, 38410441, 38408908, 38347979, 38322955, 38409817, 69518028, 38322891, 38324491, 70305993, 38409820, 38324427, 38409827, 26351193, 25564764, 38323915, 284 38348065, 38421065, 38421068, 38421067, 38348001, 38421081, 38312161, 38388299, 38421092, 75810889, 38421084, 75810891, 38421091, 75810905, 38388316, 38421083, 285 38348057, 38421193, 38312217, 38416971, 38408929, 38347993, 69507297, 38312153, 38324505, 75811017, 38416988, 26358347, 38416995, 38324441, 69583452, 38320345, 286 38421260, 75896905, 38421196, 75896907, 38410465, 75896921, 38388428, 70369867, 75896932, 70305865, 75896924, 70305867, 75896931, 70305881, 70369884, 75896923, 287 38421259, 75897033, 38417100, 38421195, 38409953, 38410457, 69583564, 38377689, 75811083, 70305993, 75896412, 75811019, 75896419, 70306009, 70107740, 70301913, 288 38348068, 38422601, 38422604, 38422603, 38422625, 38422617, 76595788, 76595787, 38348004, 38310628, 38422620, 38389835, 38422627, 38389849, 76595804, 38422619, 289 38422793, 38422729, 76681804, 76681803, 76681825, 76681817, 69517900, 69517899, 38408932, 38389961, 76681820, 69584971, 76681827, 69584985, 69517916, 76681819, 290 38348060, 38310684, 38422732, 38418507, 38322972, 38418521, 76595916, 25573451, 38410468, 70292196, 38347996, 38310620, 38418531, 70371417, 38322908, 38318812, 291 38422795, 38418633, 76681932, 38422731, 76595979, 76682841, 69518028, 76595915, 38409956, 70371529, 38408924, 38376156, 76682851, 70109273, 69518044, 69513948, 292 38348067, 38310691, 38312227, 38422091, 38422753, 38422105, 76585185, 76661323, 38421220, 75797220, 38422108, 75876427, 38348003, 38310627, 38312163, 38311651, 293 38422809, 38422217, 76585241, 76689995, 76681953, 38422745, 69507297, 76585177, 38417124, 75876553, 76690012, 73779275, 38408931, 38389977, 69507299, 76593369, 294 38421276, 75797276, 38422220, 75905099, 38418657, 75905113, 76661452, 74564171, 75897060, 70292196, 38421212, 75797212, 38410467, 70292195, 38388444, 75805404, 295 38348059, 38310683, 38312219, 38422219, 38322971, 38418649, 25467163, 76650713, 38324507, 26252059, 38417116, 75862748, 38409955, 70371545, 69583580, 38347995, 296 }; 297 #endregion 298 } 299}