YOUR ACCOUNT

Login or Register to post new topics or replies
David Roberson
Artist
Posts: 404
Filters: 36
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.
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
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.
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
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.
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
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.
  Details E-Mail
David Roberson
Artist
Posts: 404
Filters: 36
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.
  Details E-Mail

Join Our Community!

Filter Forge has a thriving, vibrant, knowledgeable user community. Feel free to join us and have fun!

33,711 Registered Users
+18 new in 30 days!

153,533 Posts
+38 new in 30 days!

15,348 Topics
+73 new in year!

Create an Account

Online Users Last minute:

31 unregistered users.

Recent Forum Posts: