You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Raylib Alpha混合异常求助:按钮高亮效果不符合预期

Raylib 2D按钮高亮:白色遮罩变暗问题的无Shader解决方案

问题根源

你遇到的是Raylib默认BLEND_ALPHA混合模式的颜色叠加逻辑问题:
默认混合公式为:最终色 = 源色 * 源透明度 + 目标色 * (1 - 源透明度)
当白色遮罩的透明度较低(如0.33),且按钮原图颜色偏暗时,目标色的占比(1-0.33=0.67)远高于白色的占比,导致混合后颜色比原按钮更暗。如果遮罩精灵本身还带有alpha通道,实际透明度会进一步降低,变暗效果更明显。

无自定义Shader解决方案

以下三种方法均基于Raylib内置功能,无需编写Shader:

方案1:使用BLEND_ADDITIVE混合模式(推荐)

ADDITIVE模式的混合逻辑是最终色 = 目标色 + 源色 * 源透明度,白色遮罩的增量会直接加到按钮颜色上,从根源避免变暗问题,过渡更自然。

修改后的绘制代码:

// 绘制基础按钮
DrawTexturePro(GCN::TG->tex_grid_menubuts, (Rectangle){0, 32.0f*t, 320, 32}, (Rectangle){(float)x, (float)y, (float)320, (float)32}, (Vector2){0, 0}, 0.0f, (Color){255, 255, 255, 255});

if (hi > 0)
{
    float alpha = hi_alph * hi / hi_max;
    BeginBlendMode(BLEND_ADDITIVE);
    // 绘制白色高亮遮罩
    DrawTexturePro(GCN::TG->tex_grid_menubuts, 
                   (Rectangle){320, 32.0f*t, 320, 32}, 
                   (Rectangle){(float)x, (float)y, (float)320, (float)32}, 
                   (Vector2){0, 0}, 0.0f, 
                   (Color){255, 255, 255, (unsigned char)round(alpha * 255)});
    EndBlendMode();
}

// 绘制按钮文本
DrawTextEx(GCN::TG->fnt_AL, disp_text.c_str(), (Vector2){(float)(x + w/2 - MeasureTextEx(GCN::TG->fnt_AL, disp_text.c_str(), 24.0f, 1.0f).x/2), (float)(y+6)}, 24.0f, 1.0f, (Color){0, 0, 0, 255});
  • 建议将hi_alph调整至0.2~0.4区间,避免高亮过度刺眼。

方案2:预乘Alpha配合BLEND_ALPHA_PREMULTIPLY模式

预乘Alpha是将RGB值先与透明度相乘,再使用预乘混合模式,公式为最终色 = 源色 + 目标色 * (1 - 源透明度),确保白色的权重足够,不会被目标色压制。

修改后的绘制代码:

// 绘制基础按钮
DrawTexturePro(GCN::TG->tex_grid_menubuts, (Rectangle){0, 32.0f*t, 320, 32}, (Rectangle){(float)x, (float)y, (float)320, (float)32}, (Vector2){0, 0}, 0.0f, (Color){255, 255, 255, 255});

if (hi > 0)
{
    float alpha = hi_alph * hi / hi_max;
    unsigned char alphaByte = (unsigned char)round(alpha * 255);
    // 生成预乘Alpha的白色
    Color premultipliedWhite = {(unsigned char)(255 * alpha), (unsigned char)(255 * alpha), (unsigned char)(255 * alpha), alphaByte};
    
    BeginBlendMode(BLEND_ALPHA_PREMULTIPLY);
    DrawTexturePro(GCN::TG->tex_grid_menubuts, 
                   (Rectangle){320, 32.0f*t, 320, 32}, 
                   (Rectangle){(float)x, (float)y, (float)320, (float)32}, 
                   (Vector2){0, 0}, 0.0f, 
                   premultipliedWhite);
    EndBlendMode();
}

// 绘制按钮文本
DrawTextEx(GCN::TG->fnt_AL, disp_text.c_str(), (Vector2){(float)(x + w/2 - MeasureTextEx(GCN::TG->fnt_AL, disp_text.c_str(), 24.0f, 1.0f).x/2), (float)(y+6)}, 24.0f, 1.0f, (Color){0, 0, 0, 255});

方案3:直接绘制纯色高亮矩形(无需遮罩精灵)

如果遮罩仅为纯色按钮形状,可直接用DrawRectanglePro替代遮罩精灵,减少资源依赖,效果更可控:

// 绘制基础按钮
DrawTexturePro(GCN::TG->tex_grid_menubuts, (Rectangle){0, 32.0f*t, 320, 32}, (Rectangle){(float)x, (float)y, (float)320, (float)32}, (Vector2){0, 0}, 0.0f, (Color){255, 255, 255, 255});

if (hi > 0)
{
    float alpha = hi_alph * hi / hi_max;
    BeginBlendMode(BLEND_ADDITIVE);
    // 直接绘制带透明度的白色矩形覆盖按钮
    DrawRectanglePro((Rectangle){(float)x, (float)y, 320, 32}, (Vector2){0,0}, 0.0f, (Color){255,255,255, (unsigned char)round(alpha*255)});
    EndBlendMode();
}

// 绘制按钮文本
DrawTextEx(GCN::TG->fnt_AL, disp_text.c_str(), (Vector2){(float)(x + w/2 - MeasureTextEx(GCN::TG->fnt_AL, disp_text.c_str(), 24.0f, 1.0f).x/2), (float)(y+6)}, 24.0f, 1.0f, (Color){0, 0, 0, 255});

内容的提问来源于stack exchange,提问作者DrZ214

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 03:54:58