Filter Forge中Lua实现绕Y轴球面角度渐变的方法
球形贴图脚本绕Y轴角度渐变修复方案
核心问题
现有脚本沿Y轴的线性渐变逻辑已经正常,绕Y轴360度环形渐变失效的原因有两点:
- 参考的JS、C#示例中使用的三目运算符(
? :)不被Lua支持,无法直接完成象限判断 - 直接使用坐标分量作为角度输出,没有做极角转换和取值范围映射,导致输出出现双周期、颜色断层
修复逻辑
- 绿色通道(沿Y轴线性渐变):保留现有
py分量的映射逻辑,完成倾斜、旋转变换后的py取值范围为[-1,1],映射到[0,1]区间即为从球体南极到北极的连续线性渐变,无需改动 - 红色通道(绕Y轴360度环形渐变):所有变换完成后,绕Y轴的截面为X-Z平面,调用Lua内置
math.atan2(z, px)即可获取点在X-Z平面的弧度值,该函数原生支持全象限符号判断,返回值范围为[-π, π],将其除以2*math.pi后加0.5,即可映射为[0,1]区间的连续360度无断层环形渐变 - 球体范围外的透明区域保持原有判断逻辑即可
修正后完整代码
-- 3d sphere -- 绿色通道输出沿Y轴线性渐变,红色通道输出绕Y轴360度环形渐变 function prepare() -- tilt & rotation precalc toRad = 180/math.pi radius = get_slider_input(RADIUS) angle = get_angle_input(ROTATION)/toRad cosa = math.cos(angle) sina = math.sin(angle) tilt = get_angle_input(TILT)/toRad cosa2 = math.cos(tilt) sina2 = math.sin(tilt) end; function get_sample(x, y) local r, g, b, a = get_sample_map(x, y, SOURCE) -- 坐标原点偏移到中心,归一化半径范围 local px = (x*2.0) - 1.0 local py = (y*2.0) - 1.0 px = px/radius py = py/radius local len = math.sqrt((px*px)+(py*py)) if len > 1.0 then return 0,0,0,0 end local z = -math.sqrt(1.0 - ((px*px)+(py*py))) -- 应用倾斜变换 local tz = (cosa2 * z) - (sina2 * py) local ty = (sina2 * z) + (cosa2 * py) -- 沿Y轴渐变基准值 z = tz py = ty -- 应用绕Y轴旋转变换 local tx = (cosa * px) - (sina * z) local tz = (sina * px) + (cosa * z) px = tx z = tz -- 计算绕Y轴环形渐变:atan2返回[-pi, pi]范围弧度,映射到[0,1] local long = math.atan2(z, px) / (2 * math.pi) + 0.5 -- 计算沿Y轴线性渐变:py范围[-1,1],映射到[0,1] local lat = py / 2 + 0.5 -- 通道输出:R=绕Y轴角度环变,G=沿Y轴线变,B/A保留原采样通道值 return long, lat, b, a end;
调整说明
- 如果需要反转渐变方向,将对应通道的计算值替换为
1 - 计算值即可 - 如果需要调整环形渐变的起始角度,在
math.atan2(z, px)的返回值上叠加对应弧度偏移量即可 - 如果不需要保留原输入贴图的蓝色、透明通道,可自行替换为需要的输出值
内容的提问来源于stack exchange,提问作者David B Roberson
相关产品推荐
相关产品推荐

