当前位置: 首页 > news >正文

UE5.5 PCGFrameWork--GPU CustomHLSL

在上一篇UE5.5 PCGFrameWork使用入门-CSDN博客 大致介绍了UE5 PCG框架的基本使用.

本篇探索PCGFrame的高级应用--GPU点云。也就是利用GPU HLSL编程对点云进行操纵,可以大幅度提升点云生成效率。

目前在UE5 PCG框架中,点云GPU的应用大致分为三类: PointGenerator, PointProcessor, Custom

GPU节点

三种模式下是同一个节点,只是选择模式,GPU变量预声明,GPU函数等存在一些差别。

SourceEditor

SourceEditor可以打开相应模式下的GPU,可以看到预先声明变量和各种公用函数。

PointGenerator

预先生成的点云函数和变量

预生成数量

预定义生成点云的数量, 

在GPU HLSL NumPoints和ElementIndex

输入声明(Input Declartions)

由节点的输入类型和名字动态决定来生成相应输入函数,可以用来在GPU获取点云,地形,纹理等数据,类型有下面几种

 比如增加一个点云输入和地形数据输入

预先生成输入代码:

下面具体分析每种类型输入的相应简单使用

点云输入

"InPosition"名的点云输入

/*** INPUT DATA FUNCTIONS ***/uint InPosition_GetNumData();
uint InPosition_GetNumElements();
uint InPosition_GetNumElements(uint DataIndex);// Valid types: bool, int, float, float2, float3, float4, Rotator (float3), Quat (float4), Transform (float4x4), StringKey (int), Name (uint2)<type> InPosition_Get<type>(uint DataIndex, uint ElementIndex, int AttributeId);
<type> InPosition_Get<type>(uint DataIndex, uint ElementIndex, 'AttributeName');/*** INPUT POINT DATA FUNCTIONS ***/float3 InPosition_GetPosition(uint DataIndex, uint ElementIndex);
float4 InPosition_GetRotation(uint DataIndex, uint ElementIndex);
float3 InPosition_GetScale(uint DataIndex, uint ElementIndex);
float3 InPosition_GetBoundsMin(uint DataIndex, uint ElementIndex);
float3 InPosition_GetBoundsMax(uint DataIndex, uint ElementIndex);
float4 InPosition_GetColor(uint DataIndex, uint ElementIndex);
float InPosition_GetDensity(uint DataIndex, uint ElementIndex);
int InPosition_GetSeed(uint DataIndex, uint ElementIndex);
float InPosition_GetSteepness(uint DataIndex, uint ElementIndex);
float4x4 InPosition_GetPointTransform(uint DataIndex, uint ElementIndex);
bool InPosition_IsPointRemoved(uint DataIndex, uint ElementIndex);

这里暂时不清楚NumData意义,可以确定的并不是点云数量

这里的Type代表你获取数据的类型, 而ElementIndex代码第N个点云,DataIndex暂时推荐都使用0.

InPosition_GetNumElements

获取输入点云的数量

InPosition_Get<type>

这里是获取第N个点云的相应属性, 这里有两种方法

[1]通过属性序号来获取

<type> InPosition_Get<type>(uint DataIndex, uint ElementIndex, int AttributeId);

案例: 获取输入的第2个点云的位置,Position的AttributeId为0

float3 Position = InPosition_GetFloat3(0, 1, 0);

[2]一种是通过属性名字来获取

<type> InPosition_Get<type>(uint DataIndex, uint ElementIndex, 'AttributeName');

案例: 获取输入的第2个点云的位置,Position的名字为'$Position', 注意单引号和$字符前缀

否则会报语法错误.当然类型映射措辞和属性名字不存在也会报语法错误.


float3 Position = InPosition_GetFloat3(0, 0, '$Position');
InPosition_GetXXX

这里比较容易理解,直接获取点云各种属性(位置,缩放,旋转,Color, Bound等等)。

