2013-09-01 77 views
2

在我的基于2D平铺的游戏中,玩家可以在平铺时改变颜色。简单的方法(以及我已经完成的)是使用SpriteBatch.Draw中的tint参数。不要着色,但“着色”精灵

这看起来不错,而且这里有一个例子:

enter image description here

但是说,我要画的木白。如果你曾经与色调混淆,你知道这是不可能的使用色调参数。 Color.White会将sprite设为默认颜色,而不是白色。这不是一个主要问题,但我想有些用户可能需要它。

我的问题是,有没有一种基于色调/饱和度而不是色调的精灵颜色的方法。类似于GIMP中的“colorify”功能。

http://gyazo.com/eaa8d54d82a15ce05b006b084e71803f.png

一个显而易见的方法是使用在GIMP这个功能,只是出口的精灵为每种颜色。麻烦在于,这对我所有的精灵来说都是永远的事情,每个精灵都有多种变化,这意味着你可以在一个模块类型中总共使用100个以上的组合。

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

+4

为什么不让基础精灵尽可能明亮(接近白色)?你可以用像素着色器实现任意效果,但我怀疑在这种情况下这是必要的。在我看来,Gimp使用与tint参数相同的技术。 –

+0

研究HSV颜色模型:[链接](http://en.wikipedia.org/wiki/HSL_and_HSV)。您可以将您的纹理从RGB转换为HSV,将偏移应用于Hue以更改颜色,然后将其转换回RGB。虽然如果你的纹理以白色开始,并且使用内置的XNA着色,它绝对会更容易。 – foolmoron

回答

4

GIMP中的“colourify”函数简单地进行去饱和(转换为灰度),然后进行颜色乘法。很简单。这应该是等同的HLSL(未经测试):

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); 

但是你可以通过简单地存储所有纹理去饱和开始与和使用默认SpriteBatch着色器的乘法达到同样的效果。如果您不想修改源文件,可以在自定义内容处理器中进行。


尽管如此,如果你想使用自定义着色器,你可以做一些更复杂。你可以实现完整的色调旋转(有点复杂)。但也许你可以考虑像"Overlay" blend mode(非常简单) - 它可以让灰色着色,同时保留高光和低光(而不是乘法,这也会使高光成色)。

+0

当在同一像素上反复使用此公式并将结果存储在该像素中时,像素会变得越来越暗。有关如何避免这种情况的建议? – jjxtra

+0

@PsychoDad如果你没有在alpha乘法前做一些奇怪的事情,那么这可能是一个精确丢失问题。浮点数学很少给出确切的结果,微小的错误最终会加上一个很大的错误。简单的答案是:“不要那样做”。如果它仍然引起你的问题,也许提出一个新的问题将全部细节(也许在GameDev网站)。 –

1

要继续使用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](半透明和更红的ish)

+0

这样做的问题是,假设我有一个块,不能仅将棕色色调应用为默认值,即具有多种颜色的块。我可能只是抓住texture2d数据,并将其作为灰度级数据复制到新的数据。 – Cyral

+0

@CYral如果出现这种情况,我可能会考虑使用Paint(Color tintColor)方法,该方法获得了原始纹理的灰度版本并对其进行了着色(使用rendertarget很容易)。 –