Hello. I created gradient material using Shader Graph. If the Image Type is simple, there is no problem. But if the image type is sliced, the transitions are sharp. How can I get over this?
Hi,
sorry your question was left unanswered for so long.
Obviously, to achieve 9 slicing, the UVs of the generated mesh are set to stretch the texture in the middle (to preserve corners).
I guess the current solution would be to go with a UI Mask using 9-slicing to mask a gradient Image that is not sliced.
That said, your suggestion makes sense since Shader Graph now supports Canvas Material.
So here’s another solution.
uGUI allows modifying the mesh vertices. As an example, PositionAsUV1 stores the raw vertex position in the second UV channel (UV1).
But raw position won’t help you much for a gradient spanning across an Image.
Here’s a script that will store the normalized position in the ZW component of UV0.
using UnityEngine;
using UnityEngine.UI;
namespace ShaderGraph.Helpers
{
[AddComponentMenu("UI/Effects/Normalized Position As UV0.ZW", 82)]
public class NormalizedPositionAsUV0ZW : BaseMeshEffect
{
protected NormalizedPositionAsUV0ZW()
{ }
public override void ModifyMesh(VertexHelper vh)
{
Bounds bounds = new Bounds();
UIVertex vert = new UIVertex();
for (int i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vert, i);
bounds.Encapsulate(vert.position);
}
Debug.Log(bounds);
for (int i = 0; i < vh.currentVertCount; i++)
{
vh.PopulateUIVertex(ref vert, i);
var normalizedPosition = new Vector2(
Mathf.InverseLerp(bounds.min.x, bounds.max.x, vert.position.x),
Mathf.InverseLerp(bounds.min.y, bounds.max.y, vert.position.y));
vert.uv0 = new Vector4(vert.uv0.x, vert.uv0.y, normalizedPosition.x, normalizedPosition.y);
vh.SetUIVertex(vert, i);
}
}
}
}
Add this component to your UI Image, then in the Shader Graph, you can use the ZW components to sample images or gradients with no distorsion.
Hope this helps.
Don’t hesitate to provide feedback and suggest features on our roadmap page.