internal void ToSphericalHarmonicsShaderConstants(ProbeVolumeSHBands srcBands, NativeArray <float> shL0L1Data, NativeArray <float> shL2Data, int probeIdx) { var sh = new SphericalHarmonicsL2(); ToSphericalHarmonicsL2(ref sh); WriteToShaderCoeffsL0L1(ref sh, shL0L1Data, probeIdx * ProbeVolumeAsset.kL0L1ScalarCoefficientsCount); if (srcBands == ProbeVolumeSHBands.SphericalHarmonicsL2) { WriteToShaderCoeffsL2(ref sh, shL2Data, probeIdx * ProbeVolumeAsset.kL2ScalarCoefficientsCount); } }
internal ProbeBrickPool(ProbeVolumeTextureMemoryBudget memoryBudget, ProbeVolumeSHBands shBands) { Profiler.BeginSample("Create ProbeBrickPool"); m_NextFreeChunk.x = m_NextFreeChunk.y = m_NextFreeChunk.z = 0; m_SHBands = shBands; m_FreeList = new Stack <BrickChunkAlloc>(256); DerivePoolSizeFromBudget(memoryBudget, out int width, out int height, out int depth); m_Pool = CreateDataLocation(width * height * depth, false, shBands, "APV", true, out int estimatedCost); estimatedVMemCost = estimatedCost; m_AvailableChunkCount = (m_Pool.width / (kProbePoolChunkSizeInBricks * kBrickProbeCountPerDim)) * (m_Pool.height / kBrickProbeCountPerDim) * (m_Pool.depth / kBrickProbeCountPerDim); Profiler.EndSample(); }
public static void FillDataLocation(ref DataLocation loc, SphericalHarmonicsL2[] shl2, ProbeVolumeSHBands bands) { int numBricks = shl2.Length / kBrickProbeCountTotal; int shidx = 0; int bx = 0, by = 0, bz = 0; Color c = new Color(); Color[] L0L1Rx_locData = new Color[loc.width * loc.height * loc.depth * 2]; Color[] L1GL1Ry_locData = new Color[loc.width * loc.height * loc.depth * 2]; Color[] L1BL1Rz_locData = new Color[loc.width * loc.height * loc.depth * 2]; Color[] L2_0_locData = null; Color[] L2_1_locData = null; Color[] L2_2_locData = null; Color[] L2_3_locData = null; if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { L2_0_locData = new Color[loc.width * loc.height * loc.depth]; L2_1_locData = new Color[loc.width * loc.height * loc.depth]; L2_2_locData = new Color[loc.width * loc.height * loc.depth]; L2_3_locData = new Color[loc.width * loc.height * loc.depth]; } for (int brickIdx = 0; brickIdx < shl2.Length; brickIdx += kBrickProbeCountTotal) { for (int z = 0; z < kBrickProbeCountPerDim; z++) { for (int y = 0; y < kBrickProbeCountPerDim; y++) { for (int x = 0; x < kBrickProbeCountPerDim; x++) { int ix = bx + x; int iy = by + y; int iz = bz + z; c.r = shl2[shidx][0, 0]; // L0.r c.g = shl2[shidx][1, 0]; // L0.g c.b = shl2[shidx][2, 0]; // L0.b c.a = shl2[shidx][0, 1]; // L1_R.r SetPixel(ref L0L1Rx_locData, ix, iy, iz, loc.width, loc.height, c); c.r = shl2[shidx][1, 1]; // L1_G.r c.g = shl2[shidx][1, 2]; // L1_G.g c.b = shl2[shidx][1, 3]; // L1_G.b c.a = shl2[shidx][0, 2]; // L1_R.g SetPixel(ref L1GL1Ry_locData, ix, iy, iz, loc.width, loc.height, c); c.r = shl2[shidx][2, 1]; // L1_B.r c.g = shl2[shidx][2, 2]; // L1_B.g c.b = shl2[shidx][2, 3]; // L1_B.b c.a = shl2[shidx][0, 3]; // L1_R.b SetPixel(ref L1BL1Rz_locData, ix, iy, iz, loc.width, loc.height, c); if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { c.r = shl2[shidx][0, 4]; c.g = shl2[shidx][0, 5]; c.b = shl2[shidx][0, 6]; c.a = shl2[shidx][0, 7]; SetPixel(ref L2_0_locData, ix, iy, iz, loc.width, loc.height, c); c.r = shl2[shidx][1, 4]; c.g = shl2[shidx][1, 5]; c.b = shl2[shidx][1, 6]; c.a = shl2[shidx][1, 7]; SetPixel(ref L2_1_locData, ix, iy, iz, loc.width, loc.height, c); c.r = shl2[shidx][2, 4]; c.g = shl2[shidx][2, 5]; c.b = shl2[shidx][2, 6]; c.a = shl2[shidx][2, 7]; SetPixel(ref L2_2_locData, ix, iy, iz, loc.width, loc.height, c); c.r = shl2[shidx][0, 8]; c.g = shl2[shidx][1, 8]; c.b = shl2[shidx][2, 8]; c.a = 1; SetPixel(ref L2_3_locData, ix, iy, iz, loc.width, loc.height, c); } shidx++; } } } // update the pool index bx += kBrickProbeCountPerDim; if (bx >= loc.width) { bx = 0; by += kBrickProbeCountPerDim; if (by >= loc.height) { by = 0; bz += kBrickProbeCountPerDim; Debug.Assert(bz < loc.depth || brickIdx == shl2.Length - kBrickProbeCountTotal, "Location depth exceeds data texture."); } } } loc.TexL0_L1rx.SetPixels(L0L1Rx_locData); loc.TexL0_L1rx.Apply(false); loc.TexL1_G_ry.SetPixels(L1GL1Ry_locData); loc.TexL1_G_ry.Apply(false); loc.TexL1_B_rz.SetPixels(L1BL1Rz_locData); loc.TexL1_B_rz.Apply(false); if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { loc.TexL2_0.SetPixels(L2_0_locData); loc.TexL2_0.Apply(false); loc.TexL2_1.SetPixels(L2_1_locData); loc.TexL2_1.Apply(false); loc.TexL2_2.SetPixels(L2_2_locData); loc.TexL2_2.Apply(false); loc.TexL2_3.SetPixels(L2_3_locData); loc.TexL2_3.Apply(false); } }
public static DataLocation CreateDataLocation(int numProbes, bool compressed, ProbeVolumeSHBands bands) { Vector3Int locSize = ProbeCountToDataLocSize(numProbes); int width = locSize.x; int height = locSize.y; int depth = locSize.z; DataLocation loc; loc.TexL0_L1rx = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGB_BC6H_UFloat : GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None, 1); loc.TexL1_G_ry = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL1_B_rz = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { loc.TexL2_0 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_1 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_2 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_3 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); } else { loc.TexL2_0 = null; loc.TexL2_1 = null; loc.TexL2_2 = null; loc.TexL2_3 = null; } loc.width = width; loc.height = height; loc.depth = depth; return(loc); }
internal void Update(DataLocation source, List <BrickChunkAlloc> srcLocations, List <BrickChunkAlloc> dstLocations, ProbeVolumeSHBands bands) { Debug.Assert(srcLocations.Count == dstLocations.Count); for (int i = 0; i < srcLocations.Count; i++) { BrickChunkAlloc src = srcLocations[i]; BrickChunkAlloc dst = dstLocations[i]; for (int j = 0; j < kBrickProbeCountPerDim; j++) { int width = Mathf.Min(m_AllocationSize * kBrickProbeCountPerDim, source.width - src.x); Graphics.CopyTexture(source.TexL0_L1rx, src.z + j, 0, src.x, src.y, width, kBrickProbeCountPerDim, m_Pool.TexL0_L1rx, dst.z + j, 0, dst.x, dst.y); Graphics.CopyTexture(source.TexL1_G_ry, src.z + j, 0, src.x, src.y, width, kBrickProbeCountPerDim, m_Pool.TexL1_G_ry, dst.z + j, 0, dst.x, dst.y); Graphics.CopyTexture(source.TexL1_B_rz, src.z + j, 0, src.x, src.y, width, kBrickProbeCountPerDim, m_Pool.TexL1_B_rz, dst.z + j, 0, dst.x, dst.y); if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { Graphics.CopyTexture(source.TexL2_0, src.z + j, 0, src.x, src.y, width, kBrickProbeCountPerDim, m_Pool.TexL2_0, dst.z + j, 0, dst.x, dst.y); Graphics.CopyTexture(source.TexL2_1, src.z + j, 0, src.x, src.y, width, kBrickProbeCountPerDim, m_Pool.TexL2_1, dst.z + j, 0, dst.x, dst.y); Graphics.CopyTexture(source.TexL2_2, src.z + j, 0, src.x, src.y, width, kBrickProbeCountPerDim, m_Pool.TexL2_2, dst.z + j, 0, dst.x, dst.y); Graphics.CopyTexture(source.TexL2_3, src.z + j, 0, src.x, src.y, width, kBrickProbeCountPerDim, m_Pool.TexL2_3, dst.z + j, 0, dst.x, dst.y); } } } }
public static DataLocation CreateDataLocation(int numProbes, bool compressed, ProbeVolumeSHBands bands, string name, out int allocatedBytes) { Vector3Int locSize = ProbeCountToDataLocSize(numProbes); int width = locSize.x; int height = locSize.y; int depth = locSize.z; int texelCount = width * height * depth; DataLocation loc; allocatedBytes = 0; loc.TexL0_L1rx = new Texture3D(width, height, depth, GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None, 1); loc.TexL0_L1rx.hideFlags = HideFlags.HideAndDontSave; loc.TexL0_L1rx.name = $"{name}_TexL0_L1rx"; allocatedBytes += texelCount * 8; loc.TexL1_G_ry = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL1_G_ry.hideFlags = HideFlags.HideAndDontSave; loc.TexL1_G_ry.name = $"{name}_TexL1_G_ry"; allocatedBytes += texelCount * (compressed ? 1 : 4); loc.TexL1_B_rz = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL1_B_rz.hideFlags = HideFlags.HideAndDontSave; loc.TexL1_B_rz.name = $"{name}_TexL1_B_rz"; allocatedBytes += texelCount * (compressed ? 1 : 4); loc.TexValidity = new Texture3D(width, height, depth, GraphicsFormat.R8_UNorm, TextureCreationFlags.None, 1); loc.TexValidity.hideFlags = HideFlags.HideAndDontSave; loc.TexValidity.name = $"{name}_Validity"; allocatedBytes += texelCount; if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { loc.TexL2_0 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_0.hideFlags = HideFlags.HideAndDontSave; loc.TexL2_0.name = $"{name}_TexL2_0"; allocatedBytes += texelCount * (compressed ? 1 : 4); loc.TexL2_1 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_1.hideFlags = HideFlags.HideAndDontSave; loc.TexL2_1.name = $"{name}_TexL2_1"; allocatedBytes += texelCount * (compressed ? 1 : 4); loc.TexL2_2 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_2.hideFlags = HideFlags.HideAndDontSave; loc.TexL2_2.name = $"{name}_TexL2_2"; allocatedBytes += texelCount * (compressed ? 1 : 4); loc.TexL2_3 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_3.hideFlags = HideFlags.HideAndDontSave; loc.TexL2_3.name = $"{name}_TexL2_3"; allocatedBytes += texelCount * (compressed ? 1 : 4); } else { loc.TexL2_0 = null; loc.TexL2_1 = null; loc.TexL2_2 = null; loc.TexL2_3 = null; } loc.width = width; loc.height = height; loc.depth = depth; return(loc); }
public static DataLocation CreateDataLocation(int numProbes, bool compressed, ProbeVolumeSHBands bands, string name, bool allocateRendertexture, out int allocatedBytes) { Vector3Int locSize = ProbeCountToDataLocSize(numProbes); int width = locSize.x; int height = locSize.y; int depth = locSize.z; DataLocation loc; var L0Format = GraphicsFormat.R16G16B16A16_SFloat; var L1L2Format = compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm; allocatedBytes = 0; loc.TexL0_L1rx = CreateDataTexture(width, height, depth, L0Format, $"{name}_TexL0_L1rx", allocateRendertexture, ref allocatedBytes); loc.TexL1_G_ry = CreateDataTexture(width, height, depth, L1L2Format, $"{name}_TexL1_G_ry", allocateRendertexture, ref allocatedBytes); loc.TexL1_B_rz = CreateDataTexture(width, height, depth, L1L2Format, $"{name}_TexL1_B_rz", allocateRendertexture, ref allocatedBytes); loc.TexValidity = CreateDataTexture(width, height, depth, GraphicsFormat.R8_UNorm, $"{name}_Validity", false, ref allocatedBytes) as Texture3D; if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { loc.TexL2_0 = CreateDataTexture(width, height, depth, L1L2Format, $"{name}_TexL2_0", allocateRendertexture, ref allocatedBytes); loc.TexL2_1 = CreateDataTexture(width, height, depth, L1L2Format, $"{name}_TexL2_1", allocateRendertexture, ref allocatedBytes); loc.TexL2_2 = CreateDataTexture(width, height, depth, L1L2Format, $"{name}_TexL2_2", allocateRendertexture, ref allocatedBytes); loc.TexL2_3 = CreateDataTexture(width, height, depth, L1L2Format, $"{name}_TexL2_3", allocateRendertexture, ref allocatedBytes); } else { loc.TexL2_0 = null; loc.TexL2_1 = null; loc.TexL2_2 = null; loc.TexL2_3 = null; } loc.width = width; loc.height = height; loc.depth = depth; return(loc); }
public static void FillDataLocation(ref DataLocation loc, SphericalHarmonicsL2[] shl2, ProbeVolumeSHBands bands) { int numBricks = shl2.Length / kBrickProbeCountTotal; int shidx = 0; int bx = 0, by = 0, bz = 0; Color c = new Color(); for (int brickIdx = 0; brickIdx < shl2.Length; brickIdx += kBrickProbeCountTotal) { for (int z = 0; z < kBrickProbeCountPerDim; z++) { for (int y = 0; y < kBrickProbeCountPerDim; y++) { for (int x = 0; x < kBrickProbeCountPerDim; x++) { int ix = bx + x; int iy = by + y; int iz = bz + z; Vector3 L0 = SphericalHarmonicsL2Utils.GetCoefficient(shl2[shidx], 0); Vector3 L1R, L1G, L1B; SphericalHarmonicsL2Utils.GetL1(shl2[shidx], out L1R, out L1G, out L1B); // First texture will have L0 coefficients in RGB, and L1R.x in the alpha channel Color L0_L1Rx = new Color(L0.x, L0.y, L0.z, L1R.x); // Second texture will have L1_G coefficients in RGB and L1R.y in the alpha channel Color L1G_L1Ry = new Color(L1G.x, L1G.y, L1G.z, L1R.y); // Third texture will have L1_B coefficients in RGB and L1R.z in the alpha channel Color L1B_L1Rz = new Color(L1B.x, L1B.y, L1B.z, L1R.z); loc.TexL0_L1rx.SetPixel(ix, iy, iz, L0_L1Rx); loc.TexL1_G_ry.SetPixel(ix, iy, iz, L1G_L1Ry); loc.TexL1_B_rz.SetPixel(ix, iy, iz, L1B_L1Rz); if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { Vector3 L2_0, L2_1, L2_2, L2_3, L2_4; SphericalHarmonicsL2Utils.GetL2(shl2[shidx], out L2_0, out L2_1, out L2_2, out L2_3, out L2_4); c.r = L2_0.x; c.g = L2_1.x; c.b = L2_2.x; c.a = L2_3.x; loc.TexL2_0.SetPixel(ix, iy, iz, c); c.r = L2_0.y; c.g = L2_1.y; c.b = L2_2.y; c.a = L2_3.y; loc.TexL2_1.SetPixel(ix, iy, iz, c); c.r = L2_0.z; c.g = L2_1.z; c.b = L2_2.z; c.a = L2_3.z; loc.TexL2_2.SetPixel(ix, iy, iz, c); c.r = L2_4.x; c.g = L2_4.y; c.b = L2_4.z; c.a = 1; loc.TexL2_3.SetPixel(ix, iy, iz, c); } shidx++; } } } // update the pool index bx += kBrickProbeCountPerDim; if (bx >= loc.width) { bx = 0; by += kBrickProbeCountPerDim; if (by >= loc.height) { by = 0; bz += kBrickProbeCountPerDim; Debug.Assert(bz < loc.depth || brickIdx == shl2.Length - kBrickProbeCountTotal, "Location depth exceeds data texture."); } } } loc.TexL0_L1rx.Apply(false); loc.TexL1_G_ry.Apply(false); loc.TexL1_B_rz.Apply(false); if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { loc.TexL2_0.Apply(false); loc.TexL2_1.Apply(false); loc.TexL2_2.Apply(false); loc.TexL2_3.Apply(false); } }
public static DataLocation CreateDataLocation(int numProbes, bool compressed, ProbeVolumeSHBands bands) { Debug.Assert(numProbes != 0); Debug.Assert(numProbes % kBrickProbeCountTotal == 0); int numBricks = numProbes / kBrickProbeCountTotal; int poolWidth = kMaxPoolWidth / kBrickProbeCountPerDim; int width, height, depth; depth = (numBricks + poolWidth * poolWidth - 1) / (poolWidth * poolWidth); if (depth > 1) { width = height = poolWidth; } else { height = (numBricks + poolWidth - 1) / poolWidth; if (height > 1) { width = poolWidth; } else { width = numBricks; } } width *= kBrickProbeCountPerDim; height *= kBrickProbeCountPerDim; depth *= kBrickProbeCountPerDim; DataLocation loc; loc.TexL0_L1rx = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGB_BC6H_UFloat : GraphicsFormat.R16G16B16A16_SFloat, TextureCreationFlags.None, 1); loc.TexL1_G_ry = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL1_B_rz = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); if (bands == ProbeVolumeSHBands.SphericalHarmonicsL2) { loc.TexL2_0 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_1 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_2 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); loc.TexL2_3 = new Texture3D(width, height, depth, compressed ? GraphicsFormat.RGBA_BC7_UNorm : GraphicsFormat.R8G8B8A8_UNorm, TextureCreationFlags.None, 1); } else { loc.TexL2_0 = null; loc.TexL2_1 = null; loc.TexL2_2 = null; loc.TexL2_3 = null; } loc.width = width; loc.height = height; loc.depth = depth; return(loc); }