Issue
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;
Solution
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.
Answered By - DavidBryanRoberson Answer Checked By - David Goodson (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.