BlueRoseNote/03-UnrealEngine/VisualEffect/Niagara Module笔记.md

104 lines
5.4 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Niagara Module笔记
date: 2024-02-20 11:14:46
excerpt:
tags:
rating: ⭐
---
# 前言
- UE4 Niagara源码解析:https://zhuanlan.zhihu.com/p/362638250
不论Niagara Emitter有多少的ModuleModule里有多少的脚本脚本中写了多少东西。我们当然要抓住本质数据其都是更新某个渲染器所需要的必要参数也就是如下图所示的信息。
![](https://pic4.zhimg.com/80/v2-46e1c558d019994e189f44cb96bd3e3b_720w.webp)
也就是说只有这些信息是每个渲染器所需要的其会传递给渲染线程并最终提交渲染。任何其他参数仅仅为中间变量。因此我们首先关心的是这个数据是存储在什么地方的。由于一个Emitter可以拥有多个不同的Renderer。因此其本身存储在Emitter级别而不是在Renderer级别。
因此我们最终传递给渲染线程的数据存储在每个Emitter实例FNiagaraEmitterInstance的FNiagaraDataSet身上。不论是GPU粒子还是CPU粒子。
![](https://pic3.zhimg.com/80/v2-6ec8d1bc1de249f2c872f9439b5782d6_720w.webp)
# Module 变量类型
- InputModule输入的变量。
- Local单帧内存在的变量。
- Particle粒子级别**持久存在**的变量。
- Emitter发射器级别**持久存在**的变量。
- Engine引擎提供的只读变量。
# 粒子属性读取
在Module中在ParticleAttributeReader中可以读取对应的例子属性。引用的数据的方式有两种粒子的ID或者Index索引。但是难就难在最初的我不太了解这两个是啥。大致知道是某种编号。ID的话倒是了解一点但不知道它结果分为Index 和Acquire Tag组合在一起的。
PS.**Niagara Debugger**工具可以用于检查粒子ID以及对应变量的变化情况。
# 其他
1. **发射器固定粒子ID**:勾选发射器上**RequiresPersistentIDs**选项即可固定。
2. ExportParticleDataToBlueprint可以输出CPU或者GPU变量
1. 在该节点上添加蓝图变量名。之后在蓝图的BeginPlay()设置这个变量为该蓝图类。之后实现ReceiveParticleData接口。
2. GPU 粒子数据导出是通过从 GPU 内存回读的方式进行的。这需要不可预知的非固定帧数,通常为 1-2 帧。
3. GPU 回读性能受限于回读缓冲区的大小。建议使用最小值的 GPU 固定大小分配来捕捉特定帧中可能发生的所有事件。任何超过固定大小的事件都将无法发送。
3. Window - GeneratedCode可以看到生成出的HLSL代码。
#
Particle的Module都是c++级别写死的。基本位于`Engine\Source\Runtime\Engine\Classes\Particles`目录。基类为**UParticleModule**Niagara的Module都是蓝图资产引擎自带的都在 `Engine\Plugins\FX\Niagara\Content\Modules`。基类为**UNiagaraScript**。
- UNiagaraScriptBase定义了一些编译相关的接口。ModifyCompilationEnvironment()、ShouldCompile()以及获取模拟元数据接口GetSimulationStageMetaData()。
- UNiagaraScript排除掉Editor相关函数主要的函数为
- IsXXXScript()系列判断函数。
- 相关接口PreSave、Serialize、PostLoad基类接口实现。
- FNiagaraVMExecutableData相关
- 编译相关。
- 其他。
## Niagara里面的相关类型
### DataInterface
基类为UNiagaraDataInterface。
- UNiagaraDataInterfaceTextureNiagaraDataInterfaceTextureTemplate.ush
- LoadTexture2D()
- GatherRedTexture2D()
- SampleTexture2D()
- SamplePseudoVolumeTexture()
- GetTextureDimensions()
- GetNumMipLevels()
- UNiagaraDataInterface2DArrayTextureNiagaraDataInterfaceTexture2DArrayTemplate.ush
- LoadTexture()
- GatherRedTexture()
- SampleTexture()
- TextureDimension()
- UNiagaraDataInterfaceVirtualTextureNiagaraDataInterfaceVirtualTextureTemplate.ush
- GetAttributesValid()
- SampleRVTLayer()
- SampleRVT()
## Texture相关Module
- Textures
- SampleTexture
- SamplePseudoVolumeTexture
- 主要调用SamplePseudoVolumeTexture()
- SubUV_TextureSample
-
- WorldAlignedTextureSample
- SubUV
- SubUVAnimation
- V2
- SubUVAnimation
里面的一些节点调用一些函数,这些函数都在对应的**UNiagaraDataInterface**中的**GetFunctions()** 定义,具体的逻辑位于 对应的**xxxTemplate.ush**
## 生成的代码
高斯3D里Niagara采用PositionTexture生成的相关代码
```c++
int2 Emitter_SampleTexture_Texture_TextureSize;
int Emitter_SampleTexture_Texture_MipLevels;
Texture2D Emitter_SampleTexture_Texture_Texture;
SamplerState Emitter_SampleTexture_Texture_TextureSampler;
void SampleTexture2D_Emitter_SampleTexture_Texture(in float2 UV, in float MipLevel, out float4 OutValue)
{
OutValue = Emitter_SampleTexture_Texture_Texture.SampleLevel(Emitter_SampleTexture_Texture_TextureSampler, UV, MipLevel);
}
void SampleTexture_Emitter_Func_(inout FSimulationContext Context)
{
float4 SampleTexture2D_Emitter_SampleTexture_TextureOutput_Value;
SampleTexture2D_Emitter_SampleTexture_Texture(Context.MapSpawn.SampleTexture.UV, Constants_Emitter_SampleTexture_MipLevel, SampleTexture2D_Emitter_SampleTexture_TextureOutput_Value);
Context.MapSpawn.OUTPUT_VAR.SampleTexture.SampledColor = SampleTexture2D_Emitter_SampleTexture_TextureOutput_Value;
Context.MapSpawn.OUTPUT_VAR.SampleTexture.SamplerUV = Context.MapSpawn.SampleTexture.UV;
Context.MapSpawn.Particles.SampleTexture.SampledColor = SampleTexture2D_Emitter_SampleTexture_TextureOutput_Value;
Context.MapSpawn.Particles.SampleTexture.SamplerUV = Context.MapSpawn.SampleTexture.UV;
}
```