Hi everyone, I’m writing a really simple shader that is supposed to blend colors between each gradient segment on a cylinder including the start and the end segment, in other words the gradient should be seamless. However, despite that, there seams to be a visible seem on the cylinder when certain int values are typed into _Count property field, such as 30, in other words the blending at start and end UV points breaks for some reason. The strange thing is that if you substitute the property field with a local variable or an r-value the problem disappears and the shader displays the results as expected. I need to point out that cylinder’s base UV’s overlay over the whole UV map.
Is this Unity’s internal issue or am I doing something wrong?
Application: Unity 2021.3.9f1 OS : Windows 10 GPU: AMD Radeon R9-270x CPU: AMD FX8300
Cylinder FBX:
Shader "CgProgramming/Custom/Wraper"
{
Properties
{
_MainTex("Main Tex", 2D) = "white"
_Count("Count", Integer) = 1
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Cull Off
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
sampler2D _MainTex;
float4 _MainTex_ST;
uniform half _Count;
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
int n = _Count; // doesn't work properly with some values (e.g. 30)
// int n = 30; // works fine with any value
float x_i = floor(i.uv.x*n);
float x_f = frac(i.uv.x*n);
float cell1 = x_i/n;
float cell2 = fmod((x_i+1.0), n)/n;
float val = lerp(cell1, cell2, x_f*x_f*(3.0-2.0*x_f));
return fixed4(val.xxx, 1.0);
}
ENDCG
}
}
}
I would report this as a bug using the in-editor reporting tool. If there is an issue with specific hardware / drivers as I suspect is the case, this is something they’ll need to handle.
Until then I might suggest changing: _Count("Count", Integer) = 1
to _Count("Count", Float) = 1
and use float _Count; for the uniform and int n = _Count + 0.5; in the function.