diff --git a/Source/Editor/Surface/Archetypes/Textures.cs b/Source/Editor/Surface/Archetypes/Textures.cs
index 0e1e8ac72..61ac3d6fe 100644
--- a/Source/Editor/Surface/Archetypes/Textures.cs
+++ b/Source/Editor/Surface/Archetypes/Textures.cs
@@ -1,6 +1,8 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
using System;
+using FlaxEditor.Content.Settings;
+using FlaxEditor.GUI;
using FlaxEngine;
namespace FlaxEditor.Surface.Archetypes
@@ -11,30 +13,77 @@ namespace FlaxEditor.Surface.Archetypes
[HideInEditor]
public static class Textures
{
- ///
- /// Common samplers types.
- ///
- public enum CommonSamplerType
+ internal enum CommonSamplerType
{
- ///
- /// The linear clamp
- ///
LinearClamp = 0,
-
- ///
- /// The point clamp
- ///
PointClamp = 1,
-
- ///
- /// The linear wrap
- ///
LinearWrap = 2,
-
- ///
- /// The point wrap
- ///
PointWrap = 3,
+ TextureGroup = 4,
+ }
+
+ internal class SampleTextureNode : SurfaceNode
+ {
+ private ComboBox _textureGroupPicker;
+
+ public SampleTextureNode(uint id, VisjectSurfaceContext context, NodeArchetype nodeArch, GroupArchetype groupArch)
+ : base(id, context, nodeArch, groupArch)
+ {
+ }
+
+ public override void OnValuesChanged()
+ {
+ base.OnValuesChanged();
+
+ UpdateUI();
+ }
+
+ public override void OnLoaded()
+ {
+ base.OnLoaded();
+
+ UpdateUI();
+ }
+
+ private void UpdateUI()
+ {
+ if ((int)Values[0] == (int)CommonSamplerType.TextureGroup)
+ {
+ if (_textureGroupPicker == null)
+ {
+ _textureGroupPicker = new ComboBox
+ {
+ Location = new Vector2(FlaxEditor.Surface.Constants.NodeMarginX + 50, FlaxEditor.Surface.Constants.NodeMarginY + FlaxEditor.Surface.Constants.NodeHeaderSize + FlaxEditor.Surface.Constants.LayoutOffsetY * 5),
+ Width = 100,
+ Parent = this,
+ };
+ _textureGroupPicker.SelectedIndexChanged += OnSelectedTextureGroupChanged;
+ var groups = GameSettings.Load();
+ if (groups?.TextureGroups != null)
+ {
+ for (int i = 0; i < groups.TextureGroups.Length; i++)
+ _textureGroupPicker.AddItem(groups.TextureGroups[i].Name);
+ }
+ }
+ else
+ {
+ _textureGroupPicker.Visible = true;
+ }
+ _textureGroupPicker.SelectedIndexChanged -= OnSelectedTextureGroupChanged;
+ _textureGroupPicker.SelectedIndex = (int)Values[2];
+ _textureGroupPicker.SelectedIndexChanged += OnSelectedTextureGroupChanged;
+ }
+ else if (_textureGroupPicker != null)
+ {
+ _textureGroupPicker.Visible = false;
+ }
+ ResizeAuto();
+ }
+
+ private void OnSelectedTextureGroupChanged(ComboBox comboBox)
+ {
+ SetValue(2, _textureGroupPicker.SelectedIndex);
+ }
}
///
@@ -213,6 +262,7 @@ namespace FlaxEditor.Surface.Archetypes
new NodeArchetype
{
TypeID = 9,
+ Create = (id, context, arch, groupArch) => new SampleTextureNode(id, context, arch, groupArch),
Title = "Sample Texture",
Description = "Custom texture sampling",
Flags = NodeFlags.MaterialGraph,
@@ -222,6 +272,7 @@ namespace FlaxEditor.Surface.Archetypes
{
0,
-1.0f,
+ 0,
},
Elements = new[]
{
@@ -230,7 +281,7 @@ namespace FlaxEditor.Surface.Archetypes
NodeElementArchetype.Factory.Input(2, "Level", true, typeof(float), 2, 1),
NodeElementArchetype.Factory.Input(3, "Offset", true, typeof(Vector2), 3),
NodeElementArchetype.Factory.Output(0, "Color", typeof(Vector4), 4),
- NodeElementArchetype.Factory.Text(0, Surface.Constants.LayoutOffsetY * 4 + 4, "Sampler"),
+ NodeElementArchetype.Factory.Text(0, Surface.Constants.LayoutOffsetY * 4, "Sampler"),
NodeElementArchetype.Factory.ComboBox(50, Surface.Constants.LayoutOffsetY * 4, 100, 0, typeof(CommonSamplerType))
}
},
diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs
index 3eab59f80..fe146dcb2 100644
--- a/Source/Editor/Utilities/Utils.cs
+++ b/Source/Editor/Utilities/Utils.cs
@@ -12,6 +12,14 @@ using FlaxEditor.Scripting;
using FlaxEngine;
using FlaxEngine.GUI;
+namespace FlaxEngine
+{
+ partial struct TextureGroup
+ {
+ internal bool IsAnisotropic => SamplerFilter == GPUSamplerFilter.Anisotropic;
+ }
+}
+
namespace FlaxEditor.Utilities
{
///
diff --git a/Source/Engine/Graphics/GPUResource.h b/Source/Engine/Graphics/GPUResource.h
index 5f5a01d41..94753205f 100644
--- a/Source/Engine/Graphics/GPUResource.h
+++ b/Source/Engine/Graphics/GPUResource.h
@@ -10,6 +10,7 @@
/// Releases GPU resource memory and deletes object.
///
#define SAFE_DELETE_GPU_RESOURCE(x) if (x) { (x)->DeleteObjectNow(); (x) = nullptr; }
+#define SAFE_DELETE_GPU_RESOURCES(x) for (auto& e : (x)) if (e) { e->DeleteObjectNow(); e = nullptr; }
///
/// The base class for all GPU resources.
diff --git a/Source/Engine/Graphics/MaterialParams.cs b/Source/Engine/Graphics/MaterialParams.cs
index 65d2e3aa3..c817124c7 100644
--- a/Source/Engine/Graphics/MaterialParams.cs
+++ b/Source/Engine/Graphics/MaterialParams.cs
@@ -101,5 +101,10 @@ namespace FlaxEngine
/// The gameplay global.
///
GameplayGlobal = 18,
+
+ ///
+ /// The texture sampler derived from texture group settings.
+ ///
+ TextureGroupSampler = 19,
}
}
diff --git a/Source/Engine/Graphics/Materials/MaterialParams.cpp b/Source/Engine/Graphics/Materials/MaterialParams.cpp
index 01483558d..626996575 100644
--- a/Source/Engine/Graphics/Materials/MaterialParams.cpp
+++ b/Source/Engine/Graphics/Materials/MaterialParams.cpp
@@ -11,6 +11,7 @@
#include "Engine/Graphics/RenderBuffers.h"
#include "Engine/Graphics/GPUDevice.h"
#include "Engine/Graphics/GPULimits.h"
+#include "Engine/Streaming/Streaming.h"
bool MaterialInfo8::operator==(const MaterialInfo8& other) const
{
@@ -153,6 +154,9 @@ const Char* ToString(MaterialParameterType value)
case MaterialParameterType::GameplayGlobal:
result = TEXT("GameplayGlobal");
break;
+ case MaterialParameterType::TextureGroupSampler:
+ result = TEXT("TextureGroupSampler");
+ break;
default:
result = TEXT("");
break;
@@ -169,6 +173,7 @@ Variant MaterialParameter::GetValue() const
case MaterialParameterType::Integer:
case MaterialParameterType::SceneTexture:
case MaterialParameterType::ChannelMask:
+ case MaterialParameterType::TextureGroupSampler:
return _asInteger;
case MaterialParameterType::Float:
return _asFloat;
@@ -209,6 +214,7 @@ void MaterialParameter::SetValue(const Variant& value)
case MaterialParameterType::Integer:
case MaterialParameterType::SceneTexture:
case MaterialParameterType::ChannelMask:
+ case MaterialParameterType::TextureGroupSampler:
_asInteger = (int32)value;
break;
case MaterialParameterType::Float:
@@ -446,6 +452,9 @@ void MaterialParameter::Bind(BindMeta& meta) const
}
}
break;
+ case MaterialParameterType::TextureGroupSampler:
+ meta.Context->BindSampler(_registerIndex, Streaming::GetTextureGroupSampler(_asInteger));
+ break;
default:
break;
}
@@ -475,6 +484,7 @@ void MaterialParameter::clone(const MaterialParameter* param)
break;
case MaterialParameterType::Integer:
case MaterialParameterType::SceneTexture:
+ case MaterialParameterType::TextureGroupSampler:
_asInteger = param->_asInteger;
break;
case MaterialParameterType::Float:
@@ -654,6 +664,7 @@ bool MaterialParams::Load(ReadStream* stream)
case MaterialParameterType::Integer:
case MaterialParameterType::SceneTexture:
case MaterialParameterType::ChannelMask:
+ case MaterialParameterType::TextureGroupSampler:
stream->ReadInt32(¶m->_asInteger);
break;
case MaterialParameterType::Float:
@@ -727,6 +738,7 @@ bool MaterialParams::Load(ReadStream* stream)
break;
case MaterialParameterType::Integer:
case MaterialParameterType::SceneTexture:
+ case MaterialParameterType::TextureGroupSampler:
stream->ReadInt32(¶m->_asInteger);
break;
case MaterialParameterType::Float:
@@ -801,6 +813,7 @@ bool MaterialParams::Load(ReadStream* stream)
case MaterialParameterType::Integer:
case MaterialParameterType::SceneTexture:
case MaterialParameterType::ChannelMask:
+ case MaterialParameterType::TextureGroupSampler:
stream->ReadInt32(¶m->_asInteger);
break;
case MaterialParameterType::Float:
@@ -893,6 +906,7 @@ void MaterialParams::Save(WriteStream* stream)
case MaterialParameterType::Integer:
case MaterialParameterType::SceneTexture:
case MaterialParameterType::ChannelMask:
+ case MaterialParameterType::TextureGroupSampler:
stream->WriteInt32(param->_asInteger);
break;
case MaterialParameterType::Float:
@@ -967,6 +981,7 @@ void MaterialParams::Save(WriteStream* stream, const ArrayWriteInt32(param.AsInteger);
break;
case MaterialParameterType::Float:
diff --git a/Source/Engine/Graphics/Materials/MaterialParams.h b/Source/Engine/Graphics/Materials/MaterialParams.h
index 63ee16677..dde8ed73c 100644
--- a/Source/Engine/Graphics/Materials/MaterialParams.h
+++ b/Source/Engine/Graphics/Materials/MaterialParams.h
@@ -123,6 +123,11 @@ enum class MaterialParameterType : byte
/// The gameplay global.
///
GameplayGlobal = 18,
+
+ ///
+ /// The texture sampler derived from texture group settings.
+ ///
+ TextureGroupSampler = 19,
};
const Char* ToString(MaterialParameterType value);
diff --git a/Source/Engine/Graphics/Materials/MaterialShader.h b/Source/Engine/Graphics/Materials/MaterialShader.h
index 4196b6de4..3eb6a45f8 100644
--- a/Source/Engine/Graphics/Materials/MaterialShader.h
+++ b/Source/Engine/Graphics/Materials/MaterialShader.h
@@ -52,10 +52,7 @@ protected:
void Release()
{
- for (int32 i = 0; i < ARRAY_COUNT(PS); i++)
- {
- SAFE_DELETE_GPU_RESOURCE(PS[i]);
- }
+ SAFE_DELETE_GPU_RESOURCES(PS);
}
};
diff --git a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp
index c2582ad95..4197cab8a 100644
--- a/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp
+++ b/Source/Engine/GraphicsDevice/Vulkan/GPUDeviceVulkan.cpp
@@ -863,11 +863,7 @@ GPUBufferVulkan* HelperResourcesVulkan::GetDummyVertexBuffer()
void HelperResourcesVulkan::Dispose()
{
- for (int32 i = 0; i < ARRAY_COUNT(_dummyTextures); i++)
- {
- SAFE_DELETE_GPU_RESOURCE(_dummyTextures[i]);
- }
-
+ SAFE_DELETE_GPU_RESOURCES(_dummyTextures);
SAFE_DELETE_GPU_RESOURCE(_dummyBuffer);
SAFE_DELETE_GPU_RESOURCE(_dummyVB);
diff --git a/Source/Engine/Renderer/AmbientOcclusionPass.cpp b/Source/Engine/Renderer/AmbientOcclusionPass.cpp
index 7e4ac0d33..2b536d866 100644
--- a/Source/Engine/Renderer/AmbientOcclusionPass.cpp
+++ b/Source/Engine/Renderer/AmbientOcclusionPass.cpp
@@ -188,10 +188,8 @@ void AmbientOcclusionPass::Dispose()
// Delete pipeline states
SAFE_DELETE_GPU_RESOURCE(_psPrepareDepths);
SAFE_DELETE_GPU_RESOURCE(_psPrepareDepthsHalf);
- for (int32 i = 0; i < ARRAY_COUNT(_psPrepareDepthMip); i++)
- SAFE_DELETE_GPU_RESOURCE(_psPrepareDepthMip[i]);
- for (int32 i = 0; i < ARRAY_COUNT(_psGenerate); i++)
- SAFE_DELETE_GPU_RESOURCE(_psGenerate[i]);
+ SAFE_DELETE_GPU_RESOURCES(_psPrepareDepthMip);
+ SAFE_DELETE_GPU_RESOURCES(_psGenerate);
SAFE_DELETE_GPU_RESOURCE(_psSmartBlur);
SAFE_DELETE_GPU_RESOURCE(_psSmartBlurWide);
SAFE_DELETE_GPU_RESOURCE(_psNonSmartBlur);
diff --git a/Source/Engine/Streaming/Streaming.cpp b/Source/Engine/Streaming/Streaming.cpp
index 395a890b9..7057f9ffd 100644
--- a/Source/Engine/Streaming/Streaming.cpp
+++ b/Source/Engine/Streaming/Streaming.cpp
@@ -9,6 +9,7 @@
#include "Engine/Threading/Threading.h"
#include "Engine/Threading/Task.h"
#include "Engine/Graphics/GPUDevice.h"
+#include "Engine/Graphics/Textures/GPUSampler.h"
#include "Engine/Serialization/Serialization.h"
namespace StreamingManagerImpl
@@ -17,6 +18,8 @@ namespace StreamingManagerImpl
int32 LastUpdateResourcesIndex = 0;
CriticalSection ResourcesLock;
Array Resources;
+ Array> TextureGroupSamplers;
+ GPUSampler* FallbackSampler = nullptr;
}
using namespace StreamingManagerImpl;
@@ -30,6 +33,7 @@ public:
}
void Update() override;
+ void BeforeExit() override;
};
StreamingManagerService StreamingManagerServiceInstance;
@@ -39,6 +43,8 @@ Array> Streaming::TextureGroups;
void StreamingSettings::Apply()
{
Streaming::TextureGroups = TextureGroups;
+ SAFE_DELETE_GPU_RESOURCES(TextureGroupSamplers);
+ TextureGroupSamplers.Resize(TextureGroups.Count(), false);
}
void StreamingSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
@@ -217,6 +223,13 @@ void StreamingManagerService::Update()
// TODO: add StreamingManager stats, update time per frame, updates per frame, etc.
}
+void StreamingManagerService::BeforeExit()
+{
+ SAFE_DELETE_GPU_RESOURCE(FallbackSampler);
+ SAFE_DELETE_GPU_RESOURCES(TextureGroupSamplers);
+ TextureGroupSamplers.Resize(0);
+}
+
void Streaming::RequestStreamingUpdate()
{
PROFILE_CPU();
@@ -225,3 +238,35 @@ void Streaming::RequestStreamingUpdate()
e->RequestStreamingUpdate();
ResourcesLock.Unlock();
}
+
+GPUSampler* Streaming::GetTextureGroupSampler(int32 index)
+{
+ GPUSampler* sampler = nullptr;
+ if (index >= 0 && index < TextureGroupSamplers.Count())
+ {
+ // Sampler from texture group options
+ auto& group = TextureGroups[index];
+ auto desc = GPUSamplerDescription::New(group.SamplerFilter);
+ desc.MaxAnisotropy = group.MaxAnisotropy;
+ sampler = TextureGroupSamplers[index];
+ if (!sampler)
+ {
+ sampler = GPUSampler::New();
+ sampler->Init(desc);
+ TextureGroupSamplers[index] = sampler;
+ }
+ if (sampler->GetDescription().Filter != desc.Filter || sampler->GetDescription().MaxAnisotropy != desc.MaxAnisotropy)
+ sampler->Init(desc);
+ }
+ if (!sampler)
+ {
+ // Default sampler to prevent issue
+ if (!FallbackSampler)
+ {
+ FallbackSampler = GPUSampler::New();
+ FallbackSampler->Init(GPUSamplerDescription::New(GPUSamplerFilter::Trilinear));
+ }
+ sampler = FallbackSampler;
+ }
+ return sampler;
+}
diff --git a/Source/Engine/Streaming/Streaming.h b/Source/Engine/Streaming/Streaming.h
index 2afb404f6..b164eeb86 100644
--- a/Source/Engine/Streaming/Streaming.h
+++ b/Source/Engine/Streaming/Streaming.h
@@ -6,6 +6,8 @@
#include "Engine/Scripting/ScriptingType.h"
#include "TextureGroup.h"
+class GPUSampler;
+
///
/// The content streaming service.
///
@@ -22,4 +24,11 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Streaming);
/// Requests the streaming update for all the loaded resources. Use it to refresh content streaming after changing configuration.
///
API_FUNCTION() static void RequestStreamingUpdate();
+
+ ///
+ /// Gets the texture sampler for a given texture group. Sampler objects is managed and cached by streaming service. Returned value is always valid (uses fallback object).
+ ///
+ /// The texture group index.
+ /// The texture sampler (always valid).
+ API_FUNCTION() static GPUSampler* GetTextureGroupSampler(int32 index);
};
diff --git a/Source/Engine/Streaming/TextureGroup.h b/Source/Engine/Streaming/TextureGroup.h
index 87ad7dc4d..0569e2653 100644
--- a/Source/Engine/Streaming/TextureGroup.h
+++ b/Source/Engine/Streaming/TextureGroup.h
@@ -4,6 +4,7 @@
#include "Engine/Core/Types/String.h"
#include "Engine/Core/ISerializable.h"
+#include "Engine/Graphics/Textures/GPUSamplerDescription.h"
#if USE_EDITOR
#include "Engine/Core/Collections/Dictionary.h"
#endif
@@ -22,6 +23,18 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(TextureGroup);
API_FIELD(Attributes="EditorOrder(10)")
String Name;
+ ///
+ /// The default filtering method for samplers using this texture group.
+ ///
+ API_FIELD(Attributes="EditorOrder(15)")
+ GPUSamplerFilter SamplerFilter = GPUSamplerFilter::Trilinear;
+
+ ///
+ /// The maximum number of samples that can be used to improve the quality of sample footprints that are anisotropic. Higher values improve texturing but reduce performance. Limited by GPU capabilities and used only if SamplerFilter is Anisotropic.
+ ///
+ API_FIELD(Attributes="EditorOrder(16), Limit(1, 16), VisibleIf(\"IsAnisotropic\")")
+ int32 MaxAnisotropy = 16;
+
///
/// The quality scale factor applied to textures in this group. Can be used to increase or decrease textures resolution. In range 0-1 where 0 means lowest quality, 1 means full quality.
///
diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp
index f8a18b76e..9237ce9cb 100644
--- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp
+++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Textures.cpp
@@ -290,6 +290,7 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
PointClamp = 1,
LinearWrap = 2,
PointWrap = 3,
+ TextureGroup = 4,
};
const Char* SamplerNames[]
{
@@ -345,8 +346,18 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
const bool useLevel = levelBox->HasConnection() || (int32)node->Values[1] != -1;
const bool useOffset = offsetBox->HasConnection();
const auto offset = useOffset ? eatBox(offsetBox->GetParent(), offsetBox->FirstConnection()) : Value::Zero;
+ const Char* samplerName;
const int32 samplerIndex = node->Values[0].AsInt;
- if (samplerIndex < 0 || samplerIndex >= ARRAY_COUNT(SamplerNames))
+ if (samplerIndex == TextureGroup)
+ {
+ auto& textureGroupSampler = findOrAddTextureGroupSampler(node->Values[2].AsInt);
+ samplerName = *textureGroupSampler.ShaderName;
+ }
+ else if (samplerIndex >= 0 && samplerIndex < ARRAY_COUNT(SamplerNames))
+ {
+ samplerName = SamplerNames[samplerIndex];
+ }
+ else
{
OnError(node, box, TEXT("Invalid texture sampler."));
return;
@@ -372,7 +383,7 @@ void MaterialGenerator::ProcessGroupTextures(Box* box, Node* node, Value& value)
// Sample texture
const String sampledValue = String::Format(format,
texture.Value, // {0}
- SamplerNames[samplerIndex], // {1}
+ samplerName, // {1}
uvs.Value, // {2}
level.Value, // {3}
offset.Value // {4}
diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp
index 2669fae79..afe98e34a 100644
--- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp
+++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.cpp
@@ -422,7 +422,7 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
// Resources
{
- int32 srv = 0;
+ int32 srv = 0, sampler = GPU_STATIC_SAMPLERS_COUNT;
switch (baseLayer->Domain)
{
case MaterialDomain::Surface:
@@ -466,7 +466,9 @@ bool MaterialGenerator::Generate(WriteStream& source, MaterialInfo& materialInfo
}
if (_parameters.HasItems())
{
- const auto error = ShaderGraphUtilities::GenerateShaderResources(_writer, _parameters, srv);
+ auto error = ShaderGraphUtilities::GenerateShaderResources(_writer, _parameters, srv);
+ if (!error)
+ error = ShaderGraphUtilities::GenerateSamplers(_writer, _parameters, sampler);
if (error)
{
OnError(nullptr, nullptr, error);
diff --git a/Source/Engine/Visject/ShaderGraph.cpp b/Source/Engine/Visject/ShaderGraph.cpp
index 754c1aac9..59904135b 100644
--- a/Source/Engine/Visject/ShaderGraph.cpp
+++ b/Source/Engine/Visject/ShaderGraph.cpp
@@ -1273,6 +1273,30 @@ SerializedMaterialParam ShaderGenerator::findOrAddSceneTexture(MaterialSceneText
return param;
}
+SerializedMaterialParam& ShaderGenerator::findOrAddTextureGroupSampler(int32 index)
+{
+ // Find
+ for (int32 i = 0; i < _parameters.Count(); i++)
+ {
+ SerializedMaterialParam& param = _parameters[i];
+ if (!param.IsPublic && param.Type == MaterialParameterType::TextureGroupSampler && param.AsInteger == index)
+ {
+ return param;
+ }
+ }
+
+ // Create
+ SerializedMaterialParam& param = _parameters.AddOne();
+ param.Type = MaterialParameterType::TextureGroupSampler;
+ param.IsPublic = false;
+ param.Override = true;
+ param.Name = TEXT("Texture Group Sampler");
+ param.ShaderName = getParamName(_parameters.Count());
+ param.AsInteger = index;
+ param.ID = Guid(_parameters.Count(), 0, 0, 3); // Assign temporary id
+ return param;
+}
+
String ShaderGenerator::getLocalName(int32 index)
{
return TEXT("local") + StringUtils::ToString(index);
diff --git a/Source/Engine/Visject/ShaderGraph.h b/Source/Engine/Visject/ShaderGraph.h
index 1bcfd747a..f73be6506 100644
--- a/Source/Engine/Visject/ShaderGraph.h
+++ b/Source/Engine/Visject/ShaderGraph.h
@@ -285,6 +285,7 @@ protected:
SerializedMaterialParam findOrAddNormalMap(const Guid& id);
SerializedMaterialParam findOrAddCubeTexture(const Guid& id);
SerializedMaterialParam findOrAddSceneTexture(MaterialSceneTextures type);
+ SerializedMaterialParam& findOrAddTextureGroupSampler(int32 index);
static String getLocalName(int32 index);
static String getParamName(int32 index);
diff --git a/Source/Engine/Visject/ShaderGraphUtilities.cpp b/Source/Engine/Visject/ShaderGraphUtilities.cpp
index c698164d2..f5e8ba66f 100644
--- a/Source/Engine/Visject/ShaderGraphUtilities.cpp
+++ b/Source/Engine/Visject/ShaderGraphUtilities.cpp
@@ -136,11 +136,9 @@ void ShaderGraphUtilities::GenerateShaderConstantBuffer(TextWriterUnicode& write
const Char* ShaderGraphUtilities::GenerateShaderResources(TextWriterUnicode& writer, Array& parameters, int32 startRegister)
{
- int32 registerIndex = startRegister;
for (int32 i = 0; i < parameters.Count(); i++)
{
auto& param = parameters[i];
-
const Char* format;
switch (param.Type)
{
@@ -164,15 +162,12 @@ const Char* ShaderGraphUtilities::GenerateShaderResources(TextWriterUnicode& wri
format = nullptr;
break;
}
-
if (format)
{
param.Offset = 0;
- param.RegisterIndex = registerIndex;
- writer.WriteLine(format, param.ShaderName, static_cast(registerIndex));
- registerIndex++;
-
- // Validate Shader Resource count limit
+ param.RegisterIndex = (byte)startRegister;
+ writer.WriteLine(format, param.ShaderName, startRegister);
+ startRegister++;
if (param.RegisterIndex >= GPU_MAX_SR_BINDED)
{
return TEXT("Too many textures used. The maximum supported amount is " MACRO_TO_STR(GPU_MAX_SR_BINDED) " (including lightmaps and utility textures for lighting).");
@@ -182,6 +177,36 @@ const Char* ShaderGraphUtilities::GenerateShaderResources(TextWriterUnicode& wri
return nullptr;
}
+const Char* ShaderGraphUtilities::GenerateSamplers(TextWriterUnicode& writer, Array& parameters, int32 startRegister)
+{
+ for (int32 i = 0; i < parameters.Count(); i++)
+ {
+ auto& param = parameters[i];
+ const Char* format;
+ switch (param.Type)
+ {
+ case MaterialParameterType::TextureGroupSampler:
+ format = TEXT("sampler {0} : register(s{1});");
+ break;
+ default:
+ format = nullptr;
+ break;
+ }
+ if (format)
+ {
+ param.Offset = 0;
+ param.RegisterIndex = (byte)startRegister;
+ writer.WriteLine(format, param.ShaderName, startRegister);
+ startRegister++;
+ if (param.RegisterIndex >= GPU_MAX_SAMPLER_BINDED)
+ {
+ return TEXT("Too many samplers used. The maximum supported amount is " MACRO_TO_STR(GPU_MAX_SAMPLER_BINDED) ".");
+ }
+ }
+ }
+ return nullptr;
+}
+
template
const Char* GetTypename()
{
diff --git a/Source/Engine/Visject/ShaderGraphUtilities.h b/Source/Engine/Visject/ShaderGraphUtilities.h
index 903059f05..3f1ae5d6b 100644
--- a/Source/Engine/Visject/ShaderGraphUtilities.h
+++ b/Source/Engine/Visject/ShaderGraphUtilities.h
@@ -12,6 +12,7 @@ namespace ShaderGraphUtilities
{
void GenerateShaderConstantBuffer(TextWriterUnicode& writer, Array& parameters);
const Char* GenerateShaderResources(TextWriterUnicode& writer, Array& parameters, int32 startRegister);
+ const Char* GenerateSamplers(TextWriterUnicode& writer, Array& parameters, int32 startRegister);
template
void SampleCurve(TextWriterUnicode& writer, const BezierCurve& curve, const String& time, const String& value);
}