在 cocos2d-x中已经有一个LayerRadialGradient
. 效果很好,但是我的游戏场景上运行了其他着色器,所以现在出现了问题。它正在使用着色器。
我想用生成径向渐变纹理的 Sprite 替换它。
这是LayerRadialGradient
绘图结果的示例:
LayerRadialGradient::create(
Color4B(179, 232, 184, 89),
Color4B(0, 90, 128, 0),
620,
center,
0.0f);
我有一些代码建议,例如:
static Color4B Lerp(const Color4B& value1, const Color4B& value2, float amount)
{
amount = clampf(amount, 0.0f, 1.0f);
return Color4B(
(int)MathUtil::lerp(value1.r, value2.r, amount),
(int)MathUtil::lerp(value1.g, value2.g, amount),
(int)MathUtil::lerp(value1.b, value2.b, amount),
(int)MathUtil::lerp(value1.a, value2.a, amount)
);
}
static float Falloff(float distance, float maxDistance, float scalingFactor)
{
if (distance <= maxDistance / 3)
{
return scalingFactor * (1 - 3 * distance * distance / (maxDistance * maxDistance));
}
else if (distance <= maxDistance)
{
float x = 1 - distance / maxDistance;
return (3.f / 2.f) * scalingFactor * x * x;
}
else
return 0;
}
static float Falloff(float distance, float maxDistance)
{
return Falloff(distance, maxDistance, 1.f);
}
static Texture2D* generateRadialGradientTexture(int size) {
auto radius = size / 2;
auto colors = new (std::nothrow) GLubyte[size * size * 4];
Color4B centerColor(Color4B(179, 232, 184, 89));
Color4B borderColor(Color4B(0, 90, 128, 0));
for (int y = 0; y < size; y++)
{
for (int x = 0; x < size; x++)
{
float distance = Vec2::ONE.distance(Vec2(x, y) / radius);
float alpha = Falloff(distance, 1, 1);
int idx = (y * size + x) * 4;
float innerGradient = Falloff(distance, 0.6f, 0.8f);
auto color = Lerp(borderColor, centerColor, innerGradient);
colors[idx + 0] = color.r;
colors[idx + 1] = color.g;
colors[idx + 2] = color.b;
//alpha
colors[idx + 3] = (GLbyte)clampf(alpha * 256.f + 0.5f, 0.f, 255.f);
}
}
auto txt = new Texture2D();
txt->initWithData(colors, size * size * 4, Texture2D::PixelFormat::RGBA8888, size, size, Size(size, size));
delete[] colors;
return txt;
}
并且只使用:
Sprite::createWithTexture(generateRadialGradientTexture(radius));
但结果真的不一样: