diff --git a/Content/Editor/MaterialTemplates/GUI.shader b/Content/Editor/MaterialTemplates/GUI.shader index 7eced6390..170d95f1a 100644 --- a/Content/Editor/MaterialTemplates/GUI.shader +++ b/Content/Editor/MaterialTemplates/GUI.shader @@ -19,6 +19,7 @@ float3 ViewDir; float TimeParam; float4 ViewInfo; float4 ScreenSize; +float4 ViewSize; @1META_CB_END // Shader resources diff --git a/Source/Editor/Surface/Archetypes/Material.cs b/Source/Editor/Surface/Archetypes/Material.cs index a010f56f9..97c6fe9d0 100644 --- a/Source/Editor/Surface/Archetypes/Material.cs +++ b/Source/Editor/Surface/Archetypes/Material.cs @@ -863,6 +863,19 @@ namespace FlaxEditor.Surface.Archetypes NodeElementArchetype.Factory.TextBox(0, 40, 300, 200, 0), } }, + new NodeArchetype + { + TypeID = 39, + Title = "View Size", + Description = "The size of the view.", + Flags = NodeFlags.MaterialGraph, + Size = new Float2(150, 40), + Elements = new[] + { + NodeElementArchetype.Factory.Output(0, "Size", typeof(Float2), 0), + NodeElementArchetype.Factory.Output(1, "Inv Size", typeof(Float2), 1), + } + }, }; } } diff --git a/Source/Engine/Graphics/Materials/GUIMaterialShader.cpp b/Source/Engine/Graphics/Materials/GUIMaterialShader.cpp index 4e2609928..634614458 100644 --- a/Source/Engine/Graphics/Materials/GUIMaterialShader.cpp +++ b/Source/Engine/Graphics/Materials/GUIMaterialShader.cpp @@ -20,6 +20,7 @@ PACK_STRUCT(struct GUIMaterialShaderData { float TimeParam; Float4 ViewInfo; Float4 ScreenSize; + Float4 ViewSize; }); void GUIMaterialShader::Bind(BindParameters& params) @@ -32,6 +33,7 @@ void GUIMaterialShader::Bind(BindParameters& params) cb = Span(cb.Get() + sizeof(GUIMaterialShaderData), cb.Length() - sizeof(GUIMaterialShaderData)); int32 srv = 0; const auto ps = context->IsDepthBufferBinded() ? _cache.Depth : _cache.NoDepth; + auto customData = (Render2D::CustomData*)params.CustomData; // Setup parameters MaterialParameter::BindMeta bindMeta; @@ -45,8 +47,8 @@ void GUIMaterialShader::Bind(BindParameters& params) // Setup material constants { - const auto viewProjectionMatrix = (Matrix*)params.CustomData; - Matrix::Transpose(*viewProjectionMatrix, materialData->ViewProjectionMatrix); + const auto viewProjectionMatrix = customData->ViewProjection; + Matrix::Transpose(viewProjectionMatrix, materialData->ViewProjectionMatrix); Matrix::Transpose(Matrix::Identity, materialData->WorldMatrix); Matrix::Transpose(Matrix::Identity, materialData->ViewMatrix); materialData->ViewPos = Float3::Zero; @@ -56,6 +58,7 @@ void GUIMaterialShader::Bind(BindParameters& params) materialData->ViewInfo = Float4::Zero; auto& viewport = Render2D::GetViewport(); materialData->ScreenSize = Float4(viewport.Width, viewport.Height, 1.0f / viewport.Width, 1.0f / viewport.Height); + materialData->ViewSize = Float4(customData->ViewSize.X, customData->ViewSize.Y, 1.0f / customData->ViewSize.X, 1.0f / customData->ViewSize.Y); } // Bind constants diff --git a/Source/Engine/Render2D/Render2D.cpp b/Source/Engine/Render2D/Render2D.cpp index 404689ca4..489f1df24 100644 --- a/Source/Engine/Render2D/Render2D.cpp +++ b/Source/Engine/Render2D/Render2D.cpp @@ -114,6 +114,8 @@ struct Render2DDrawCall struct { MaterialBase* Mat; + float Width; + float Height; } AsMaterial; struct @@ -984,7 +986,10 @@ void DrawBatch(int32 startIndex, int32 count) // Apply and bind material auto material = d.AsChar.Mat; MaterialBase::BindParameters bindParams(Context, *(RenderContext*)nullptr); - bindParams.CustomData = &ViewProjection; + Render2D::CustomData customData; + customData.ViewProjection = ViewProjection; + customData.ViewSize = Float2(d.AsMaterial.Width, d.AsMaterial.Height); + bindParams.CustomData = &customData; material->Bind(bindParams); // Bind font atlas as a material parameter @@ -1017,7 +1022,10 @@ void DrawBatch(int32 startIndex, int32 count) // Bind material auto material = (MaterialBase*)d.AsMaterial.Mat; MaterialBase::BindParameters bindParams(Context, *(RenderContext*)nullptr); - bindParams.CustomData = &ViewProjection; + Render2D::CustomData customData; + customData.ViewProjection = ViewProjection; + customData.ViewSize = Float2(d.AsMaterial.Width, d.AsMaterial.Height); + bindParams.CustomData = &customData; material->Bind(bindParams); // Bind index and vertex buffers @@ -1892,6 +1900,8 @@ void Render2D::DrawMaterial(MaterialBase* material, const Rectangle& rect, const drawCall.StartIB = IBIndex; drawCall.CountIB = 6; drawCall.AsMaterial.Mat = material; + drawCall.AsMaterial.Width = rect.GetWidth(); + drawCall.AsMaterial.Height = rect.GetHeight(); WriteRect(rect, color); } diff --git a/Source/Engine/Render2D/Render2D.h b/Source/Engine/Render2D/Render2D.h index 6ee08e688..811d67381 100644 --- a/Source/Engine/Render2D/Render2D.h +++ b/Source/Engine/Render2D/Render2D.h @@ -5,6 +5,8 @@ #include "Engine/Core/Math/Color.h" #include "Engine/Scripting/ScriptingType.h" #include "Engine/Core/Types/Span.h" +#include "Engine/Core/Math/Vector2.h" +#include "Engine/Core/Math/Matrix.h" struct SpriteHandle; struct TextLayoutOptions; @@ -44,6 +46,13 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Render2D); VertexSnapping = 1, }; +public: + struct CustomData + { + Matrix ViewProjection; + Float2 ViewSize; + }; + public: /// diff --git a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp index 09c2da80d..275734a90 100644 --- a/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp +++ b/Source/Engine/Tools/MaterialGenerator/MaterialGenerator.Material.cpp @@ -480,6 +480,16 @@ void MaterialGenerator::ProcessGroupMaterial(Box* box, Node* node, Value& value) value = writeLocal(ValueType::Float3, String::Format(TEXT("float3({0}.x * 360.0f, {0}.y / ({0}.z + {1}), {0}.z)"), hcv.Value, epsilon.Value), node); break; } + // View Size + case 39: + { + const auto layer = GetRootLayer(); + if (layer && layer->Domain == MaterialDomain::GUI) + { + value = Value(VariantType::Float2, box->ID == 0 ? TEXT("ViewSize.xy") : TEXT("ViewSize.zw")); + } + break; + } default: break; }