102 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
		
		
			
		
	
	
			102 lines
		
	
	
		
			5.3 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								title: Niagara Module笔记
							 | 
						|||
| 
								 | 
							
								date: 2024-02-20 11:14:46
							 | 
						|||
| 
								 | 
							
								excerpt: 
							 | 
						|||
| 
								 | 
							
								tags: 
							 | 
						|||
| 
								 | 
							
								rating: ⭐
							 | 
						|||
| 
								 | 
							
								---
							 | 
						|||
| 
								 | 
							
								# 前言
							 | 
						|||
| 
								 | 
							
								- UE4 Niagara源码解析:https://zhuanlan.zhihu.com/p/362638250
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								不论Niagara Emitter有多少的Module,Module里有多少的脚本,脚本中写了多少东西。我们当然要抓住本质数据,其都是更新某个渲染器所需要的必要参数,也就是如下图所示的信息。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								也就是说,只有这些信息是每个渲染器所需要的,其会传递给渲染线程并最终提交渲染。任何其他参数仅仅为中间变量。因此我们首先关心的是这个数据是存储在什么地方的。由于一个Emitter可以拥有多个不同的Renderer。因此其本身存储在Emitter级别,而不是在Renderer级别。
							 | 
						|||
| 
								 | 
							
								因此我们最终传递给渲染线程的数据存储在每个Emitter实例FNiagaraEmitterInstance的FNiagaraDataSet身上。不论是GPU粒子还是CPU粒子。
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								# Module 变量类型
							 | 
						|||
| 
								 | 
							
								- Input:Module输入的变量。
							 | 
						|||
| 
								 | 
							
								- 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。
							 | 
						|||
| 
								 | 
							
								- UNiagaraDataInterfaceTexture:NiagaraDataInterfaceTextureTemplate.ush
							 | 
						|||
| 
								 | 
							
									- LoadTexture2D()
							 | 
						|||
| 
								 | 
							
									- GatherRedTexture2D()
							 | 
						|||
| 
								 | 
							
									- SampleTexture2D()
							 | 
						|||
| 
								 | 
							
									- SamplePseudoVolumeTexture()
							 | 
						|||
| 
								 | 
							
									- GetTextureDimensions()
							 | 
						|||
| 
								 | 
							
									- GetNumMipLevels()
							 | 
						|||
| 
								 | 
							
								- UNiagaraDataInterface2DArrayTexture:NiagaraDataInterfaceTexture2DArrayTemplate.ush
							 | 
						|||
| 
								 | 
							
									- LoadTexture()
							 | 
						|||
| 
								 | 
							
									- GatherRedTexture()
							 | 
						|||
| 
								 | 
							
									- SampleTexture()
							 | 
						|||
| 
								 | 
							
									- TextureDimension()
							 | 
						|||
| 
								 | 
							
								- UNiagaraDataInterfaceVirtualTexture:NiagaraDataInterfaceVirtualTextureTemplate.ush
							 | 
						|||
| 
								 | 
							
									- GetAttributesValid()
							 | 
						|||
| 
								 | 
							
									- SampleRVTLayer()
							 | 
						|||
| 
								 | 
							
									- SampleRVT()
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								## Texture相关Module
							 | 
						|||
| 
								 | 
							
								- Textures
							 | 
						|||
| 
								 | 
							
									- SampleTexture
							 | 
						|||
| 
								 | 
							
									- 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;
							 | 
						|||
| 
								 | 
							
								}
							 | 
						|||
| 
								 | 
							
								```
							 |