David Roberson
Artist
|
I'm stuck on a script that is supposed to do two different coordinate transforms, each of which I've been able to turn into gradients that will remap in a get_sample_map(). The problem arises when it comes to applying one after the other, meaning I still need some kind of internal lookup function that will remap v or r, g, b, a values. This is something I've tried to figure out on my own at times over the past few years without success. If someone can help or provide an example script I'd really appreciate it.
Edit: In general, I am interested in learning how to do most of the basic transforms (like respective transform components) within a lua script (i.e. Offset, Scale, Flip... I've already been helped with Rotation by emme). On thinking about this, the obvious thing is that get_sample_map() essentially does a lookup if you provide x, y coordinates you calculate before it:
Code |
---|
function prepare()
ox,oy = get_slider_input(ORIGIN_X),get_slider_input(ORIGIN_Y)
d = math.rad(get_angle_input(ROTATION))
s,c = math.sin(d), math.cos(d)
end;
function get_sample(x, y)
local nx = c * (x-ox) - s * (y-oy) + ox
local ny = s * (x-ox) + c * (y-oy) + oy
local r,g,b,a = get_sample_map(nx, ny, SOURCE)
return r,g,b,a
end;
|
So, I'm really interested in understanding what is happening in the get_sample functions.
|
Posted: February 26, 2023 6:30 pm |
Details
E-Mail
|
David Roberson
Artist
|
Going off my last thought, I came up with this:
Code |
---|
function prepare()
-- custom get_sample function
end;
function get_sample(x, y)
local r, g, b, a = get_sample_gradient(x, y)
return r, g, b, a
end;
function get_sample_gradient(x, y)
local nr, ng, nb, na = x, y, (x + y) / 2, 1
return nr, ng, nb, na
end; |
If I'm right about this, I can expand on this to create the internal lookup I'm after.
|
Posted: February 27, 2023 12:03 am |
Details
E-Mail
|
David Roberson
Artist
|
The next experiment succeeded pretty quickly! Since I worked it out on my own, I'm just updating for anyone who has an interest. It really goes to show how hard it can be understand scripting without good reference material or guidance. I was really stumped by my lack of experience with scripting in general and understanding of get_sample functions specifically:
Code |
---|
local sqrt, min, max, rad, pi = math.sqrt, math.min, math.max, math.rad, math.pi
local sin, cos, tan, asin, acos, atan2 = math.sin, math.cos, math.tan, math.asin, math.acos, math.atan2
function prepare()
-- inputs and precalculation.
aspect = OUTPUT_HEIGHT / OUTPUT_WIDTH * 2
ang_x = rad(get_angle_input(ANGLE_X) + 180)
ang_y = rad(get_angle_input(ANGLE_Y))
ang_z = rad(get_angle_input(ANGLE_Z) - 180)
cos_ax, sin_ax = cos(ang_x), sin(ang_x)
cos_ay, sin_ay = cos(ang_y), sin(ang_y)
cos_az, sin_az = cos(ang_z), sin(ang_z)
end;
function get_sample(x, y)
local nx, ny = map_spherical_rotations(x, y)
-- local r, g, b, a = get_sample_gradient(nx, ny)
local r, g, b, a = get_sample_map(nx, ny, SOURCE) -- for testing remap seams
return r, g, b, a
end;
function get_sample_gradient(x, y)
local nr, ng, nb, na = x, y, (x + y) / 2, 1
return nr, ng, nb, na
end;
function map_spherical_rotations(x, y)
-- coordinate rotations
local x = x * aspect * pi
local y = y * pi
local nx = cos(x) * sin(y)
local ny = sin(x) * sin(y)
local nz = cos(y)
-- local r, g, b, a = nx, ny, 0, 1
local ax1, ax2 = (nx * cos_ax) + (ny * sin_ax), (nx * sin_ax) - (ny * cos_ax)
local ay1, ay2 = (ax1 * cos_ay) - (cos(y) * sin_ay), (ax1 * sin_ay) + (cos(y) * cos_ay)
local az1, az2 = (ax2 * cos_az) + (ay2 * sin_az), (ax2 * sin_az) - (ay2 * cos_az)
nx = atan2(az1, ay1) * 0.159155 + 0.5
ny = acos(az2) * 0.159155 * 2
if OUTPUT_WIDTH / OUTPUT_HEIGHT == 2 then
nx = nx * 2 - 1
end
return nx, ny
end; |
I really hope this helps a few people out.
|
Posted: February 27, 2023 12:22 am |
Details
E-Mail
|
David Roberson
Artist
|
I guess I spoke too soon. Once I tried to apply my "solution" it became clear that my premise was flawed. This version shows where I went wrong:
Code |
---|
local sqrt, min, max, rad, pi = math.sqrt, math.min, math.max, math.rad, math.pi
local sin, cos, tan, asin, acos, atan2 = math.sin, math.cos, math.tan, math.asin, math.acos, math.atan2
function prepare()
-- inputs and precalculation.
aspect = OUTPUT_HEIGHT / OUTPUT_WIDTH * 2
ang_x = rad(get_angle_input(ANGLE_X) + 180)
ang_y = rad(get_angle_input(ANGLE_Y))
ang_z = rad(get_angle_input(ANGLE_Z) - 180)
cos_ax, sin_ax = cos(ang_x), sin(ang_x)
cos_ay, sin_ay = cos(ang_y), sin(ang_y)
cos_az, sin_az = cos(ang_z), sin(ang_z)
end;
function get_sample(x, y)
local nx, ny = map_spherical_rotations(x, y)
-- reroute coordinates thru channels
local r, g, b, a = x, y, (x + y) / 2, 1
-- pass cords and channels to function
r, g, b, a = get_sample_gradient(nx, ny, r, g, b, a)
-- local r, g, b, a = get_sample_map(nx, ny, SOURCE) -- for testing remap seams
return r, g, b, a
end;
function get_sample_gradient(x, y, r, g, b, a)
-- channels pass thru without remapping
local nr, ng, nb, na = r, g, b, a
return nr, ng, nb, na
end;
function map_spherical_rotations(x, y)
-- coordinate rotations
local x = x * aspect * pi
local y = y * pi
local nx = cos(x) * sin(y)
local ny = sin(x) * sin(y)
local nz = cos(y)
-- local r, g, b, a = nx, ny, 0, 1
local ax1, ax2 = (nx * cos_ax) + (ny * sin_ax), (nx * sin_ax) - (ny * cos_ax)
local ay1, ay2 = (ax1 * cos_ay) - (cos(y) * sin_ay), (ax1 * sin_ay) + (cos(y) * cos_ay)
local az1, az2 = (ax2 * cos_az) + (ay2 * sin_az), (ax2 * sin_az) - (ay2 * cos_az)
nx = atan2(az1, ay1) * 0.159155 + 0.5
ny = acos(az2) * 0.159155 * 2
if OUTPUT_WIDTH / OUTPUT_HEIGHT == 2 then
nx = nx * 2 - 1
end
return nx, ny
end; |
So, the original problem remains. I can generate the right gradients, but don't know how to use them without get_sample functions.
|
Posted: February 27, 2023 5:00 am |
Details
E-Mail
|
David Roberson
Artist
|
Just a thought I had last night, the essence of a get_sample function is just to sample a value at specific coordinates. If there are any transformations, they have to come between the sampled value and the returned value. The values can be generated or sampled via the usual get_sample functions. With some trigonometry involved, it's hard to imagine what is happening, for example, when my script generates spherically mapped noise. My mind knots up when a series of transformations needs to be done. Any light someone can shed on this is welcome, but of course I'll keep working on it too. I'll update each time I come up with any techniques or solutions.
|
Posted: March 1, 2023 12:01 pm |
Details
E-Mail
|