Firealpaca Lua笔刷脚本:等亮度随机色偏色问题修复求助
Firealpaca笔刷脚本:亮度一致随机色问题修复方案
问题描述
正在制作Firealpaca笔刷脚本,需实现两个功能:
- 通过抖动生成纹理
- 绘制与前景色亮度(luminance)相同的随机颜色
当前实现存在以下问题:
- 低亮度时颜色偏向蓝色,高亮度时偏向绿色
- 高亮度场景下绿色值常超过255,限制为255后导致最终颜色亮度降低
原代码如下:
Firstdraw = true function param1() -- minimum, maximum, default value return "random" , 0 , 100 , 2 end function main(x, y, p) if Firstdraw then r, g, b = bs_fore() luminance = (r * 0.3) + (g * 0.59) + (b * 0.11) luminanceStart = luminance if luminance <= 28 then blue = math.random(0, luminance/0.11) elseif luminance >= 227 then blue = math.random((luminance-227)/0.11, 255) else blue = math.random(0, 255) end luminance = luminance - blue*0.11 if luminance <= 76 then red = math.random(0, luminance/0.3) elseif luminance >= 179 then red = math.random((luminanceStart-179)/0.3, 255) else red = math.random(0, 255) end luminance = luminance - red*0.3 green = luminance/0.59 if green > 255 then green = 255 end luminanceEnd = (red * 0.3) + (green * 0.59) + (blue * 0.11) local sx = tostring(luminanceStart) local sv = tostring(luminanceEnd) local sy = tostring(red) local sp = tostring( green) local sd = tostring( blue) bs_debug_log( "sx: " .. sx .. " sv: " .. sv .. " sy: " .. sy .. " sp: " .. sp.. " sd: " .. sd ) bs_debug_log("") end local width = bs_width() local x, y = x+math.random(bs_param1()*-1, bs_param1())*p*width/10, y+math.random(bs_param1()*-1, bs_param1())*p*width/10 local opacity = bs_opaque() * 255 bs_ellipse(x, y, width, width, 0, red, green, blue, opacity) Firstdraw = false return 1 end
问题根源
原代码的颜色计算逻辑存在两个核心问题:
- 颜色生成顺序与范围约束错误:先随机蓝色、再随机红色,最后计算绿色的方式,导致绿色被过度依赖——高亮度时绿色容易超出255阈值;低亮度时蓝色的随机范围计算不合理,直接导致偏蓝。
- 亮度补偿缺失:当绿色被截断到255时,没有重新调整红、蓝值弥补亮度损失,最终亮度低于目标值。
修复后的代码
Firstdraw = true function param1() -- minimum, maximum, default value return "random" , 0 , 100 , 2 end -- 封装亮度计算函数,便于复用 function calculate_luminance(r, g, b) return r * 0.3 + g * 0.59 + b * 0.11 end -- 生成与目标亮度一致的随机颜色 function generate_random_color(target_luminance) local r, g, b local max_attempts = 100 -- 防止极端情况导致无限循环 local attempts = 0 repeat -- 先随机生成0-255范围内的基础RGB值 r = math.random(0, 255) g = math.random(0, 255) b = math.random(0, 255) -- 计算当前亮度与目标亮度的比例 local current_luminance = calculate_luminance(r, g, b) local ratio = target_luminance / current_luminance -- 按比例调整RGB值,同时确保不超过255上限 r = math.min(math.floor(r * ratio + 0.5), 255) g = math.min(math.floor(g * ratio + 0.5), 255) b = math.min(math.floor(b * ratio + 0.5), 255) -- 重新计算调整后的亮度,确保误差在±1以内 current_luminance = calculate_luminance(r, g, b) attempts = attempts + 1 until (math.abs(current_luminance - target_luminance) <= 1) or (attempts >= max_attempts) return r, g, b end function main(x, y, p) if Firstdraw then local r_fore, g_fore, b_fore = bs_fore() local target_luminance = calculate_luminance(r_fore, g_fore, b_fore) -- 生成符合目标亮度的随机颜色 r, g, b = generate_random_color(target_luminance) -- 输出调试日志,方便验证亮度一致性 bs_debug_log( string.format("Target Luminance: %.2f | Final Luminance: %.2f | RGB: %d, %d, %d", target_luminance, calculate_luminance(r, g, b), r, g, b) ) bs_debug_log("") end local width = bs_width() -- 抖动偏移计算,保持原有功能 local dx = math.random(bs_param1()*-1, bs_param1()) * p * width / 10 local dy = math.random(bs_param1()*-1, bs_param1()) * p * width / 10 local opacity = bs_opaque() * 255 bs_ellipse(x + dx, y + dy, width, width, 0, r, g, b, opacity) Firstdraw = false return 1 end
修复关键点
- 随机颜色生成逻辑重构:
- 先随机生成全范围的RGB值,再根据目标亮度比例调整,避免单一颜色被过度约束,解决偏色问题
- 使用循环微调,确保最终亮度与目标值误差在±1以内,彻底解决亮度降低问题
- 代码模块化:把亮度计算封装成独立函数,提升代码可读性和可维护性
- 日志优化:使用
string.format让调试信息更直观,便于验证效果
内容的提问来源于stack exchange,提问作者Indonesiaball
相关产品推荐
相关产品推荐

