Lecture06 Rendering of Mother Nature

Lecture06-1 Terrain Rendering 地形渲染

Simple Idea - Heightfield

Height MapL06_HeightMap Contour MapL06_ContourMap

  • 符合分形原则
  • 渲染
    • 均匀网格,依据Heightfield位移每一个顶点 问题:世界过大时过于复杂

    • 解决方法:LoD -> 非均匀网格 -> 保证场景连续,保证LoD过渡均匀 Adaptive Mesh Tessellation

      L06_AdaptiveMeshTessellation

    • 优化原则

      • 依据Distance to Camera和FoV做LoD
      • Error Bound:简化后的误差小于阈值(一般为呈现在屏幕上一个像素大小)

Tessellation

Triangle-Based Subdivision

L06_TriangleBasedSubdivision

  • 在等腰直角三角形的长边切割 -> 得到两个新的等腰直角三角形 L06_TriangleBasedSubdivisionLevels
  • 二叉树结构,因此又称Binary Triangle-Based Subdivision
  • T-Junctions L06_T-Junction 解决方法:判断若邻边切分更密,则当前边也需同样进行切分 L06_T-JunctionSolution
  • 实际应用中不广泛
QuadTree-Based Subdivision 四叉树分割

L06_QuadTreeBasedSubdivision

  • 优势
    • 易于建构
    • 易于管理几何分区数据,Objects Culling和Data Streaming
    • 符合Texture存储规范
  • 劣势
    • Mesh细分没有三角形细分灵活
    • 叶子节点的网格层级锁定
  • 符合直觉,应用主流 L06_QuadTreeTerrain
  • T-Junctions
    • 与三角形分割类似的问题,细分层级边界处产生
    • 解决方法:Stitching 吸附 L06_Stitching 吸附生成的三角形:退化三角形
  • Triangulated Irregular Network (TIN) L06_TIN
    • 几何细节不丰富处,用较粗的三角形
    • 优势
      • 易于Runtime渲染
      • 更少的三角形
    • 劣势
      • 需要预计算
      • 不够通用
    • 特殊的游戏会用
GPU-Based Tessellation
  • DX11开始: L06_GPUBasedTessllation

    • Hull-Shader Stage:生成Subdivision用的Patch,告诉Control point数据和Tessellation数量
    • Tessellator Stage:做Tessellation
    • Domain-Shader Stage:根据高度图移动顶点
    • Geometry Shader Stage:算Vertex L06_DX11TerrainShaders
  • Mesh Shader Pipeline (DX12) L06_MeshShaderPipeline

  • GPU-Based Tessellation -> Runtime Tessellation -> Real-Time Deformable Terrain 假定地面上每一个Texel是一个“弹簧”,逐Tick更新高度,并实时Tessellation

Non-Heightfield Terrain 悬崖、山洞等

  • 传统做法:在悬崖、山洞处悬空插入物体
  • 一种Trick:山洞处的顶点做标记,GPU处理退化消除;再向山洞中加入物体
  • 目前用的较少一种的方法——体素化
    • 体素化表达世界,在每个体素上存当前空间物质密度
    • Marching Cube:14种方法把cube切分成三角面 L06_MarchingCube
    • 问题:Marching Cube怎么解决近密远疏并保证密封,LUT方法解决
    • 全动态地形——支持打洞

Paint Terrain Materials

混合贴图
  • 问题:边缘过渡羽化 L06_SimpleTextureSplatting

    return texture1.rgb * a1 + texture2.rgb * a2;
  • 解决:Height作为Alpha L06_HeightMapsAlphaBlending

    return height1 > height2 ? texture1.rgb : texture2.rgb
  • 问题:0-1切换信息高频,在远观时过于Sharp 解决:Biased 扰动 L06_HeightMapsAlphaBlendingBiased

    float depth = 0.2; //Height Bias
    float ma = max(texture1.a + height1, texture2.a + height2) - depth;
    float b1 = max(texture1.a + height1 - ma, 0);
    float b2 = max(texture2.a + height2 - ma, 0);
    return (texture1.rgb * b1 + texture2.rgb * b2) / (b1 + b2);
  • 实战中:更多Texture -> Texture Array TextureArray[Index]

  • Parallax and Displacement Mapping 由于表面高度,看到位置B而非A L06_ParallaxMapping 更彻底的方法:Displacement Mapping,直接改变Mesh L06_ParallaxAndDisplacementMapping

  • 大量材质图读写的性能开销 -> Virture Texture

    • 核心思想:把用到的部分装载在内存中,不用的放在硬盘上
    • 把地形分成块(2的幂次切割),只加载能看到的地形
    • L06_VirtualTexture
Virtual Texture Implementation, DirectStorage & DMA
  • GPU cache管理 L06_GPUCacheManagement
  • DirectStorage L06_DirectStorage
  • DMA L06_DMA
浮点数精度溢出
  • 浮点数数值小时精度高、数值大时精度低

  • 摄影机离物体过远时,出现严重抖动与闪烁

  • Camera-Relative Rendering 相机相对性渲染 在MVP变换之前,将相机位置设为世界坐标系原点;重新计算MVP矩阵

  • 其他方法 eg. UE Sublevels,每个Sublevel重置坐标系

Tree Rendering

Decorator Rendering 装饰物,草、灌木等

Road and Decals Rendering

  • Road
    • Spline
    • Spline to Mesh,放置在地形上
    • 路面侵蚀地形,处理高度场
  • Decal 贴片,贴花
  • 全部直接Bake到Virtual Texture上