《游戏编程模式》三、享元模式(Unity 实现)

使用共享以高效地支持大量的细粒度对象。

适用场景:

  • 有太多对象并考虑对其进行轻量化

3.1 森林之树

为了在屏幕上渲染出森林,所有的(树)数据必须按照一定的方式进行组织并沿着总线从 CPU 传送到 GPU 里去

  • 一个多边形网格:定义了树干、树枝和树叶的几何描述
  • 树皮和树叶的纹理
  • 树在森林中的位置以及朝向
  • 调节参数:如大小、颜色等,以使每棵树看起来都不一样

虽然森林中有成千上万的树木,但它们大部分看起来是相似的。它们可能会全部使用相同的网格和纹理数据

我们将对象侵害成两个独立的类------通用数据特殊数据

通用数据:

cs 复制代码
class TreeModel
{
    private Mesh mesh;
    private Texture bark;
    private Texture leaves;
}

整个游戏只需要一份这样的数据,然后游戏世界中每棵树的实例都有一个指向共享的 TreeModel 的引用

cs 复制代码
class Tree
{
    private TreeModel model;
    
    private Vector3 position;
    private float height;
    //...
}

将数据存储在内在中是个好办法,但对渲染毫无助益。在显示之前,森林数据还是必须按照一定的格式上传到 GPU 中,我们需要用显卡能够识别的方式来表达这种资源共享

3.2 一千个实例

为了最大程度地减少发送到 GPU 上的数据量,我们希望

  • 只发送一次共享数据------TreeModel
  • 再单独将每棵树的特殊数据上传
  • 告诉 GPU:使用那个共享模型来渲染每个实例

3.3 享元模式

有太多对象并考虑对其进行轻量化时它便能派上用场

3.4 扎根之地

地面也要在我们的游戏中被表示出来。如草地、泥土、丘陵、湖泊==,我们将使用基于瓦片(Tile-based)的技术来构建地面,地面是一个由许多细小瓦片组成的巨大网格,每块瓦片都由某种地形所覆盖

cs 复制代码
class Terrain
{
    private int moveCost;
    private bool isWater;
    private Texture texture;
    
    Terrain(int moveCost, bool isWater, Texture texture) { ... }
    //...
}

但我们不希望为每块瓦片构建地形实例付出成本,因为同类的地形实例是相同的

cs 复制代码
class World
{
    private Terrain[,] tiles = new Terrain[width, height];
    //...
}

每个相同地形的瓦片都会引用相同的地形实例

相关推荐
AI大法师1 小时前
品牌焕新不只换 Logo:捷豹案例里的触点重构方法
大数据·人工智能·设计模式·新媒体运营
AI人工智能+电脑小能手1 天前
大白话说Java设计模式-23-桥接模式(源码剖析篇)
java·设计模式·jdbc·桥接模式·源码分析·awt·java logging
嘟嘟07171 天前
TypeScript 工具类型通关:Pick、Omit、Partial、Record 区别与 Omit 等价实现一次讲清
设计模式·面试·typescript
SL_staff1 天前
中小离散制造如何用工艺路线模板解决‘人走流程丢’——JVS-APS 实践解析
java·设计模式·全栈
Asize1 天前
3 种设计模式 + DI:Nest.js 后端第一课
后端·设计模式·nestjs
St_rive2 天前
Page Object设计模式
java·开发语言·设计模式
烬羽2 天前
NestJS 依赖注入:Controller 里那个没有 new 的 service,到底从哪来的?
设计模式·typescript·nestjs
用户938515635073 天前
工厂模式与 Nest.js 核心思想 —— 从蜜雪冰城到企业级架构
后端·设计模式·nestjs
烬羽3 天前
从 nest new 到 Hello World:一个最小 NestJS 项目,讲透工厂 + 装饰器 + 模块化
设计模式·node.js·nestjs
艺艺生辉4 天前
从if-else到策略模式
后端·设计模式