Here’s a shader I have, and it works fine. but somehow I’m getting a different result when
mask2 = 1-mask1;
vs
mask2 = (i.uv1.y > _DissolveGradientSize) ? 1 : 0;
when _DissolveAmt is at 0?
Shader "SelfMade/Unlit/Line"
{
Properties
{
_MainTex ("Mask", 2D) = "white" {} // use as over all edge mask
_DissolveGradientSize ("Start Gradient Size", Float) = .05
//https://docs.unity3d.com/2023.2/Documentation/ScriptReference/MaterialPropertyDrawer.html
_DissolveAmt ("Reveal Amount", Range(0, 1)) = 0
_Texture ("Texture", 2D) = "white" {} // use as tiled texture mask
}
SubShader
{
Tags {"Queue"="Transparent" "RenderType"="Transparent" }
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
float remapper(float i, float nMin, float nMax, float oMin, float oMax)
{
return nMin + ( (i-oMin) * (nMax-nMin) / (oMax-oMin) );
}
struct appdata
{
float4 vertex : POSITION;
float4 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float4 lColor : COLOR;
};
struct v2f
{
float4 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float4 vertex : SV_POSITION;
float4 lColor : COLOR;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _Texture;
float4 _Texture_ST;
float _DissolveGradientSize;
float _DissolveAmt;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv.xy = TRANSFORM_TEX(v.uv, _MainTex);
o.uv.zw = TRANSFORM_TEX(v.uv, _Texture);
//float sinT = ((_SinTime.w + 1) / 2);
o.uv1.x = remapper(v.uv1.x, 0, 1, 0, _DissolveAmt ); //remap the uv to scale it
o.uv1.y = v.uv.x; // a staic uv gradient
o.lColor = v.lColor;
return o;
}
float4 frag (v2f i) : SV_Target
{
//float sinT = ((_SinTime.w + 1) / 2);
float mask1 = step(i.uv1.y, _DissolveGradientSize);
float mask2 = 1-mask1; //(i.uv1.y > _DissolveGradientSize) ? 1 : 0; // single line if statement (condition) ? true returns this : false returns this;
/*
for some unknown reason
1-mask1
vs (i.uv1.y > _DissolveGradientSize) ? 1 : 0 OR step(_DissolveGradientSize, i.uv1.y); <- these produce same results
produce different final image even tho the masks looks
*/
i.uv.x = (i.uv1.y * mask1) + (i.uv1.x * mask2); //overiding i.uv.x, making it so that the start doesn't stretch, but shows up immediately from 0 up to _DissolveGradientSize, and the stretches from that point onwards towards 1
float a = (tex2D(_MainTex, i.uv.xy)).g;
float col_a = (tex2D(_Texture, i.uv.zw)).g;
return float4 (i.lColor.rgb, a*col_a);
//return float4 (i.uv.z , i.uv.z , i.uv.z , 1);
//return float4 (mask1, mask2, 0, 1);
}
ENDCG
}
}
}
like the masks looks the same when I output it from the frag shader, so why is the result different?
I’m pretty new to make shader with just code (it’s a lotta fun) but I have no idea what’s happening here and I’d like to know lol
so the issue seems to come from dividing by 0, causing NaN to leak thru to the end result, but I have no idea why the different masking calculation causes the result to be different?
I’m seeing the same results no matter if I do > or >= in the ternary or not.
The result from 1-Mask1 is what I expected, but I have no idea why it’s the only one that seems to not let NaN breaks it?
NaN leaks when I use step() or ternary for both masks.
if I do mask1 using ternary and mask2 w/ 1-mask1, NaN also leaks
and if I do mask1 using step() and mask2 w/ 1-mask1, there’s no leak?
and under mask1 using step() and mask2 w/ 1-mask1, if I calculate i.uv.x with lerp, NaN leaks, but if I use the *m1+*m2 it doesn’t leak???
It can be that your calculations giving the same visual result, but the values can be different. You can try to use a clamp() or saturation(), directly after your calculation.
When you say these are not the same precision, are you referring to? 1-mask1 and i.uv1.y > _DissolveGradientSize) ? 1 : 0 OR step(_DissolveGradientSize, i.uv1.y)?
I’m just confused as to why the way mask2 are calculated effects the outcome if the problem is with i.uv1.x dividing by zero? the masks’ calculation only deals with i.uv.y. Like in either case of mask2, would mask2 * i.uv1.x not return the same +/-INF or NaN? Or is it returning differently (0 or 1 here I’m guessing) because of the different in precision?
btw, how can you tell when things have different precision? aren’t I using floats for both of 'em?