float3 InPosition_GetPosition(uint DataIndex, uint ElementIndex);
float4 InPosition_GetRotation(uint DataIndex, uint ElementIndex);
float3 InPosition_GetScale(uint DataIndex, uint ElementIndex);
float3 InPosition_GetBoundsMin(uint DataIndex, uint ElementIndex);
float3 InPosition_GetBoundsMax(uint DataIndex, uint ElementIndex);
float4 InPosition_GetColor(uint DataIndex, uint ElementIndex);
float InPosition_GetDensity(uint DataIndex, uint ElementIndex);
int InPosition_GetSeed(uint DataIndex, uint ElementIndex);
float InPosition_GetSteepness(uint DataIndex, uint ElementIndex);
float4x4 InPosition_GetPointTransform(uint DataIndex, uint ElementIndex);
bool InPosition_IsPointRemoved(uint DataIndex, uint ElementIndex);

地形输入

"Landscape"名的地形输入

float Landscape_GetHeight(float3 WorldPos);
float3 Landscape_GetNormal(float3 WorldPos);

这里不用解释太多,就是根据WorldPos采样地形的高度和法线等属性

纹理输入

“Texture”名的纹理输入

float2 Texture_GetTexCoords(float2 WorldPos, float2 Min, float2 Max);
float4 Texture_Sample(uint DataIndex, float2 TexCoords);// Computes sample coordinates of the WorldPos relative to the texture data's bounds.float4 
Texture_SampleWorldPos(uint DataIndex, float2 WorldPos);

案例: 在一个PCG Volume的Grid2D点云设置相应的纹理值为点云缩放

float3 Min = GetComponentBoundsMin(); // World-space
float3 Max = GetComponentBoundsMax(); // World-space
float3 InPosition = CreateGrid2D(ElementIndex, NumPoints, Min, Max);
float2 UV = Texture_GetTexCoords(float2(InPosition.x, InPosition.y), Min, Max);
float4 SampleValue = Texture_Sample(0, UV);
Out_SetScale(Out_DataIndex, ElementIndex, float3(SampleValue.x, SampleValue.x, SampleValue.x));
Out_SetPosition(Out_DataIndex, ElementIndex, InPosition);

AttributeSet

输出函数(Output Declarations)

/*** OUTPUT DATA FUNCTIONS ***/// Valid types: bool, int, float, float2, float3, float4, Rotator (float3), Quat (float4), Transform (float4x4), StringKey (int), Name (uint2)void Out_Set<type>(uint DataIndex, uint ElementIndex, int AttributeId, <type> Value);
void Out_Set<type>(uint DataIndex, uint ElementIndex, 'AttributeName', <type> Value);/*** OUTPUT POINT DATA FUNCTIONS ***/void Out_InitializePoint(uint DataIndex, uint ElementIndex);
void Out_CopyElementFrom_<input pin>(uint TargetDataIndex, uint TargetElementIndex, uint SourceDataIndex, uint SourceElementIndex);
bool Out_RemovePoint(uint DataIndex, uint ElementIndex);void Out_SetPosition(uint DataIndex, uint ElementIndex, float3 Position);
void Out_SetRotation(uint DataIndex, uint ElementIndex, float4 Rotation);
void Out_SetScale(uint DataIndex, uint ElementIndex, float3 Scale);
void Out_SetBoundsMin(uint DataIndex, uint ElementIndex, float3 BoundsMin);
void Out_SetBoundsMax(uint DataIndex, uint ElementIndex, float3 BoundsMax);
void Out_SetColor(uint DataIndex, uint ElementIndex, float4 Color);
void Out_SetDensity(uint DataIndex, uint ElementIndex, float Density);
void Out_SetSeed(uint DataIndex, uint ElementIndex, int Seed);
void Out_SetSteepness(uint DataIndex, uint ElementIndex, float Steepness);
void Out_SetPointTransform(uint DataIndex, uint ElementIndex, float4x4 Transform);

设置输出点云数据的各种函数(虽然Ouput引脚支持各种类型,暂时只发现只有Point类型可以输出)

这里和上面的输入函数用法基本一致。主要解释一个特殊函数: 

Out_RemovePoint(Out_DataIndex, ElementIndex);

这个函数用于移除某个ElementIndex的点云

代码例子: 移除ElementIndex为3的整数倍的点云

if(ElementIndex % 3 == 0)Out_RemovePoint(Out_DataIndex, ElementIndex);

辅助函数(Helper Declarations)

/*** HELPER FUNCTIONS ***/int3 GetNumThreads();
uint GetThreadCountMultiplier();// Returns false if thread has no data to operate on.
// Valid pins: InPosition, Landscape, Texture, Out
bool <pin>_GetThreadData(uint ThreadIndex, out uint OutDataIndex, out uint OutElementIndex);float3 GetComponentBoundsMin(); // World-space
float3 GetComponentBoundsMax();
uint GetSeed();float FRand(inout uint Seed); // Returns random float between 0 and 1.
uint ComputeSeed(uint A, uint B);
uint ComputeSeed(uint A, uint B, uint C);
uint ComputeSeedFromPosition(float3 Position);// Returns the position of the Nth point in a 2D or 3D grid with the given constraints.
float3 CreateGrid2D(int ElementIndex, int NumPoints, float3 Min, float3 Max);
float3 CreateGrid2D(int ElementIndex, int NumPoints, int NumRows, float3 Min, float3 Max);
float3 CreateGrid3D(int ElementIndex, int NumPoints, float3 Min, float3 Max);
float3 CreateGrid3D(int ElementIndex, int NumPoints, int NumRows, int NumCols, float3 Min, float3 Max);

GetComponentBoundsMin和GetComponentBoundsMax

获取PCG Volume的BoundMin, BoundMax

随机函数

uint GetSeed();float FRand(inout uint Seed); // Returns random float between 0 and 1.
uint ComputeSeed(uint A, uint B);
uint ComputeSeed(uint A, uint B, uint C);
uint ComputeSeedFromPosition(float3 Position);

和随机种子和随机值密切相关的一组函数,非常常见的配套函数.

GetSeed函数获取的种子来自节点面板:

创建Grid点云函数

// Returns the position of the Nth point in a 2D or 3D grid with the given constraints.
float3 CreateGrid2D(int ElementIndex, int NumPoints, float3 Min, float3 Max);
float3 CreateGrid2D(int ElementIndex, int NumPoints, int NumRows, float3 Min, float3 Max);
float3 CreateGrid3D(int ElementIndex, int NumPoints, float3 Min, float3 Max);
float3 CreateGrid3D(int ElementIndex, int NumPoints, int NumRows, int NumCols, float3 Min, float3 Max);

一组可以让用户快速创建Grid(2D或者3D)点云的函数

演示一个案例: 创建400个 行数为10的Grid 2D点云

使用

float3 CreateGrid2D(int ElementIndex, int NumPoints, int NumRows, float3 Min, float3 Max);

完整代码:

float3 Min = GetComponentBoundsMin(); // World-space
float3 Max = GetComponentBoundsMax(); // World-space
float3 InPosition = CreateGrid2D(ElementIndex, NumPoints, 10, Min, Max);
Out_SetPosition(Out_DataIndex, ElementIndex, InPosition);

演示效果:

自定义函数(ShaderFunction)

用户自定义函数,如何生成各种分形点云,各种自定义几何形状分布的点云等等

演示Demo: 生成一个以某点位置为中心的贴地形点云圆圈

GPU代码相关

Shader Function
/** CUSTOM SHADER FUNCTIONS **/float3 CreateCircle2D(uint ElementIndex, int NumPoints, float3 Center, float Radius)
{// 计算角度(均匀分布)float Angle = 2 * 3.14159265358979323846 * ElementIndex / NumPoints;// 极坐标转笛卡尔坐标float X = Center.x + Radius * cos(Angle);float Z = Center.y + Radius * sin(Angle);return float3(X, Z, 0);
}
Shader Source
float3 InPosition = InPosition_GetFloat3(0, 0, 0);
float3 Position = CreateCircle2D(ElementIndex, NumPoints, InPosition, 3000.0);
float Height = Landscape_GetHeight(Position);
Position.z = Height;
Out_SetPosition(Out_DataIndex, ElementIndex, Position);

运行Demo效果

跟随PCG Actor移动的贴地点云圆圈

PointProcessor和Custom

目前看PointProcessor和Custom像PointGenerator除了无法预定义点云数量, 暂时看不出什么和PointGenerator存在什么区别

参考资料

