Add support for using per-texture group sampler in Materials
This commit is contained in:
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Common samplers types.
|
||||
/// </summary>
|
||||
public enum CommonSamplerType
|
||||
internal enum CommonSamplerType
|
||||
{
|
||||
/// <summary>
|
||||
/// The linear clamp
|
||||
/// </summary>
|
||||
LinearClamp = 0,
|
||||
|
||||
/// <summary>
|
||||
/// The point clamp
|
||||
/// </summary>
|
||||
PointClamp = 1,
|
||||
|
||||
/// <summary>
|
||||
/// The linear wrap
|
||||
/// </summary>
|
||||
LinearWrap = 2,
|
||||
|
||||
/// <summary>
|
||||
/// The point wrap
|
||||
/// </summary>
|
||||
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<StreamingSettings>();
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -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))
|
||||
}
|
||||
},
|
||||
|
||||
@@ -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
|
||||
{
|
||||
/// <summary>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
/// Releases GPU resource memory and deletes object.
|
||||
/// </summary>
|
||||
#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; }
|
||||
|
||||
/// <summary>
|
||||
/// The base class for all GPU resources.
|
||||
|
||||
@@ -101,5 +101,10 @@ namespace FlaxEngine
|
||||
/// The gameplay global.
|
||||
/// </summary>
|
||||
GameplayGlobal = 18,
|
||||
|
||||
/// <summary>
|
||||
/// The texture sampler derived from texture group settings.
|
||||
/// </summary>
|
||||
TextureGroupSampler = 19,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 Array<SerializedMaterialPar
|
||||
case MaterialParameterType::SceneTexture:
|
||||
case MaterialParameterType::ChannelMask:
|
||||
case MaterialParameterType::Integer:
|
||||
case MaterialParameterType::TextureGroupSampler:
|
||||
stream->WriteInt32(param.AsInteger);
|
||||
break;
|
||||
case MaterialParameterType::Float:
|
||||
|
||||
@@ -123,6 +123,11 @@ enum class MaterialParameterType : byte
|
||||
/// The gameplay global.
|
||||
/// </summary>
|
||||
GameplayGlobal = 18,
|
||||
|
||||
/// <summary>
|
||||
/// The texture sampler derived from texture group settings.
|
||||
/// </summary>
|
||||
TextureGroupSampler = 19,
|
||||
};
|
||||
|
||||
const Char* ToString(MaterialParameterType value);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<StreamableResource*> Resources;
|
||||
Array<GPUSampler*, InlinedAllocation<32>> 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<TextureGroup, InlinedAllocation<32>> 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;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
#include "TextureGroup.h"
|
||||
|
||||
class GPUSampler;
|
||||
|
||||
/// <summary>
|
||||
/// The content streaming service.
|
||||
/// </summary>
|
||||
@@ -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.
|
||||
/// </summary>
|
||||
API_FUNCTION() static void RequestStreamingUpdate();
|
||||
|
||||
/// <summary>
|
||||
/// 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).
|
||||
/// </summary>
|
||||
/// <param name="index">The texture group index.</param>
|
||||
/// <returns>The texture sampler (always valid).</returns>
|
||||
API_FUNCTION() static GPUSampler* GetTextureGroupSampler(int32 index);
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// The default filtering method for samplers using this texture group.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(15)")
|
||||
GPUSamplerFilter SamplerFilter = GPUSamplerFilter::Trilinear;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(16), Limit(1, 16), VisibleIf(\"IsAnisotropic\")")
|
||||
int32 MaxAnisotropy = 16;
|
||||
|
||||
/// <summary>
|
||||
/// 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.
|
||||
/// </summary>
|
||||
|
||||
@@ -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<Node>(), 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}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -136,11 +136,9 @@ void ShaderGraphUtilities::GenerateShaderConstantBuffer(TextWriterUnicode& write
|
||||
|
||||
const Char* ShaderGraphUtilities::GenerateShaderResources(TextWriterUnicode& writer, Array<SerializedMaterialParam>& 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<int32>(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<SerializedMaterialParam>& 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<typename T>
|
||||
const Char* GetTypename()
|
||||
{
|
||||
|
||||
@@ -12,6 +12,7 @@ namespace ShaderGraphUtilities
|
||||
{
|
||||
void GenerateShaderConstantBuffer(TextWriterUnicode& writer, Array<SerializedMaterialParam>& parameters);
|
||||
const Char* GenerateShaderResources(TextWriterUnicode& writer, Array<SerializedMaterialParam>& parameters, int32 startRegister);
|
||||
const Char* GenerateSamplers(TextWriterUnicode& writer, Array<SerializedMaterialParam>& parameters, int32 startRegister);
|
||||
template<typename T>
|
||||
void SampleCurve(TextWriterUnicode& writer, const BezierCurve<T>& curve, const String& time, const String& value);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user