修复shader问题
This commit is contained in:
@@ -7,36 +7,86 @@ using System.Threading.Tasks;
|
||||
namespace SpineViewer.Spine
|
||||
{
|
||||
/// <summary>
|
||||
/// SFML 混合模式
|
||||
/// SFML 混合模式, 预乘模式下输入和输出的像素值都是预乘的
|
||||
/// </summary>
|
||||
public static class BlendModeSFML
|
||||
{
|
||||
/// <summary>
|
||||
/// Alpha Blend
|
||||
/// <code>
|
||||
/// res.c = src.c * src.a + dst.c * (1 - src.a)
|
||||
/// res.a = src.a * 1 + dst.a * (1 - src.a)
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static SFML.Graphics.BlendMode Normal = SFML.Graphics.BlendMode.Alpha;
|
||||
///// <summary>
|
||||
///// Normal Blend, 无预乘, 仅在 dst.a 是 1 时得到正确结果, 其余情况是有偏结果
|
||||
///// <para>当 <c>src.c < dst.c</c> 时, 结果偏大, 例如 src 是半透明纯黑, dst 是全透明纯白</para>
|
||||
///// <para>当 <c>src.c > dst.c</c> 时, 结果偏小, 例如 src 是半透明纯白, dst 是全透明纯黑</para>
|
||||
///// <code>
|
||||
///// res.c = src.c * src.a + dst.c * (1 - src.a)
|
||||
///// res.a = src.a * 1 + dst.a * (1 - src.a)
|
||||
///// </code>
|
||||
///// </summary>
|
||||
//public static SFML.Graphics.BlendMode Normal = new(
|
||||
// SFML.Graphics.BlendMode.Factor.SrcAlpha,
|
||||
// SFML.Graphics.BlendMode.Factor.OneMinusSrcAlpha,
|
||||
// SFML.Graphics.BlendMode.Equation.Add,
|
||||
// SFML.Graphics.BlendMode.Factor.One,
|
||||
// SFML.Graphics.BlendMode.Factor.OneMinusSrcAlpha,
|
||||
// SFML.Graphics.BlendMode.Equation.Add
|
||||
//);
|
||||
|
||||
///// <summary>
|
||||
///// Additive Blend, 无预乘, 仅在 dst.a 是 1 时得到正确结果, 其余情况是有偏结果
|
||||
///// <para>当 <c>src.a + dst.a >= 1</c> 时, 结果偏大, 例如 src 是不透明纯黑, dst 是全透明纯白</para>
|
||||
///// <para>当 <c>src.a + dst.a < 1</c> 时, 结果偏差方式类似 <see cref="Normal"/>, 均可假设 dst 是全透明纯白进行判断</para>
|
||||
///// <code>
|
||||
///// res.c = src.c * src.a + dst.c * 1
|
||||
///// res.a = src.a * 1 + dst.a * 1
|
||||
///// </code>
|
||||
///// </summary>
|
||||
//public static SFML.Graphics.BlendMode Additive = new(
|
||||
// SFML.Graphics.BlendMode.Factor.SrcAlpha,
|
||||
// SFML.Graphics.BlendMode.Factor.One,
|
||||
// SFML.Graphics.BlendMode.Equation.Add,
|
||||
// SFML.Graphics.BlendMode.Factor.One,
|
||||
// SFML.Graphics.BlendMode.Factor.One,
|
||||
// SFML.Graphics.BlendMode.Equation.Add
|
||||
//);
|
||||
|
||||
/// <summary>
|
||||
/// Additive Blend
|
||||
/// Normal Blend with PremultipliedAlpha
|
||||
/// <code>
|
||||
/// res.c = src.c * src.a + dst.c * 1
|
||||
/// res.a = src.a * 1 + dst.a * 1
|
||||
/// [res.c * res.a] = [src.c * src.a] * 1 + [dst.c * dst.a] * (1 - src.a)
|
||||
/// res.a = src.a * 1 + dst.a * (1 - src.a)
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static SFML.Graphics.BlendMode Additive = SFML.Graphics.BlendMode.Add;
|
||||
public static SFML.Graphics.BlendMode NormalPma = new(
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Factor.OneMinusSrcAlpha,
|
||||
SFML.Graphics.BlendMode.Equation.Add,
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Factor.OneMinusSrcAlpha,
|
||||
SFML.Graphics.BlendMode.Equation.Add
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Multiply Blend (PremultipliedAlpha Only)
|
||||
/// Additive Blend with PremultipliedAlpha
|
||||
/// <code>
|
||||
/// [res.c * res.a] = [src.c * src.a] * 1 + [dst.c * dst.a] * 1
|
||||
/// res.a = src.a * 1 + dst.a * 1
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static SFML.Graphics.BlendMode AdditivePma = new(
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Equation.Add,
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Equation.Add
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Multiply Blend with PremultipliedAlpha
|
||||
/// <code>
|
||||
/// res.c = src.c * dst.c + dst.c * (1 - src.a)
|
||||
/// res.a = src.a * 1 + dst.a * (1 - src.a)
|
||||
/// res.a = src.a * 1 + dst.a * (1 - src.a)
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static SFML.Graphics.BlendMode Multiply = new(
|
||||
public static SFML.Graphics.BlendMode MultiplyPma = new(
|
||||
SFML.Graphics.BlendMode.Factor.DstColor,
|
||||
SFML.Graphics.BlendMode.Factor.OneMinusSrcAlpha,
|
||||
SFML.Graphics.BlendMode.Equation.Add,
|
||||
@@ -46,13 +96,13 @@ namespace SpineViewer.Spine
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// Screen Blend (PremultipliedAlpha Only)
|
||||
/// Screen Blend with PremultipliedAlpha Only
|
||||
/// <code>
|
||||
/// res.c = src.c * 1 + dst.c * (1 - src.c) = 1 - [(1 - src.c)(1 - dst.c)]
|
||||
/// res.a = src.a * 1 + dst.a * (1 - src.a)
|
||||
/// </code>
|
||||
/// </summary>
|
||||
public static SFML.Graphics.BlendMode Screen = new(
|
||||
public static SFML.Graphics.BlendMode ScreenPma = new(
|
||||
SFML.Graphics.BlendMode.Factor.One,
|
||||
SFML.Graphics.BlendMode.Factor.OneMinusSrcColor,
|
||||
SFML.Graphics.BlendMode.Equation.Add,
|
||||
|
||||
@@ -261,6 +261,7 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
states.Shader = Shader.GetShader(usePremultipliedAlpha);
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
@@ -322,18 +323,13 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
}
|
||||
|
||||
// 似乎 2.1.x 也没有 BlendMode
|
||||
SFML.Graphics.BlendMode blendMode = slot.Data.AdditiveBlending ? BlendModeSFML.Additive : BlendModeSFML.Normal;
|
||||
SFML.Graphics.BlendMode blendMode = slot.Data.AdditiveBlending ? BlendModeSFML.AdditivePma : BlendModeSFML.NormalPma;
|
||||
|
||||
states.Texture ??= texture;
|
||||
if (states.BlendMode != blendMode || states.Texture != texture)
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
@@ -377,11 +373,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
|
||||
//clipping.ClipEnd(slot);
|
||||
}
|
||||
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
//clipping.ClipEnd();
|
||||
|
||||
// 调试纹理
|
||||
|
||||
@@ -208,10 +208,10 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
BlendMode.Normal => BlendModeSFML.NormalPma,
|
||||
BlendMode.Additive => BlendModeSFML.AdditivePma,
|
||||
BlendMode.Multiply => BlendModeSFML.MultiplyPma,
|
||||
BlendMode.Screen => BlendModeSFML.ScreenPma,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
@@ -220,6 +220,7 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
states.Shader = Shader.GetShader(usePremultipliedAlpha);
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
@@ -286,11 +287,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
@@ -336,11 +332,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
}
|
||||
clipping.ClipEnd();
|
||||
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
|
||||
@@ -178,10 +178,10 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
BlendMode.Normal => BlendModeSFML.NormalPma,
|
||||
BlendMode.Additive => BlendModeSFML.AdditivePma,
|
||||
BlendMode.Multiply => BlendModeSFML.MultiplyPma,
|
||||
BlendMode.Screen => BlendModeSFML.ScreenPma,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
@@ -190,6 +190,7 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
states.Shader = Shader.GetShader(usePremultipliedAlpha);
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
@@ -256,12 +257,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
@@ -307,11 +302,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
}
|
||||
clipping.ClipEnd();
|
||||
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
|
||||
@@ -184,10 +184,10 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
BlendMode.Normal => BlendModeSFML.NormalPma,
|
||||
BlendMode.Additive => BlendModeSFML.AdditivePma,
|
||||
BlendMode.Multiply => BlendModeSFML.MultiplyPma,
|
||||
BlendMode.Screen => BlendModeSFML.ScreenPma,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
@@ -196,6 +196,7 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
states.Shader = Shader.GetShader(usePremultipliedAlpha);
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
@@ -262,14 +263,8 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
|
||||
vertexArray.Clear();
|
||||
@@ -313,11 +308,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
}
|
||||
clipping.ClipEnd();
|
||||
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
|
||||
@@ -180,10 +180,10 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
BlendMode.Normal => BlendModeSFML.NormalPma,
|
||||
BlendMode.Additive => BlendModeSFML.AdditivePma,
|
||||
BlendMode.Multiply => BlendModeSFML.MultiplyPma,
|
||||
BlendMode.Screen => BlendModeSFML.ScreenPma,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
@@ -192,6 +192,7 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
states.Shader = Shader.GetShader(usePremultipliedAlpha);
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
@@ -258,12 +259,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
@@ -309,11 +304,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
}
|
||||
clipping.ClipEnd();
|
||||
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
|
||||
@@ -180,10 +180,10 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
BlendMode.Normal => BlendModeSFML.NormalPma,
|
||||
BlendMode.Additive => BlendModeSFML.AdditivePma,
|
||||
BlendMode.Multiply => BlendModeSFML.MultiplyPma,
|
||||
BlendMode.Screen => BlendModeSFML.ScreenPma,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
@@ -192,6 +192,7 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
states.Shader = Shader.GetShader(usePremultipliedAlpha);
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
@@ -258,12 +259,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
@@ -309,11 +304,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
}
|
||||
clipping.ClipEnd();
|
||||
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
|
||||
@@ -180,10 +180,10 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
return spineBlendMode switch
|
||||
{
|
||||
BlendMode.Normal => BlendModeSFML.Normal,
|
||||
BlendMode.Additive => BlendModeSFML.Additive,
|
||||
BlendMode.Multiply => BlendModeSFML.Multiply,
|
||||
BlendMode.Screen => BlendModeSFML.Screen,
|
||||
BlendMode.Normal => BlendModeSFML.NormalPma,
|
||||
BlendMode.Additive => BlendModeSFML.AdditivePma,
|
||||
BlendMode.Multiply => BlendModeSFML.MultiplyPma,
|
||||
BlendMode.Screen => BlendModeSFML.ScreenPma,
|
||||
_ => throw new NotImplementedException($"{spineBlendMode}"),
|
||||
};
|
||||
}
|
||||
@@ -192,6 +192,7 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
vertexArray.Clear();
|
||||
states.Texture = null;
|
||||
states.Shader = Shader.GetShader(usePremultipliedAlpha);
|
||||
|
||||
// 要用 DrawOrder 而不是 Slots
|
||||
foreach (var slot in skeleton.DrawOrder)
|
||||
@@ -258,12 +259,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
{
|
||||
if (vertexArray.VertexCount > 0)
|
||||
{
|
||||
// XXX: 实测不用设置 sampler2D 的值也正确
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
@@ -309,11 +304,6 @@ namespace SpineViewer.Spine.Implementations.Spine
|
||||
}
|
||||
clipping.ClipEnd();
|
||||
|
||||
if (usePremultipliedAlpha && (states.BlendMode == BlendModeSFML.Normal || states.BlendMode == BlendModeSFML.Additive))
|
||||
states.Shader = Shader.FragmentShader;
|
||||
else
|
||||
states.Shader = null;
|
||||
|
||||
// 调试纹理
|
||||
if (!isDebug || debugTexture)
|
||||
target.Draw(vertexArray, states);
|
||||
|
||||
@@ -9,19 +9,44 @@ namespace SpineViewer.Spine
|
||||
public static class Shader
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于解决 PMA 和渐变动画问题的片段着色器
|
||||
/// 用于非预乘纹理的 fragment shader, 乘上了插值后的透明度用于实现透明度变化(插值预乘), 并且输出预乘后的像素值
|
||||
/// </summary>
|
||||
private const string FRAGMENT_SHADER = (
|
||||
private const string FRAGMENT_VertexAlpha = (
|
||||
"uniform sampler2D t;" +
|
||||
"void main() { vec4 p = texture2D(t, gl_TexCoord[0].xy);" +
|
||||
"if (p.a > 0) p.rgb /= max(max(max(p.r, p.g), p.b), p.a);" +
|
||||
"void main() { vec4 p = texture(t, gl_TexCoord[0].xy);" +
|
||||
"p.rgb *= p.a * gl_Color.a;" +
|
||||
"gl_FragColor = gl_Color * p; }"
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// 针对预乘 Alpha 通道的片段着色器
|
||||
/// 用于预乘纹理的 fragment shader, 乘上了插值后的透明度用于实现透明度变化(插值预乘)
|
||||
/// </summary>
|
||||
public static SFML.Graphics.Shader? FragmentShader { get; private set; }
|
||||
private const string FRAGMENT_VertexAlphaPma = (
|
||||
"uniform sampler2D t;" +
|
||||
"void main() { vec4 p = texture(t, gl_TexCoord[0].xy);" +
|
||||
"p.rgb *= gl_Color.a;" +
|
||||
"gl_FragColor = gl_Color * p; }"
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// 预乘转非预乘 fragment shader
|
||||
/// </summary>
|
||||
private const string FRAGMENT_PmaInv = (
|
||||
"uniform sampler2D t;" +
|
||||
"void main() { vec4 p = texture(t, gl_TexCoord[0].xy);" +
|
||||
"p.rgb *= gl_Color.a;" +
|
||||
"gl_FragColor = gl_Color * p; }"
|
||||
);
|
||||
|
||||
/// <summary>
|
||||
/// 考虑了顶点透明度变化的着色器, 输入是非预乘纹理像素, 输出是预乘像素
|
||||
/// </summary>
|
||||
private static SFML.Graphics.Shader? VertexAlpha = null;
|
||||
|
||||
/// <summary>
|
||||
/// 考虑了顶点透明度变化的着色器, 输入和输出均是预乘像素值
|
||||
/// </summary>
|
||||
private static SFML.Graphics.Shader? VertexAlphaPma = null;
|
||||
|
||||
/// <summary>
|
||||
/// 加载 Shader, 可能会存在异常导致着色器加载失败
|
||||
@@ -29,7 +54,21 @@ namespace SpineViewer.Spine
|
||||
/// <exception cref="SFML.LoadingFailedException"></exception>
|
||||
public static void Init()
|
||||
{
|
||||
FragmentShader = SFML.Graphics.Shader.FromString(null, null, FRAGMENT_SHADER);
|
||||
VertexAlpha = SFML.Graphics.Shader.FromString(null, null, FRAGMENT_VertexAlpha);
|
||||
VertexAlphaPma = SFML.Graphics.Shader.FromString(null, null, FRAGMENT_VertexAlphaPma);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取合适的着色器
|
||||
/// </summary>
|
||||
/// <param name="pma">纹理是否是预乘的</param>
|
||||
/// <param name="twoColor">是否是双色着色的(TODO)</param>
|
||||
public static SFML.Graphics.Shader? GetShader(bool pma, bool twoColor = false)
|
||||
{
|
||||
if (pma)
|
||||
return VertexAlphaPma;
|
||||
else
|
||||
return VertexAlpha;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user