diff --git a/03-UnrealEngine/Rendering/RenderingPipeline/VirtualTexture学习笔记.md b/03-UnrealEngine/Rendering/RenderingPipeline/VirtualTexture学习笔记.md index 1f4db76..1f24baa 100644 --- a/03-UnrealEngine/Rendering/RenderingPipeline/VirtualTexture学习笔记.md +++ b/03-UnrealEngine/Rendering/RenderingPipeline/VirtualTexture学习笔记.md @@ -526,9 +526,53 @@ void TextureLoadVirtualPageTableInternal( 3. 通过 Page 坐标加上 Page 的 XY 偏移,再根据 mipLevel,计算出 PageTable Texture 的 UV 坐标,然后使用这个 UV 坐标和 mipLevel 采样 PageTable Texture 得到在 Physical Texture 上的信息,保存在 PageTableValue 中,在接下来的流程中使用。 4. 将第 3 步计算好的 PageTable Texture 的 Page 坐标和 mipLevel 保存在 VTPageTableResult 中,最后通过 StoreVirtualTextureFeedback 函数写入到 VT feedback Buffer 中。 +***TextureVirtualSample*** +采样所需的 VTPageTableResult 数据准备完毕,在 TextureVirtualSample 函数中就是执行真正的 Physical Texture 采样逻辑,代码如下: +```c++ +MaterialFloat4 TextureVirtualSample( + Texture2D Physical, SamplerState PhysicalSampler, + VTPageTableResult PageTableResult, uint LayerIndex, + VTUniform Uniform) +{ + const float2 pUV = VTComputePhysicalUVs(PageTableResult, LayerIndex, Uniform); + return Physical.SampleGrad(PhysicalSampler, pUV, PageTableResult.dUVdx, PageTableResult.dUVdy); +} +``` + +这个函数很简单,只有 2 个函数调用,第一行 VTComputePhysicalUVs 用于生成 Physical Texture UV 坐标,第二行用于执行渐变采样,所以这里重点是如何生成 Physical Texture UV 坐标,VTComputePhysicalUVs 函数代码如下: +```cpp +float2 VTComputePhysicalUVs(in out VTPageTableResult PageTableResult, uint LayerIndex, VTUniform Uniform) +{ + const uint PackedPageTableValue = PageTableResult.PageTableValue[LayerIndex / 4u][LayerIndex & 3u]; + + // See packing in PageTableUpdate.usf + const uint vLevel = PackedPageTableValue & 0xf; + const float UVScale = 1.0f / (float)(1 << vLevel); + const float pPageX = (float)((PackedPageTableValue >> 4) & ((1 << Uniform.PageCoordinateBitCount) - 1)); + const float pPageY = (float)(PackedPageTableValue >> (4 + Uniform.PageCoordinateBitCount)); + + const float2 vPageFrac = frac(PageTableResult.UV * UVScale); + const float2 pUV = float2(pPageX, pPageY) * Uniform.pPageSize + (vPageFrac * Uniform.vPageSize + Uniform.vPageBorderSize); + + const float ddxyScale = UVScale * Uniform.vPageSize; + PageTableResult.dUVdx *= ddxyScale; + PageTableResult.dUVdy *= ddxyScale; + return pUV; +} +``` + VT还存在一个反馈机制,具体可以参考:[[#Pass1的补充VirtualTextureFeedback]] ```c++ /** GPU fence pool. Contains a fence array that is kept in sync with the FeedbackItems ring buffer. Fences are used to know when a transfer is ready to Map() without stalling. */ /** GPU 栅栏池。其中包含一个与 FeedbackItems 环形缓冲区保持同步的栅栏数组。栅栏用于了解传输何时准备就绪,可在不停滞的情况下进行 Map()。 */ class FFeedbackGPUFencePool* Fences; -``` \ No newline at end of file +``` + +# 使用RVT实现3D高斯 LOD思路 +AI数据侧: +1. 确定点云数据是否可以划分成四叉树的数据结构,也就是将一堆点云按照一个**距离阈值** 进行分割,最终形成一个四叉树。 + 1. 确定是否可以生成金字塔结构贴图(直接写入到Mipmap结构里),或者生成多张基于2的幕长度贴图。 + +UE侧: +1. 参考使用URuntimeVirtualTextureComponent将点云数据写入VT中。 +2. 在Niagara中根据Niagara 粒子ID对VT进行采样。