From 867ae2ceaa918121f1e0f64c1973db4f123f9ab8 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 23 Jun 2025 09:31:15 +0200 Subject: [PATCH] Add `Texture Size` node to particles --- Source/Editor/Surface/Archetypes/Textures.cs | 15 ++++++++++++++- .../ParticleEmitterGraph.CPU.Particles.cpp | 7 +++++++ .../GPU/ParticleEmitterGraph.GPU.Textures.cpp | 19 +++++++++++++++++-- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs index 1e7dfb56f..56f8154d7 100644 --- a/Source/Editor/Surface/Archetypes/Textures.cs +++ b/Source/Editor/Surface/Archetypes/Textures.cs @@ -459,7 +459,7 @@ namespace FlaxEditor.Surface.Archetypes AlternativeTitles = new string[] { "Lightmap TexCoord" }, Description = "Lightmap UVs", Flags = NodeFlags.MaterialGraph, - Size = new Float2(110, 30), + Size = new Float2(110, 20), Elements = new [] { NodeElementArchetype.Factory.Output(0, "UVs", typeof(Float2), 0) @@ -493,6 +493,19 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.Bool(190, Surface.Constants.LayoutOffsetY * 4, 4), } }, + new NodeArchetype + { + TypeID = 24, + Title = "Texture Size", + Description = "Gets the size of the texture (in pixels). If texture is during streaming, then returns size of the highest resident mip.", + Flags = NodeFlags.ParticleEmitterGraph, + Size = new Float2(160, 20), + Elements = new[] + { + NodeElementArchetype.Factory.Input(0, "Texture", true, typeof(FlaxEngine.Object), 0), + NodeElementArchetype.Factory.Output(0, "Size", typeof(Float3), 1), + } + }, }; } } diff --git a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.Particles.cpp b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.Particles.cpp index 58058afc1..a47e15275 100644 --- a/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.Particles.cpp +++ b/Source/Engine/Particles/Graph/CPU/ParticleEmitterGraph.CPU.Particles.cpp @@ -162,6 +162,13 @@ void ParticleEmitterGraphCPUExecutor::ProcessGroupTextures(Box* box, Node* node, value = Value::Zero; break; } + // Texture Size + case 24: + { + // TODO: support sampling textures in CPU particles + value = Value::Zero; + break; + } default: break; } diff --git a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp index 355548e37..820f8da3d 100644 --- a/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp +++ b/Source/Engine/Particles/Graph/GPU/ParticleEmitterGraph.GPU.Textures.cpp @@ -34,8 +34,8 @@ bool ParticleEmitterGPUGenerator::loadTexture(Node* caller, Box* box, const Seri Value location = tryGetValue(locationBox, Value::InitForZero(VariantType::Float2)); // Convert into a proper type - if (isCubemap || isVolume || isArray) - location = Value::Cast(location, VariantType::Float3); + if (isVolume || isArray) + location = Value::Cast(location, VariantType::Float4); else location = Value::Cast(location, VariantType::Float3); @@ -332,6 +332,21 @@ void ParticleEmitterGPUGenerator::ProcessGroupTextures(Box* box, Node* node, Val value = box == gradientBox ? gradient : distance; break; } + // Texture Size + case 24: + { + value = Value::Zero; + auto textureBox = node->GetBox(0); + if (!textureBox->HasConnection()) + break; + const auto texture = eatBox(textureBox->GetParent(), textureBox->FirstConnection()); + const auto textureParam = findParam(texture.Value); + if (!textureParam) + break; + value = writeLocal(VariantType::Float2, node); + _writer.Write(TEXT("\t{0}.GetDimensions({1}.x, {1}.y);\n"), textureParam->ShaderName, value.Value); + break; + } default: break; }