我正在使用Android中的OpenGL ES 2创建一个2D游戏,其中包含一个健康栏。随着健康状况的降低,健康栏会在5种颜色之间变化(绿色,黄绿色,黄色,橙色,红色)。健康栏的纹理来自纹理图集,我宁愿不会为每种颜色用条形图弄乱纹理图集(将来更容易改变这些颜色)。
这是我想用GLSL重现的原始绿色。它的基色是#77ee9a。
我尝试过的是创建纹理的黑白版本。基础绿色在这里成为#aeaeae。
然后,我将我想要的颜色与这个黑白图像相乘。我意识到这不会完全正确,所以我采取了我想要的绿色(#77ee9a)并在乘以之前将其除以黑白等效物(#aeaeae)。这导致:
我意识到除以灰色会导致原始绿色的rgb值的绿色部分超过255,从而在图像的明亮部分周围产生伪影。
我不确定是否有更好的方法来实现这种着色效果,但我希望有一个解决方案可以让我这样做。
如果没有,我将能够创建两个纹理,一个是纯白色的条形,另一个是透明效果。然后我可以叠加这些,但它需要另外的纹理和游戏中的另一个精灵。
谢谢!
答案 0 :(得分:1)
您可以使用GLSL混合函数计算2个单独的渐变:一个从黑色到所选颜色,对应于灰色值0到0.68(#aeaeae),另一个从所选颜色到达白色为灰色值0.68至1.0。
将色调(例如绿色)作为制服传递:
uniform vec4 uTintColor;
读取灰色值并取任何组件(因为它们都是相同的)。然后计算灰度值在每个梯度中的位置并应用它们。当它在较低的渐变中时,upperGradientCol将等于uTintColor,因为upperGradientPos将为零,因此upperGradientCol可以用作较低渐变的上限。
// read grey scale value
vec4 texel = texture2D(uTexture, vTexCoord);
float greyValue = texel.r;
// compute position in gradients:
float upperGradientPos = clamp((greyValue - 0.68) / 0.32, 0.0, 1.0);
float lowerGradientPos = clamp(greyValue / 0.68, 0.0, 1.0);
// apply upper gradient from uTintColor up to white:
vec4 upperGradientCol = mix(uTintColor, vec4(1.0, 1.0, 1.0, 1.0), upperGradientPos);
// apply lower gradient from black up to uTintColor:
vec4 lowerGradientCol = mix(vec4(0.0, 0.0, 0.0, 1.0), upperGradientCol, lowerGradientPos);
gl_FragColor = vec4(lowerGradientCol.rgb, texel.a);
为了使这个更加通用,您可以传递不同的颜色而不是黑色和白色作为制服,并且对应于色调颜色的灰色值(当前硬编码为0.68)相同。
答案 1 :(得分:0)
你实际上可以写一个着色器,所以你只需要一个纹理,它会被修改为:失去的荒地越多,得到的灰色就越多 要获得将使用的“灰色纹理”的颜色值:
Grayvalue = 0,299×Red + 0,587×Green + 0,114×Blue
因此着色器中的公式如下:
Healthpercantage * 0.711 + 0.299,Healthpercantage * 413 + 0,587,Healthpercantage * 0.886 + 0.114