如何使用LUA在Filter Forge中创建围绕Y轴的球形角梯度?

发布于 2025-02-09 03:08:19 字数 3085 浏览 1 评论 0原文

我正在制作一个球形脚本,该脚本分别在绿色和红色通道中分别在y轴周围生成线性梯度和角度梯度。我无法找到适合该在线的任何文档,但是使用JavaScript和C#中的示例进行了实验。线性梯度效果很好,但是角度梯度(描述Y轴周围的360度弧)继续使我震惊。

我的工作脚本如下。

-- 3d sphere 
    -- produces rgb gradudient mapped to a 3d sphere, but not correctly. 
    -- this is basically missing an angle gradient around the y-axis...
function prepare()
    -- tilt & rotation precalc
    toRad = 180/math.pi
    -- toCir = 360/math.p -- may or may not work for circumference...

    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)
    -- color gradient example
    --  local r = x
    --  local g = y
    --  local b = (x + y) / 2
    --  local a = 1
    -- spherical mapping formulae (polar to cartesian, apparently)
    --  local x = x * math.pi -- * aspect 
    --  local y = y * math.pi
    --  local nx = math.cos(x) * math.sin(y) 
    --  local ny = math.sin(x) * math.sin(y) 
    --  local nz = math.cos(y) 
    -- cartesian to polar (reference)
    --  example 1
    --  r = math.sqrt(((x * x) + (y * y) + (z * z))) 
    --  long = math.acos(x / math.sqrt((x * x) + (y * y))) * (y < 0 ? -1 : 1) 
    --  lat = math.acos(z / radius) * (z < 0 ? -1 : 1) 
    --  example 2
    --      r = math.sqrt((x * x) + (y * y) + (z * z)) 
    --      long = math.acos(x / math.sqrt((x * x) + (y * y))) * (y < 0 ? -1 : 1) 
    --  lat = math.acos(z / r) 
            -- equations cannot accept boolean comparison
            -- boolean syntax may not be valid in lua
   
    -- image generation
    -- shift origin to center and set radius limits
    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)))

    -- cartesian to polar
        -- r = math.sqrt((x * x) + (y * y) + (z * z))
        -- lat = math.acos(z / r)
        -- long = math.acos(x / math.sqrt((x * x) + (y * y))) * (y < 0) ? -1 : 1) 

    -- apply rotaqtion and tilt (order is important)
    local tz = (cosa2 * z) - (sina2 * py) 
    local ty = (sina2 * z) + (cosa2 * py) -- gradient along y-axis is correct
    z = tz 
    py = ty

    local tx = (cosa * px) - (sina * z) -- gradient needs to go around y-axis
    local tz = (sina * px) + (cosa * z)
    px = tx
    z = tz

        -- r = math.sqrt((x * x) + (y * y) + (z * z)) 
        -- lat = math.acos(z / r) -- invalid z for this; what is correct source?
        -- long = math.acos(x / math.sqrt((x * x) + (y * y))) -- map -1 : 1 needed
        -- long = (sina * px) + (cosa * z) -- ok;  2 full rotations

    -- return r, g, b, a
    -- return px,py,z,a 
    return px/2+.5,py/2+.5,z/2+.5,a 
    -- return px/2+.5,px/2+.5,px/2+.5,a 
    -- return long,long,long,a 
    -- return px/2+.5,py/2+.5,long,a 
end;

I am working on a Spherical Map Script that generates a linear gradient along the y-axis and an angular gradient around the y-axis in the green and red channels, respectively. I have been unable to find any documentation suited to this online, but have experimented using examples in Javascript and C#. The linear gradient has worked out fine, but the angular gradient (one describing a 360 degree arc around the y-axis) continues to elude me.

My working script is as follows.

-- 3d sphere 
    -- produces rgb gradudient mapped to a 3d sphere, but not correctly. 
    -- this is basically missing an angle gradient around the y-axis...
function prepare()
    -- tilt & rotation precalc
    toRad = 180/math.pi
    -- toCir = 360/math.p -- may or may not work for circumference...

    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)
    -- color gradient example
    --  local r = x
    --  local g = y
    --  local b = (x + y) / 2
    --  local a = 1
    -- spherical mapping formulae (polar to cartesian, apparently)
    --  local x = x * math.pi -- * aspect 
    --  local y = y * math.pi
    --  local nx = math.cos(x) * math.sin(y) 
    --  local ny = math.sin(x) * math.sin(y) 
    --  local nz = math.cos(y) 
    -- cartesian to polar (reference)
    --  example 1
    --  r = math.sqrt(((x * x) + (y * y) + (z * z))) 
    --  long = math.acos(x / math.sqrt((x * x) + (y * y))) * (y < 0 ? -1 : 1) 
    --  lat = math.acos(z / radius) * (z < 0 ? -1 : 1) 
    --  example 2
    --      r = math.sqrt((x * x) + (y * y) + (z * z)) 
    --      long = math.acos(x / math.sqrt((x * x) + (y * y))) * (y < 0 ? -1 : 1) 
    --  lat = math.acos(z / r) 
            -- equations cannot accept boolean comparison
            -- boolean syntax may not be valid in lua
   
    -- image generation
    -- shift origin to center and set radius limits
    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)))

    -- cartesian to polar
        -- r = math.sqrt((x * x) + (y * y) + (z * z))
        -- lat = math.acos(z / r)
        -- long = math.acos(x / math.sqrt((x * x) + (y * y))) * (y < 0) ? -1 : 1) 

    -- apply rotaqtion and tilt (order is important)
    local tz = (cosa2 * z) - (sina2 * py) 
    local ty = (sina2 * z) + (cosa2 * py) -- gradient along y-axis is correct
    z = tz 
    py = ty

    local tx = (cosa * px) - (sina * z) -- gradient needs to go around y-axis
    local tz = (sina * px) + (cosa * z)
    px = tx
    z = tz

        -- r = math.sqrt((x * x) + (y * y) + (z * z)) 
        -- lat = math.acos(z / r) -- invalid z for this; what is correct source?
        -- long = math.acos(x / math.sqrt((x * x) + (y * y))) -- map -1 : 1 needed
        -- long = (sina * px) + (cosa * z) -- ok;  2 full rotations

    -- return r, g, b, a
    -- return px,py,z,a 
    return px/2+.5,py/2+.5,z/2+.5,a 
    -- return px/2+.5,px/2+.5,px/2+.5,a 
    -- return long,long,long,a 
    -- return px/2+.5,py/2+.5,long,a 
end;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情归归情 2025-02-16 03:08:20

我找到了一种从我开始的半球轴梯度中构造球形角梯度的方法,该方法是将三个用作RBG中的RBG通道作为HSL转换。我已经用它将纹理映射到映射脚本中的过滤器中,例如 this

我以为我会为在这里遵循我的问题的任何人分享解决方案。

I found a way to construct a spherical angular gradient from the hemispherical axis gradients I started with, by using three as the RBG channels in an RBG to HSL conversion. I've used this to map textures to spheres in Filter Forge in map scripts like this.

I thought I'd share the solution for anyone who's followed my question here.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文