【UE 渲染】什么是Draw Calls

news/2024/9/22 19:05:06/

目录

  • 0 引言
  • 1 什么是Draw Calls
  • 2 Draw Calls的工作原理
    • 2.1 渲染管线概述
    • 2.2 Draw Call的工作流程
    • 2.3 Draw Call的开销
  • 3 优化Draw Calls的方法
    • 3.1 批处理(Batching)
    • 3.2 实例化(Instancing)
    • 3.3 合并网格(Mesh Merging)
    • 3.4 使用LOD(Level of Detail)
    • 3.5 材质合并(Material Merging)
  • 4 在UE4中查看Draw Calls

请添加图片描述

  • 🙋‍♂️ 作者:海码007
  • 📜 专栏:UE虚幻引擎专栏
  • 💥 标题:【UE 渲染】什么是Draw Calls
  • ❣️ 寄语:书到用时方恨少,事非经过不知难!
  • 🎈 最后:文章作者技术和水平有限,如果文中出现错误,希望大家能指正,同时有问题的话,欢迎大家留言讨论。

0 引言

在Unreal Engine 4(UE4)以及其他图形引擎中,“Draw Calls”(绘制调用)是一个非常重要的概念,特别是在渲染性能优化方面。

1 什么是Draw Calls

Draw Calls是指CPU向GPU发出的绘制命令。每个Draw Call告诉GPU如何渲染一部分场景,包括使用哪些顶点、纹理、着色器等。简单来说,Draw Call是CPU与GPU之间的通信桥梁,用于指示GPU绘制特定的图形。

2 Draw Calls的工作原理

Draw Calls(绘制调用)是图形渲染管线中的一个关键概念,特别是在实时渲染和游戏开发中。理解Draw Calls的工作原理有助于优化渲染性能。以下是详细的工作原理解析:

2.1 渲染管线概述

现代图形渲染管线通常分为以下几个阶段:(渲染管线的流程划分标准有很多,不唯一)

  1. 应用阶段(Application Stage):在这个阶段,CPU负责准备渲染数据并发出Draw Calls。
  2. 几何阶段(Geometry Stage):GPU接收顶点数据并进行几何处理,如顶点变换、裁剪等。
  3. 光栅化阶段(Rasterization Stage):将几何数据转换为像素数据。
  4. 片段阶段(Fragment Stage):对每个像素进行着色处理。
  5. 输出合并阶段(Output Merger Stage):将处理后的像素数据写入帧缓冲区。

2.2 Draw Call的工作流程

以下是Draw Call在渲染管线中的详细工作流程:

  1. 准备数据

    • 顶点数据:包括顶点位置、法线、纹理坐标等。
    • 索引数据:用于定义顶点的连接方式,形成三角形。
    • 材质和纹理:定义物体的外观。
    • 着色器:用于计算顶点和像素的最终颜色。
  2. 设置渲染状态

    • 着色器程序:绑定顶点着色器和片段着色器。
    • 纹理和材质:绑定所需的纹理和材质。
    • 渲染目标:设置帧缓冲区或渲染目标。
  3. 发出Draw Call

    • API调用:通过图形API(如DirectX、OpenGL、Vulkan等)发出绘制命令。例如,在OpenGL中使用glDrawElements,在DirectX中使用DrawIndexed
    • 命令缓冲区:绘制命令被放入命令缓冲区,等待GPU处理。
  4. GPU处理

    • 顶点处理:顶点着色器对顶点数据进行变换和处理。
    • 图元装配:将顶点数据组装成图元(如三角形)。
    • 光栅化:将图元转换为片段(像素)。
    • 片段处理:片段着色器对每个片段进行着色计算。
    • 深度和模板测试:进行深度测试和模板测试,决定片段是否被写入帧缓冲区。
    • 颜色混合:将片段颜色与帧缓冲区中的现有颜色进行混合。
  5. 输出到帧缓冲区

    • 帧缓冲区:最终的像素数据被写入帧缓冲区,准备显示在屏幕上。

2.3 Draw Call的开销

每个Draw Call都有一定的开销,主要包括:

  1. CPU开销:准备数据、设置渲染状态、发出绘制命令等。
  2. GPU开销:处理顶点、光栅化、片段着色等。

大量的Draw Calls会导致CPU和GPU之间的通信开销增加,从而影响渲染性能。

3 优化Draw Calls的方法

优化Draw Calls是提高渲染性能的关键步骤,特别是在实时渲染和游戏开发中。以下是几种常见的优化Draw Calls的方法:

3.1 批处理(Batching)

批处理是将多个小的绘制命令合并成一个大的绘制命令,以减少Draw Calls的数量。

假设我们有多个相同材质的立方体需要绘制:

// 不使用批处理的绘制方式
for (const auto& cube : cubes) {SetMaterial(cube.material);DrawMesh(cube.mesh);
}

使用批处理将这些立方体合并成一个绘制命令:

// 使用批处理的绘制方式
SetMaterial(commonMaterial);
DrawMeshInstanced(cubeMesh, cubes);

在这个示例中,DrawMeshInstanced函数将多个立方体合并成一个绘制命令,从而减少了Draw Calls的数量。

3.2 实例化(Instancing)

实例化技术允许一次性绘制多个相同的几何体(如树木、草丛等),从而减少Draw Calls。

假设我们有多个相同的树模型需要绘制:

// 不使用实例化的绘制方式
for (const auto& tree : trees) {SetMaterial(tree.material);DrawMesh(tree.mesh);
}

使用实例化技术:

// 使用实例化的绘制方式
SetMaterial(treeMaterial);
DrawMeshInstanced(treeMesh, trees);

在这个示例中,DrawMeshInstanced函数将多个树模型合并成一个绘制命令,从而减少了Draw Calls的数量。

3.3 合并网格(Mesh Merging)

将多个小的网格合并成一个大的网格,以减少Draw Calls。

假设我们有多个小的静态物体需要绘制:

// 不使用网格合并的绘制方式
for (const auto& object : objects) {SetMaterial(object.material);DrawMesh(object.mesh);
}

使用网格合并技术:

// 使用网格合并的绘制方式
Mesh mergedMesh = MergeMeshes(objects);
SetMaterial(commonMaterial);
DrawMesh(mergedMesh);

在这个示例中,MergeMeshes函数将多个小的网格合并成一个大的网格,从而减少了Draw Calls的数量。

3.4 使用LOD(Level of Detail)

根据物体与相机的距离,使用不同的细节级别来绘制物体,从而减少远处物体的绘制复杂度。

假设我们有一个复杂的模型需要绘制:

// 不使用LOD的绘制方式
SetMaterial(complexModel.material);
DrawMesh(complexModel.mesh);

使用LOD技术:

// 使用LOD的绘制方式
if (distanceToCamera < nearThreshold) {SetMaterial(highDetailModel.material);DrawMesh(highDetailModel.mesh);
} else if (distanceToCamera < farThreshold) {SetMaterial(mediumDetailModel.material);DrawMesh(mediumDetailModel.mesh);
} else {SetMaterial(lowDetailModel.material);DrawMesh(lowDetailModel.mesh);
}

在这个示例中,根据物体与相机的距离,选择不同的细节级别来绘制物体,从而减少了远处物体的绘制复杂度。

3.5 材质合并(Material Merging)

将多个材质合并成一个材质,以减少材质切换的开销。

假设我们有多个不同材质的物体需要绘制:

// 不使用材质合并的绘制方式
for (const auto& object : objects) {SetMaterial(object.material);DrawMesh(object.mesh);
}

使用材质合并技术:

// 使用材质合并的绘制方式
Material mergedMaterial = MergeMaterials(objects);
SetMaterial(mergedMaterial);
DrawMesh(mergedMesh);

在这个示例中,MergeMaterials函数将多个材质合并成一个材质,从而减少了材质切换的开销。

UE4Draw_Calls_186">4 在UE4中查看Draw Calls

UE4中,你可以使用内置的性能分析工具来查看Draw Calls的数量和其他渲染性能指标。以下是一些常用的方法:

  1. Stat命令:在控制台中输入stat scenerendering命令,可以查看当前场景的渲染统计信息,包括Draw Calls的数量。
  2. Profiler:使用UE4的Profiler工具,可以详细分析渲染性能,包括Draw Calls的数量和开销。
  3. Unreal Insights:这是一个更高级的性能分析工具,提供了更详细的性能数据和可视化。

http://www.ppmy.cn/news/1511413.html

相关文章

后端Web之数据库多表设计

1.概述 项目开发中,在进行数据库表结构设计时&#xff0c;会根据业务需求及业务模块之间的关系&#xff0c;分析并设计表结构&#xff0c;由于业务之间相互关联&#xff0c;所以各个表结构之间也存在着各种联系,基本上分为三种:一对多、多对多、一对一。 数据库的多表设计是关…

day23-测试自动化之Appium的滑动和拖拽事件、高级手势ActionChains、手机操作API

目录 一、滑动和拖拽事件 1.1.应用场景 1.2.swipe滑动事件 1.3.scroll滑动事件 1.4.drag_and_drop拖拽事件 1.5.滑动和拖拽事件的选择 二、高级手势ActionChains 2.1.应用场景 2.2.使用步骤 2.3.注意点 2.4.方法 1).手指轻敲操作 (掌握) 2).手势按下和抬起操作(掌握&#xff0…

ArrayList 和 LinkedList 的区别是什么

数据结构实现&#xff1a;ArrayList 是动态数组的数据结构实现&#xff0c;而 LinkedList 是双向链表的数据结构实现。随机访问效率&#xff1a;ArrayList 比 LinkedList 在随机访问的时候效率要高&#xff0c;因为 LinkedList 是线性的数据存储方式&#xff0c;所以需要移动指…

Swift编译优化:解锁性能提升的秘诀

标题&#xff1a;Swift编译优化&#xff1a;解锁性能提升的秘诀 引言 Swift语言以其现代化的设计和出色的性能而广受开发者青睐。然而&#xff0c;随着项目规模的扩大&#xff0c;编译时间逐渐成为影响开发效率的瓶颈。本文将深入探讨Swift编译器的代码优化技术&#xff0c;提…

[C#]winform基于深度学习算法MVANet部署高精度二分类图像分割onnx模型高精度图像二值化

【训练源码】 https://github.com/qianyu-dlut/MVANet 【参考源码】 https://github.com/hpc203/MVANet-onnxrun 【算法介绍】 二分图像分割&#xff08;DIS&#xff09;最近出现在从高分辨率自然图像中进行高精度对象分割方面。在设计有效的DIS模型时&#xff0c;主要的挑战是…

【Linux入门】网络部分的基础命令及简单的配置DNS实例

文章目录 网络部分的基础命令ifconfig-用于配置和显示网络接口参数基本用法注意 route-用于显示和操作IP路由表基本语法常用选项示例 netstat-用于显示网络状态信息基本语法常用选项示例 ss-网络管理命令ss命令介绍基本语法常用选项基础用法示例 lsof-用于列出当前系统打开文件…

硬件工程师必须掌握的MOS管详细知识

MOS管&#xff0c;全称为金属-氧化物半导体场效应晶体管&#xff08;Metal-Oxide-Semiconductor Field-Effect Transistor&#xff0c;MOSFET&#xff09;&#xff0c;是一种重要的半导体器件&#xff0c;广泛应用于电子工业中各种电路的开关、放大、调制、数字电路和模拟电路等…

2024嵌入式面试:OPPO嵌入式面试题及参考答案

目录 TCP 与 UDP 的区别是什么? 请简述 TCP 的三次握手过程。 HTTP 协议的工作原理是什么? C++11 引入了哪些新特性? 什么是智能指针?如何解决其内存泄漏问题? 进程间有哪些通信方式? CPU 的调度策略有哪些? 如何保证线程安全?多线程编程需要注意哪些问题? S…