[1]PCG: Advanced Topics & New Features in UE 5.5 | Unreal Fest 2024

[2]Unreal Engine 5.5 - Compute Shaders With PCG Introduction (Height Thresholding in HLSL)

[3]Unreal Engine 5.5 - PCG Compute Introduction (Fractals in HLSL)

[4]Directx11入门教程四十八之小议ComputeShader_dx11 dispatch-CSDN博客

相关文章:

UE5.5 PCGFrameWork--GPU CustomHLSL

在上一篇UE5.5 PCGFrameWork使用入门-CSDN博客 大致介绍了UE5 PCG框架的基本使用. 本篇探索PCGFrame的高级应用--GPU点云。也就是利用GPU HLSL编程对点云进行操纵&#xff0c;可以大幅度提升点云生成效率。 目前在UE5 PCG框架中&#xff0c;点云GPU的应用大致分为三类: Point…...

RabbitMQ 如何设置限流?

RabbitMQ 的限流&#xff08;流量控制&#xff09;主要依赖于 QoS&#xff08;Quality of Service&#xff09; 机制&#xff0c;即 prefetch count 参数。这个参数控制每个消费者一次最多能获取多少条未确认的消息&#xff0c;从而避免某个消费者被大量消息压垮。 1. RabbitMQ…...

json格式,curl命令,及轻量化处理工具

一. JSON格式 JSON&#xff08;JavaScript Object Notation&#xff09; 是一种轻量级的数据交换格式。它基于一个子集的JavaScript编程语言&#xff0c;使用人类易于阅读的文本格式来存储和表示数据。尽管名字中有“JavaScript”&#xff0c;但JSON是语言无关的&#xff0c;几…...

Postman面试问题

在 API 测试领域&#xff0c;Postman 已成为最流行的工具之一。无论是功能测试、自动化测试&#xff0c;还是接口调试&#xff0c;Postman 都扮演着重要角色。而在软件测试面试中&#xff0c;Postman 相关问题更是高频考点。如果你正在准备面试&#xff0c;赶紧看看这些Postman…...

【JVM详解四】执行引擎

一、概述 Java程序运行时&#xff0c;JVM会加载.class字节码文件&#xff0c;但是字节码并不能直接运行在操作系统之上&#xff0c;而JVM中的执行引擎就是负责将字节码转化为对应平台的机器码让CPU运行的组件。 执行引擎是JVM核心的组成部分之一。可以把JVM架构分成三部分&am…...

esp32 udp 客户端 广播

esp32 udp 客户端 广播 #include "bsp_udpc.h"// #include "com_config.h" // #include "com_xqueue.h"#include "bsp_udpc.h" #define TAG "bsp_udpc"#include <string.h> #include <sys/param.h> #include &q…...

nginx日志存储access日志和error保留180天,每晚把前一天的日志文件压缩成tar.gz

‌logrotate日志分割时&#xff0c;rotate参数是必须要加的‌ 在logrotate的配置文件中&#xff0c;rotate参数用于指定保留的旧日志文件数量。如果不配置rotate参数&#xff0c;默认是0个&#xff0c;也就是只允许存在一份日志&#xff0c;刚切分出来的日志会马上被删除‌ l…...

【Java】多线程和高并发编程(四):阻塞队列(上)基础概念、ArrayBlockingQueue

文章目录 四、阻塞队列1、基础概念1.1 生产者消费者概念1.2 JUC阻塞队列的存取方法 2、ArrayBlockingQueue2.1 ArrayBlockingQueue的基本使用2.2 生产者方法实现原理2.2.1 ArrayBlockingQueue的常见属性2.2.2 add方法实现2.2.3 offer方法实现2.2.4 offer(time,unit)方法2.2.5 p…...

C#控件开发6—旋转按钮

按钮功能&#xff1a;手自动旋转&#xff0c;标签文本显示、点击二次弹框确认&#xff08;源码在最后边&#xff09;&#xff1b; 【制作方法】 找到控件的中心坐标&#xff0c;画背景外环、内圆&#xff1b;再绘制矩形开关&#xff0c;进行角度旋转即可获得&#xff1b; 【关…...

在亚马逊云科技上云原生部署DeepSeek-R1模型(下)

在本系列的上篇中&#xff0c;我们介绍了如何通过Amazon Bedrock部署并测试使用了DeepSeek模型。在接下来的下篇中小李哥将继续介绍&#xff0c;如何利用亚马逊的AI模型训练平台SageMaker AI中的&#xff0c;Amazon Sagemaker JumpStart通过脚本轻松一键式部署DeepSeek预训练模…...

C# COM 组件在.NET 平台上的编程介绍

.NET学习资料 .NET学习资料 .NET学习资料 一、COM 组件简介 COM&#xff08;Component Object Model&#xff09;即组件对象模型&#xff0c;是一种微软提出的软件组件技术&#xff0c;它允许不同的软件模块在二进制层面进行交互。COM 组件可以用多种编程语言开发&#xff0…...

火热的大模型: AIGC架构解析

文章目录 一、背景介绍二、架构描述数据层模型层&#xff08;MaaS&#xff09;服务层&#xff08;PaaS&#xff09;基础设施层&#xff08;IaaS&#xff09;应用层 三、架构分析四、应用场景与价值4.1 典型场景4.2 价值体现 五、总结 一、背景介绍 火热的大模型&#xff0c;每…...

Android LifecycleOwner 闪退,java 继承、多态特性!

1. 闪退 同意隐私政策后&#xff0c;启动进入游戏 Activity 闪退 getLifecycle NullPointerException 空指针异常 FATAL EXCEPTION: main Process: com.primer.aa.gg, PID: 15722 java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{com.primer.aa.…...

PHP 完整表单实例

PHP 完整表单实例 引言 表单是网站与用户交互的重要方式&#xff0c;尤其是在收集用户输入数据时。PHP 作为一种流行的服务器端脚本语言&#xff0c;在处理表单数据方面具有强大的功能。本文将提供一个完整的 PHP 表单实例&#xff0c;涵盖表单创建、数据收集、验证和存储等关…...

深度学习学习笔记(32周)

目录 摘要 abstract 1 Mask R-CNN 2 RoI Align 2.1 RoIPool实验 2.2 RoIAlign实验 3 Mask Branch(FCN) 4 其他细节 4.1 Mask R-CNN损失 4.2 Mask分支损失 4.3 Mask Branch预测使用 摘要 Mask R-CNN是2017年发表的文章&#xff0c;一作是何恺明大神&#xff0c;没错就…...

Web3 开发者的机遇与挑战:技术趋势与职业发展

随着 Web3 技术的迅速发展&#xff0c;互联网的未来正朝着去中心化、用户主权、隐私保护等方向演进。作为 Web3 生态的核心力量&#xff0c;Web3 开发者在推动这一变革中扮演着至关重要的角色。无论是在区块链技术、智能合约开发、去中心化应用&#xff08;DApp&#xff09;的构…...

探索robots.txt:网站管理者的搜索引擎指南

在数字时代&#xff0c;网站如同企业的在线名片&#xff0c;其内容和结构对搜索引擎的可见性至关重要。而在这背后&#xff0c;有一个默默工作的文件——robots.txt&#xff0c;它扮演着搜索引擎与网站之间沟通桥梁的角色。本文将深入探讨robots.txt的功能、编写方法及其在现代…...

LM Studio本地调用模型的方法

首先需要下载LM Studio&#xff0c;&#xff08;LM Studio - Discover, download, and run local LLMs&#xff09;安装好后&#xff0c;需要对index.js文件进行修改&#xff0c;主要是对相关源hugging face的地址修改。 以macOS为例&#xff1a; cd /Applications/LM\ Studi…...

防火墙安全综合实验

防火墙安全综合实验 一、拓扑信息 二、需求及配置 实验步骤 需求一&#xff1a;根据下表&#xff0c;完成相关配置 设备接口VLAN接口类型SW2GE0/0/2VLAN 10AccessGE0/0/3VLAN 20AccessGE0/0/1VLAN List&#xff1a;10 20Trunk 1、创建vlan10和vlan20 2、将接口划分到对应…...

uniapp 编译生成鸿蒙正式app步骤

1&#xff0c;在最新版本DevEco-Studio工具新建一个空项目并生成p12和csr文件&#xff08;构建-生成私钥和证书请求文件&#xff09; 2&#xff0c;华为开发者平台 根据上面生成的csr文件新增cer和p7b文件&#xff0c;分发布和测试 3&#xff0c;在最新版本DevEco-Studio工具 文…...

【进程与线程】如何编写一个守护进程

如何编写一个守护进程。我们首先需要理解守护进程是什么。守护进程是在后台运行的进程&#xff0c;通常没有控制终端&#xff0c;用于执行系统任务&#xff0c;比如服务器或者定时任务。 用户可能想创建一个长期运行的服务&#xff0c;比如Web服务器或者日志监控程序。 首先&a…...

ubuntu安装VMware报错/dev/vmmon加载失败

ubuntu安装VMware报错/dev/vmmon加载失败&#xff0c;解决步骤如下&#xff1a; step1&#xff1a;为vmmon和vmnet组件生成密钥对 openssl req -new -x509 -newkey rsa:2048 -keyout VMW.priv -outform DER -out VMW.der -nodes -days 36500 -subj "/CNVMware/"ste…...

web前端布局--使用element中的Container布局容器

前端页面&#xff0c;跟Qt中一样&#xff0c;都是有布局设置的。 先布局&#xff0c;然后再在各布局中添加显示的内容。 Element网站布局容器&#xff1a;https://element.eleme.cn/#/zh-CN/componet/container 1.将element相应的布局容器代码layout&#xff0c;粘贴到vue项…...

手写一个C++ Android Binder服务及源码分析

手写一个C Android Binder服务及源码分析 前言一、 基于C语言编写Android Binder跨进程通信Demo总结及改进二、C语言编写自己的Binder服务Demo1. binder服务demo功能介绍2. binder服务demo代码结构图3. binder服务demo代码实现3.1 IHelloService.h代码实现3.2 BnHelloService.c…...

git rebase发生冲突时 ☞ 解决冲突

参考&#xff1a;特性分支 Rebase 主干分支...

【通俗易懂说模型】反向传播(附多元分类与Softmax函数)

&#x1f308; 个人主页&#xff1a;十二月的猫-CSDN博客 &#x1f525; 系列专栏&#xff1a; &#x1f3c0;深度学习_十二月的猫的博客-CSDN博客 &#x1f4aa;&#x1f3fb; 十二月的寒冬阻挡不了春天的脚步&#xff0c;十二点的黑夜遮蔽不住黎明的曙光 目录 1. 前言 2. …...

SQL Server查询计划操作符(7.3)——查询计划相关操作符(6)

7.3. 查询计划相关操作符 48)Key Lookup:该操作符对一个有簇索引的表进行书签查找。参数列包含簇索引的名字和用于查找簇索引中数据行的簇键。该操作符总是伴随一个Nested Loops操作符。如果其参数列中出现WITH PREFETCH子句,则查询处理器已决定使用异步预取(预读,read-ah…...

计算机视觉的研究方向、发展历程、发展前景介绍

以下将分别从图像分类、目标检测、语义分割、图像分割&#xff08;此处应主要指实例分割&#xff09;四个方面&#xff0c;为你介绍研究生人工智能计算机视觉领域的应用方向、发展历程以及发展前景。 文章目录 1.图像分类应用方向发展历程发展前景 2.目标检测应用方向发展历程…...

反转字符串-双指针法,

在 Java 中&#xff0c;使用 双指针法 反转字符串是一种高效且直观的方法。以下是详细的解析和代码实现。 1. 双指针法的核心思想 使用两个指针&#xff1a;一个指向字符串的起始位置&#xff08;left&#xff09;&#xff0c;另一个指向字符串的末尾位置&#xff08;right&…...

亚博microros小车-原生ubuntu支持系列 27、手掌控制小车运动

背景知识 本节跟上一个测试类似&#xff1a;亚博microros小车-原生ubuntu支持系列&#xff1a;26手势控制小车基础运动-CSDN博客 都是基于MediaPipe hands做手掌、手指识别的。 为了方便理解&#xff0c;在贴一下手指关键点分布。手掌位置就是靠第9点来识别的。 2、程序说明…...