C# Don';t染色,但是;“着色”;(传说中的)精灵

C# Don';t染色,但是;“着色”;(传说中的)精灵,c#,colors,xna,shader,tint,C#,Colors,Xna,Shader,Tint,在我的基于2D瓷砖的游戏中,玩家可以绘制瓷砖来改变颜色。简单的方法(我已经做过)是使用SpriteBatch.Draw中的tint参数 这看起来不错,下面是一个示例: 但是说,我想把木头漆成白色。如果您曾经弄乱过色调,那么您知道使用“色调”参数是不可能做到这一点的颜色。白色将精灵着色为默认颜色,而不是白色。这不是一个大问题,但我想有些用户可能会想要它 我的问题是,有没有一种方法可以根据色调/饱和度而不是色调给精灵上色。类似于GIMP中的“colorify”函数 一个明显的方法是在GIMP中使

在我的基于2D瓷砖的游戏中,玩家可以绘制瓷砖来改变颜色。简单的方法(我已经做过)是使用
SpriteBatch.Draw
中的
tint
参数

这看起来不错,下面是一个示例:

但是说,我想把木头漆成白色。如果您曾经弄乱过色调,那么您知道使用“色调”参数是不可能做到这一点的<代码>颜色。白色将精灵着色为默认颜色,而不是白色。这不是一个大问题,但我想有些用户可能会想要它

我的问题是,有没有一种方法可以根据色调/饱和度而不是色调给精灵上色。类似于GIMP中的“colorify”函数

一个明显的方法是在GIMP中使用这个函数,只为每种颜色导出精灵。麻烦的是,我所有的精灵都要花很长时间才能完成,而且每个精灵都有多个变体,这意味着一个区块类型总共可以有100多个组合

这可能吗?我想一个着色器可以完成这项工作。

GIMP中的“colorify”函数只是进行去饱和(转换为灰度),然后进行颜色倍增。很简单。这应该是等效的HLSL(未测试):

但是,您可以通过简单地存储所有已去饱和的纹理,并使用默认的
SpriteBatch
着色器进行倍增,来实现相同的效果。如果您不想修改源代码,可以在自定义内容处理器中进行修改



不过,如果要使用自定义着色器,可以执行更复杂的操作。您可以实现一个完整的色调旋转(有点复杂)。但是也许你可以考虑一些(非常简单)的东西,它可以让你美化灰色,同时保存高亮和低光(而不是乘法,这也使高亮显示颜色)。

< P>继续在SPriteBatch.Draw中使用色调。只需将“可绘制”纹理设置为灰度。因此,白色木材将是您的默认颜色,但您使用使其成为木材颜色的色调绘制它

我经常用它来制作UI和团队颜色:)

如果有意思的话,着色所做的只是将纹理中的每个像素乘以您选择的颜色

示例:
纹理像素是(rgba)[1.0,0.5,0.5,1.0]
色调为[1.0,0.5,0.5,0.5]

结果是[1.0,0.25,0.25,0.5](半透明,略带红色)

为什么不让基础精灵尽可能明亮(接近白色)?使用像素着色器可以实现任意效果,但我怀疑这在这种情况下是否必要。在我看来,Gimp使用与色调参数相同的技术。查看HSV颜色模型:。可以将纹理从RGB转换为HSV,对色调应用偏移以更改颜色,然后将其转换回RGB。虽然从一开始就让你的纹理变成亮白色,并使用内置的XNA着色肯定会更容易。但问题是,假设我有一个块,不能只应用棕色着色作为默认值,而是一个具有多种颜色的块。我可能会抓取Trace2D数据,并将其复制到一个新的灰度级数据。@ CyRAL如果是这样的话,我可能会考虑使用一个油漆(颜色TtIrTrand)方法,得到原始纹理的灰度版本并着色它(很容易用RealDestRoad)。。在同一像素上反复使用此公式并将结果存储在该像素中时,该像素会越来越暗。关于如何避免这种情况的建议?@PsychoDad如果你没有对alpha预乘法做一些奇怪的事情,那么这可能是一个精度损失问题。浮点数学很少给出精确的结果,微小的错误最终会累积成巨大的错误。答案很简单:“不要那样做”。如果它仍然会给你带来问题,也许可以提出一个新的问题,并提供完整的细节(可能在GameDev网站上)。
float4 original = tex2d(...);
float q = (original.r + original.g + original.b) / 3;
q /= original.a; // optional - undo alpha premultiplication
return float4(tint.rgb * q, tint.a * original.a);