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博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15434.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Games202 Lecture11 LTC | Disney principled BRDF | NPR

Shading with microfacet BRDFs under polygonal lighting -Linearly Transformed Cosines(LTC)Real-Time PBR Materials cont. -Disney principled BRDFNon-photorealistic rendering(NPR) Linearly Transformed Cosines(LTC) lobe花瓣 BRDF的2d形状 基本思路: 任意BRDF变…

Flink 内存模型各部分大小计算公式

Flink 的运行平台 如果 Flink 是运行在 yarn 或者 standalone 模式的话&#xff0c;其实都是运行在 JVM 的基础上的&#xff0c;所以首先 Flink 组件运行所需要给 JVM 本身要耗费的内存大小。无论是 JobManager 或者 TaskManager &#xff0c;他们 JVM 内存的大小都是一样的&a…

学习数据结构(8)双向链表

1.双向链表的实现 双向链表一般指带头双向循环链表 &#xff08;1&#xff09;双向链表的声明 &#xff08;2&#xff09;双向链表的打印 &#xff08;3&#xff09;向内存申请节点 &#xff08;4&#xff09;初始化双向链表 或 &#xff08;5&#xff09;尾部插入 &#xf…

【漫话机器学习系列】088.常见的输出层激活函数(Common Output Layer Activation Functions)

在神经网络中&#xff0c;输出层&#xff08;Output Layer&#xff09; 的激活函数&#xff08;Activation Function&#xff09;直接决定了模型的输出形式&#xff0c;并影响损失函数的选择及训练效果。不同的任务类型&#xff08;如分类或回归&#xff09;需要使用不同的激活…

Python 鼠标轨迹 - 防止游戏检测

一.简介 鼠标轨迹算法是一种模拟人类鼠标操作的程序&#xff0c;它能够模拟出自然而真实的鼠标移动路径。 鼠标轨迹算法的底层实现采用C/C语言&#xff0c;原因在于C/C提供了高性能的执行能力和直接访问操作系统底层资源的能力。 鼠标轨迹算法具有以下优势&#xff1a; 模拟…

工业相机在工业生产制造过程中的视觉检测技术应用

随着技术不断发展以及工业4.0时代的到来&#xff0c;利用工业相机进行视觉检测技术已经成为制造业不可或缺的一部分。通过结合先进的计算机视觉、AI算法和自动化设备&#xff0c;工业视觉检测为生产线质量控制和效率提升提供了革命性的解决方案。 一、什么是工业视觉检测技术 …

了解网络层

目录 一、IP协议 二、地址管理 IP地址 概念 作用 格式 网段划分 三、路由选择 网络层要做的事情主要是两个方面&#xff1a; 地址管理&#xff1a;制定一系列的规则&#xff0c;通过地址&#xff0c;描述出网络上一个设备的位置。路由选择&#xff1a;网络环境比较复杂…

NO.11十六届蓝桥杯备战|if-else语句|嵌套if|悬空else|练习4道(C++)

if-else语句 if语句 if语句的语法形式如下&#xff1a; if ( 表达式 ) 语句;表达式成⽴&#xff08;为真&#xff09;&#xff0c;则语句执⾏&#xff0c;表达式不成⽴&#xff08;为假&#xff09;&#xff0c;则语句不执⾏ 0为假&#xff0c;⾮0表⽰真&#xff0c;也就是…

Json-RPC框架项目(一)

目录 1. 项目介绍: 2. 技术选择; 3. 第三方库介绍; 4. 项目功能; 5. 模块功能; 6. 项目实现: 1. 项目介绍: RPC是远程过程调用, 像调用本地接口一样调用远程接口, 进行完成业务处理, 计算任务等, 一个完整的RPC包括: 序列化协议, 通信协议, 连接复用, 服务注册, 服务发…

Discourse 创建和配置用户自定义字段

用户自定义字段能够让你在用户注册的是要求用户提供更多的信息。这些用户提供的信息可以在用户名片&#xff0c;用户摘要页面下显示&#xff0c;甚至还可以通过 Data Explorer plugin 插件进行查询。 本文能够帮助你对这些字段进行配置和设置。 添加一个用户字段 进入 Admin…

从零到一:我的元宵灯谜小程序诞生记

缘起&#xff1a;一碗汤圆引发的灵感 去年元宵节&#xff0c;我正捧着热腾腾的汤圆刷朋友圈&#xff0c;满屏都是"转发锦鲤求灯谜答案"的动态。看着大家对着手机手忙脚乱地切换浏览器查答案&#xff0c;我突然拍案而起&#xff1a;为什么不做一个能即时猜灯谜的微信…

【C++11】lambda和包装器

1.新的类功能 1.1默认的移动构造和移动赋值 原来C类中&#xff0c;有6个默认成员函数&#xff1a;构造函数/析构函数/拷⻉构造函数/拷⻉赋值重载/取地址重 载/const 取地址重载&#xff0c;最后重要的是前4个&#xff0c;后两个⽤处不⼤&#xff0c;默认成员函数就是我们不写…

Java企业电子招投标系统:Spring Cloud微服务架构-强化企业招采竞争力:电子化招投标平台助力效率与成本控制-支持二次开发

​在当今激烈的市场竞争环境下&#xff0c;企业规模的持续扩大使得招采管理变得日益重要&#xff0c;已成为企业提升核心竞争力的关键一环。为了实现更高效、更高质量的招采成果&#xff0c;我们设计了一套基于电子化平台的解决方案&#xff0c;旨在通过电子化招投标系统&#…

计算机毕业设计Spark+大模型知网文献论文推荐系统 知识图谱 知网爬虫 知网数据分析 知网大数据 知网可视化 预测系统 大数据毕业设计 机器学习

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

打家劫舍3

今天和打家讲一下打家劫舍3 题目&#xff1a; 题目链接&#xff1a;337. 打家劫舍 III - 力扣&#xff08;LeetCode&#xff09; 小偷又发现了一个新的可行窃的地区。这个地区只有一个入口&#xff0c;我们称之为root。 除了 root 之外&#xff0c;每栋房子有且只有一个“父“…

指定路径安装Ollama

通过鼠标双击安装&#xff0c;默认会安装到C盘下&#xff0c;如果需要更换默认路径则可以通过命令的方式将Ollama安装到其他盘的某个目录下。 OllamaSetup.exe /DIR"D:\Ollama" #DIR指定安装路径 执行上述命令后&#xff0c;会弹出OllamaSetup.exe安装窗体界面&…

Linux:库

目录 静态库 动态库 目标文件 ELF文件 ELF形成可执行 ELF可执行加载 ELF加载 全局偏移量表GOT(global offset table) 库是写好的&#xff0c;成熟的&#xff0c;可以复用的代码 现实中每个程序都要依赖很多的基础的底层库&#xff0c;不可能都是从零开始的 库有两种…

心脏滴血漏洞复现(CVE-2014-0160)

漏洞范围&#xff1a; OpenSSL 1.0.1版本 漏洞成因&#xff1a; Heartbleed漏洞是由于未能在memcpy()调用受害用户输入内容作为长度参数之前正确进 行边界检查。攻击者可以追踪OpenSSL所分配的64KB缓存、将超出必要范围的字节信息复 制到缓存当中再返回缓存内容&#xff0c;…

一文学会:用DeepSeek R1/V3 + AnythingLLM + Ollama 打造本地化部署的个人/企业知识库,无须担心数据上传云端的泄露问题

文章目录 前言一、AnythingLLM 简介&基础应用1.主要特性2.下载与安装3.配置 LLM 提供商4.AnythingLLM 工作区&对话 二、AnythingLLM 进阶应用&#xff1a;知识增强使用三、AnythingLLM 的 API 访问四、小结1.聊天模式2.本地存储&向量数据库 前言 如果你不知道Olla…

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 0基础…